@ykurilov/agent-chat-core 0.63.1 → 0.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +2 -2
- package/dist/access.js +2 -2
- package/dist/{chunk-FBULM4V6.js → chunk-5UUWSY6V.js} +2 -2
- package/dist/{chunk-FOAIG4DY.js → chunk-CVRDB3NM.js} +1 -1
- package/dist/chunk-CVRDB3NM.js.map +1 -0
- package/dist/{chunk-XQ5FJ2VT.js → chunk-EWEEYX6U.js} +160 -15
- package/dist/chunk-EWEEYX6U.js.map +1 -0
- package/dist/index.js +3 -3
- package/dist/storage-contract.js +13 -2
- package/dist/storage-contract.js.map +1 -1
- package/dist/types/access/chat-capabilities.d.ts +12 -8
- package/dist/types/access/client-visibility.d.ts +2 -2
- package/dist/types/agent-run/run-agent-turn.d.ts +2 -4
- package/dist/types/conversation/types.d.ts +19 -6
- package/dist/types/index.d.ts +1 -1
- package/dist/types/provider-errors/classify-provider-error.d.ts +2 -0
- package/dist/types/provider-errors/provider-error-details.d.ts +18 -0
- package/dist/types/provider-errors/provider-outages.d.ts +3 -1
- package/dist/types/text/scrub-secrets.d.ts +3 -1
- package/dist/types/turn-hooks/turn-hooks.d.ts +3 -4
- package/package.json +1 -1
- package/dist/chunk-FOAIG4DY.js.map +0 -1
- package/dist/chunk-XQ5FJ2VT.js.map +0 -1
- /package/dist/{chunk-FBULM4V6.js.map → chunk-5UUWSY6V.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/storage/storage-contract.ts"],"sourcesContent":["import { jsonSchema } from \"ai\";\nimport { describe, expect, it, vi } from \"vitest\";\nimport { CURRENT_FORMAT_VERSION, newStoredMessage } from \"../conversation/types\";\nimport type { StoredBranchSelection, StoredCompaction, StoredMessage, UsageRecord } from \"../conversation/types\";\nimport {\n ChatAlreadyExistsError,\n DuplicateChatSubjectError,\n DuplicateMessageError,\n MessageAlreadyFinishedError,\n MessageNotAwaitingError,\n UnsupportedFormatVersionError,\n} from \"./chat-storage\";\nimport type { ChatStorage, StoredPendingBurst } from \"./chat-storage\";\nimport type { TurnRequestContext } from \"../page-context/page-context\";\nimport { ChatDataTooLargeError } from \"./chat-data\";\nimport type { ChatDataFilter } from \"./chat-data\";\nimport { WidgetNotPendingError, createChatService } from \"../chat-service\";\nimport type { ChatService } from \"../chat-service\";\nimport { AnswerEditError } from \"../conversation/edit-answer-parts\";\nimport { extendCatalog } from \"../models/catalog-changes\";\nimport { standardCatalog } from \"../models/standard-catalog\";\nimport type { MemoryError, MemoryNote, MemoryNoteInput, MemoryWriteGuard } from \"../memory/long-term-memory\";\nimport type { MemoryOptimizationRules } from \"../memory/memory-optimization\";\n\n/**\n * Проверки договора хранилища (contracts/storage.md). Каждый адаптер подключает их\n * в своих тестах: `describeChatStorageContract(() => createMyStorage())`.\n */\nexport function describeChatStorageContract(\n createStorage: () => ChatStorage | Promise<ChatStorage>,\n options: {\n /** `choiceMemory: \"required\"` — методы запомненного выбора обязаны быть (для встроенных хранилищ); иначе их проверки пропускаются. */\n choiceMemory?: \"required\";\n /** `voiceDialog: \"required\"` — то же для методов голосового режима (`setVoiceCut`, `getVoiceChoice`, `setVoiceChoice`). */\n voiceDialog?: \"required\";\n /** `memory: \"required\"` — методы долгой памяти обязаны быть (для встроенных хранилищ). */\n memory?: \"required\";\n /** `memoryOptimization: \"required\"` — методы оптимизации дублей обязаны быть (для встроенных хранилищ). */\n memoryOptimization?: \"required\";\n /** `spendingLimitState: \"required\"` — методы состояния лимитов расходов обязаны быть (для встроенных хранилищ). */\n spendingLimitState?: \"required\";\n /** `subjectChats: \"required\"` — чаты объектов обязаны быть (`findChatBySubject`, ключ, данные, название и дата в `createChat`, `listChats` с `subjects`). */\n subjectChats?: \"required\";\n /** `chatData: \"required\"` — данные чата (`data`, `updateChatData`, фильтр `data` в `listChats`) обязаны быть. */\n chatData?: \"required\";\n /** `importChat: \"required\"` — перенос чата целиком (`importChat`) обязан быть. */\n importChat?: \"required\";\n /** `afterTurnState: \"required\"` — состояние хука итога у сообщения (`setAfterTurnState`, `listPendingAfterTurn`) обязано быть. */\n afterTurnState?: \"required\";\n /** `chatClosure: \"required\"` — закрытие чата (`setChatClosed`, поле `closed` у чата) обязано быть. */\n chatClosure?: \"required\";\n /** `partsOfTypes: \"required\"` — лёгкое чтение частей нужных типов (`listMessagePartsOfTypes`) обязано быть. */\n partsOfTypes?: \"required\";\n /** `usageByChat: \"required\"` — сумма расхода по списку чатов одним запросом (`sumUsageByChat`) обязана быть. */\n usageByChat?: \"required\";\n /**\n * `chatTurnLease: \"required\"` — аренда хода чата между копиями сервера (`claimChatTurn`, `releaseChatTurn`,\n * `clearChatTurnLeases`) обязана быть.\n */\n chatTurnLease?: \"required\";\n /**\n * `pendingBursts: \"required\"` — ждущие пачки (`savePendingBurst`, `takeAbandonedBursts`, `renewPendingBurst`,\n * `removePendingBurst`) обязаны быть.\n */\n pendingBursts?: \"required\";\n } = {},\n): void {\n const chatInput = { id: \"chat-1\", ownerId: \"anna\", modelId: \"deepseek-4.1-flash\", providerId: \"deepseek\" };\n\n function userMessage(id: string, createdAt: string, parentId: string | null = null): StoredMessage {\n return newStoredMessage({\n id,\n chatId: chatInput.id,\n parentId,\n role: \"user\",\n parts: [{ type: \"text\", text: `вопрос ${id}` }],\n createdAt,\n });\n }\n\n function streamingAnswer(id: string, parentId: string, createdAt: string): StoredMessage {\n return {\n ...userMessage(id, createdAt, parentId),\n role: \"assistant\",\n parts: [],\n status: \"streaming\",\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n };\n }\n\n async function storageWithChat(): Promise<ChatStorage> {\n const storage = await createStorage();\n await storage.createChat(chatInput);\n return storage;\n }\n\n describe(\"договор ChatStorage\", () => {\n it(\"создаёт чат и читает его; неизвестный чат — null\", async () => {\n const storage = await storageWithChat();\n const chat = await storage.getChat(chatInput.id);\n expect(chat).toMatchObject(chatInput);\n expect(typeof chat?.createdAt).toBe(\"string\");\n expect(chat?.updatedAt).toBe(chat?.createdAt);\n expect(await storage.getChat(\"missing\")).toBeNull();\n });\n\n it(\"хранит происхождение чата: из мессенджера — отдаёт, без него — поля нет\", async () => {\n const storage = await createStorage();\n const fromMessenger = await storage.createChat({ ...chatInput, id: \"from-telegram\", origin: \"telegram\" });\n expect(fromMessenger.origin).toBe(\"telegram\");\n expect((await storage.getChat(\"from-telegram\"))?.origin).toBe(\"telegram\");\n\n const web = await storage.createChat({ ...chatInput, id: \"from-web\" });\n expect(web.origin).toBeUndefined();\n const read = await storage.getChat(\"from-web\");\n expect(read).not.toHaveProperty(\"origin\");\n\n const listed = await storage.listChats(chatInput.ownerId);\n expect(listed.find((chat) => chat.id === \"from-telegram\")?.origin).toBe(\"telegram\");\n expect(listed.find((chat) => chat.id === \"from-web\")).not.toHaveProperty(\"origin\");\n\n for (const origin of [\"vk\", \"max\"] as const) {\n const chat = await storage.createChat({ ...chatInput, id: `from-${origin}`, origin });\n expect((await storage.getChat(chat.id))?.origin).toBe(origin);\n }\n\n await storage.updateChatModel(\"from-telegram\", { modelId: \"m\", providerId: \"p\" });\n expect((await storage.getChat(\"from-telegram\"))?.origin).toBe(\"telegram\");\n });\n\n it(\"updateChatModel меняет модель и провайдера чата\", async () => {\n const storage = await storageWithChat();\n await storage.updateChatModel(chatInput.id, { modelId: \"other-model\", providerId: \"fireworks\" });\n expect(await storage.getChat(chatInput.id)).toMatchObject({ modelId: \"other-model\", providerId: \"fireworks\" });\n });\n\n it(\"хранит уровень рассуждений чата: при создании и при смене модели; без него — стирает\", async () => {\n const storage = await createStorage();\n const withLevel = await storage.createChat({ ...chatInput, id: \"with-level\", reasoning: \"high\" });\n expect(withLevel.reasoning).toBe(\"high\");\n expect((await storage.getChat(\"with-level\"))?.reasoning).toBe(\"high\");\n\n const without = await storage.createChat({ ...chatInput, id: \"without-level\" });\n expect(without.reasoning).toBeUndefined();\n expect((await storage.getChat(\"without-level\"))?.reasoning).toBeUndefined();\n\n await storage.updateChatModel(\"without-level\", { modelId: \"m\", providerId: \"p\", reasoning: \"low\" });\n expect(await storage.getChat(\"without-level\")).toMatchObject({ modelId: \"m\", providerId: \"p\", reasoning: \"low\" });\n\n await storage.updateChatModel(\"without-level\", { modelId: \"m\", providerId: \"p\" });\n expect((await storage.getChat(\"without-level\"))?.reasoning).toBeUndefined();\n });\n\n it(\"insertMessage обновляет updatedAt чата\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n expect((await storage.getChat(chatInput.id))?.updatedAt).toBe(\"2099-01-01T00:00:00.000Z\");\n });\n\n it(\"insertMessage в несуществующий чат — отказ, сообщение не записано\", async () => {\n const storage = await storageWithChat();\n await expect(storage.insertMessage({ ...userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"), chatId: \"missing\" })).rejects.toThrow();\n expect(await storage.getMessage(\"u1\")).toBeNull();\n expect(await storage.listMessages(\"missing\")).toEqual([]);\n });\n\n it(\"listMessages отдаёт сообщения чата по времени создания\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u2\", \"2099-01-01T00:00:02.000Z\", \"a1\"));\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n expect((await storage.listMessages(chatInput.id)).map((message) => message.id)).toEqual([\"u1\", \"a1\", \"u2\"]);\n expect(await storage.listMessages(\"missing\")).toEqual([]);\n });\n\n it(\"listMessageLinks отдаёт только id, родителя и время создания, в том же порядке, что listMessages\", async () => {\n const storage = await storageWithChat();\n const sameTime = \"2099-01-01T00:00:02.000Z\";\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.insertMessage(userMessage(\"u3\", sameTime, \"a1\"));\n await storage.insertMessage(userMessage(\"u2\", sameTime, \"a1\"));\n expect(await storage.listMessageLinks(chatInput.id)).toEqual([\n { id: \"u1\", parentId: null, createdAt: \"2099-01-01T00:00:00.000Z\" },\n { id: \"a1\", parentId: \"u1\", createdAt: \"2099-01-01T00:00:01.000Z\" },\n { id: \"u3\", parentId: \"a1\", createdAt: sameTime },\n { id: \"u2\", parentId: \"a1\", createdAt: sameTime },\n ]);\n expect((await storage.listMessageLinks(chatInput.id)).map((link) => link.id)).toEqual(\n (await storage.listMessages(chatInput.id)).map((message) => message.id),\n );\n expect(await storage.listMessageLinks(\"missing\")).toEqual([]);\n });\n\n it(\"listMessagePartsOfTypes отдаёт связи и только части нужных типов, в порядке listMessages\", async (context) => {\n const storage = await storageWithChat();\n if (!storage.listMessagePartsOfTypes) {\n if (options.partsOfTypes === \"required\") throw new Error(\"У хранилища нет listMessagePartsOfTypes\");\n context.skip();\n }\n const sameTime = \"2099-01-01T00:00:02.000Z\";\n const record = { type: \"data-app-state\", data: { set: { \"fields.email\": \"a@x.ru\", $closed: { code: \"done\", message: \"Готово «ок» \\\\ \\\"кавычки\\\"\" } } } };\n const voice = { type: \"data-voice-mode\", data: { voice: \"alloy\" } };\n await storage.insertMessage({ ...userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"), parts: [{ type: \"text\", text: \"вопрос\" }, voice] as StoredMessage[\"parts\"] });\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.updateStreamingMessage(\"a1\", {\n parts: [{ type: \"step-start\" }, record, { type: \"text\", text: \"длинный ответ\", state: \"done\" }, { type: \"data-app-state\", data: { unset: [\"fields.email\"] } }] as StoredMessage[\"parts\"],\n reasoningDurationsMs: {},\n });\n await storage.insertMessage(userMessage(\"u3\", sameTime, \"a1\"));\n await storage.insertMessage({ ...userMessage(\"u2\", sameTime, \"a1\"), parts: [record] as StoredMessage[\"parts\"] });\n expect(await storage.listMessagePartsOfTypes!(chatInput.id, [\"data-app-state\", \"data-voice-mode\"])).toEqual([\n { id: \"u1\", parentId: null, createdAt: \"2099-01-01T00:00:00.000Z\", parts: [voice] },\n { id: \"a1\", parentId: \"u1\", createdAt: \"2099-01-01T00:00:01.000Z\", parts: [record, { type: \"data-app-state\", data: { unset: [\"fields.email\"] } }] },\n { id: \"u3\", parentId: \"a1\", createdAt: sameTime, parts: [] },\n { id: \"u2\", parentId: \"a1\", createdAt: sameTime, parts: [record] },\n ]);\n expect(await storage.listMessagePartsOfTypes!(chatInput.id, [\"data-voice-mode\"])).toMatchObject([{ parts: [voice] }, { parts: [] }, { parts: [] }, { parts: [] }]);\n expect(await storage.listMessagePartsOfTypes!(\"missing\", [\"data-app-state\"])).toEqual([]);\n });\n\n it(\"повтор id в insertMessage — DuplicateMessageError\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await expect(storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:01.000Z\"))).rejects.toBeInstanceOf(\n DuplicateMessageError,\n );\n expect(await storage.listMessages(chatInput.id)).toHaveLength(1);\n });\n\n it(\"части с providerMetadata у рассуждений читаются без изменений\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const parts: StoredMessage[\"parts\"] = [\n { type: \"step-start\" },\n {\n type: \"reasoning\",\n id: \"r1\",\n text: \"думаю о сложении\",\n state: \"done\",\n providerMetadata: { deepseek: { signature: \"штамп-провайдера\", nested: { list: [1, 2, 3] } } },\n },\n { type: \"text\", text: \"42\", state: \"done\" },\n ];\n await storage.updateStreamingMessage(\"a1\", { parts, reasoningDurationsMs: { r1: 1500 } });\n const saved = (await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\");\n expect(saved?.parts).toEqual(parts);\n expect(saved?.reasoningDurationsMs).toEqual({ r1: 1500 });\n expect(saved?.status).toBe(\"streaming\");\n });\n\n it(\"отметка голосового режима в частях сообщения человека переживает запись и чтение\", async () => {\n const storage = await storageWithChat();\n const parts: StoredMessage[\"parts\"] = [\n { type: \"text\", text: \"сказано голосом\" },\n { type: \"data-voice-mode\", data: true },\n ];\n await storage.insertMessage({ ...userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"), parts });\n expect((await storage.getMessage(\"u1\"))?.parts).toEqual(parts);\n expect((await storage.listMessages(chatInput.id)).find((message) => message.id === \"u1\")?.parts).toEqual(parts);\n });\n\n it(\"finishMessage переводит ответ в конечное состояние с итогом\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const usage = { inputTokens: 100, cachedInputTokens: 60, outputTokens: 20, reasoningTokens: 10 };\n await storage.finishMessage(\"a1\", {\n status: \"error\",\n parts: [{ type: \"text\", text: \"часть\", state: \"done\" }],\n usage,\n error: { kind: \"overloaded\" },\n });\n const saved = (await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\");\n expect(saved).toMatchObject({ status: \"error\", usage, error: { kind: \"overloaded\" } });\n expect(saved?.parts).toEqual([{ type: \"text\", text: \"часть\", state: \"done\" }]);\n });\n\n it(\"finishMessage с providerId меняет провайдера ответа, без поля — провайдер прежний\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a2\", \"u1\", \"2099-01-01T00:00:02.000Z\"));\n await storage.finishMessage(\"a1\", { status: \"complete\", providerId: \"fireworks\" });\n await storage.finishMessage(\"a2\", { status: \"complete\" });\n const saved = await storage.listMessages(chatInput.id);\n expect(saved.find((message) => message.id === \"a1\")?.providerId).toBe(\"fireworks\");\n expect((await storage.getMessage(\"a1\"))?.providerId).toBe(\"fireworks\");\n expect(saved.find((message) => message.id === \"a2\")?.providerId).toBe(\"deepseek\");\n });\n\n it(\"сообщение в конечном состоянии не меняется — MessageAlreadyFinishedError\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.finishMessage(\"a1\", { status: \"stopped\" });\n await expect(storage.updateStreamingMessage(\"a1\", { parts: [] })).rejects.toBeInstanceOf(\n MessageAlreadyFinishedError,\n );\n await expect(storage.finishMessage(\"a1\", { status: \"complete\" })).rejects.toBeInstanceOf(\n MessageAlreadyFinishedError,\n );\n await expect(storage.updateStreamingMessage(\"u1\", { parts: [] })).rejects.toBeInstanceOf(\n MessageAlreadyFinishedError,\n );\n const saved = (await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\");\n expect(saved?.status).toBe(\"stopped\");\n });\n\n describe(\"ответ, который ждёт подтверждения\", () => {\n const requested = {\n type: \"tool-remove\",\n toolCallId: \"c1\",\n state: \"approval-requested\",\n input: { path: \"a\" },\n approval: { id: \"ap1\" },\n } as StoredMessage[\"parts\"][number];\n\n async function storageWithAwaitingAnswer(): Promise<ChatStorage> {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.finishMessage(\"a1\", { status: \"awaiting_approval\", parts: [requested] });\n return storage;\n }\n\n const savedAnswer = async (storage: ChatStorage) =>\n (await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\");\n\n it(\"хранится как обычное сообщение и не считается идущим\", async () => {\n const storage = await storageWithAwaitingAnswer();\n expect(await savedAnswer(storage)).toMatchObject({ status: \"awaiting_approval\", parts: [requested] });\n expect(await storage.listStreamingMessageIds()).toEqual([]);\n });\n\n it(\"updateAwaitingMessage меняет части и оставляет ожидание, если статус не указан\", async () => {\n const storage = await storageWithAwaitingAnswer();\n const responded = { ...requested, state: \"approval-responded\", approval: { id: \"ap1\", approved: true } };\n await storage.updateAwaitingMessage(\"a1\", { parts: [responded as StoredMessage[\"parts\"][number]] });\n expect(await savedAnswer(storage)).toMatchObject({ status: \"awaiting_approval\", parts: [responded] });\n });\n\n it(\"updateAwaitingMessage со статусом streaming возвращает ответ в работу, после чего он дописывается и завершается\", async () => {\n const storage = await storageWithAwaitingAnswer();\n await storage.updateAwaitingMessage(\"a1\", { parts: [requested], status: \"streaming\" });\n expect(await storage.listStreamingMessageIds()).toEqual([\"a1\"]);\n await storage.updateStreamingMessage(\"a1\", { parts: [requested, { type: \"text\", text: \"готово\", state: \"done\" }] });\n await storage.finishMessage(\"a1\", { status: \"complete\" });\n expect(await savedAnswer(storage)).toMatchObject({ status: \"complete\" });\n });\n\n it(\"updateAwaitingMessage со статусом complete закрывает ожидание\", async () => {\n const storage = await storageWithAwaitingAnswer();\n await storage.updateAwaitingMessage(\"a1\", { parts: [], status: \"complete\" });\n expect(await savedAnswer(storage)).toMatchObject({ status: \"complete\", parts: [] });\n });\n\n it(\"updateAwaitingMessage с expectedParts пишет, только если части в базе те же (порядок ключей не важен)\", async () => {\n const storage = await storageWithAwaitingAnswer();\n const read = (await savedAnswer(storage))!.parts;\n const reordered = read.map((part) => Object.fromEntries(Object.entries(part).reverse())) as StoredMessage[\"parts\"];\n const responded = { ...requested, state: \"approval-responded\", approval: { id: \"ap1\", approved: true } } as StoredMessage[\"parts\"][number];\n await storage.updateAwaitingMessage(\"a1\", { parts: [responded], expectedParts: reordered });\n expect(await savedAnswer(storage)).toMatchObject({ status: \"awaiting_approval\", parts: [responded] });\n });\n\n it(\"updateAwaitingMessage с expectedParts: части изменились с прочтения — MessageNotAwaitingError, в базе чужая запись\", async () => {\n const storage = await storageWithAwaitingAnswer();\n const read = (await savedAnswer(storage))!.parts;\n const theirs = { ...requested, state: \"approval-responded\", approval: { id: \"ap1\", approved: false } } as StoredMessage[\"parts\"][number];\n const mine = { ...requested, state: \"approval-responded\", approval: { id: \"ap1\", approved: true } } as StoredMessage[\"parts\"][number];\n await storage.updateAwaitingMessage(\"a1\", { parts: [theirs] });\n await expect(storage.updateAwaitingMessage(\"a1\", { parts: [mine], status: \"streaming\", expectedParts: read })).rejects.toBeInstanceOf(\n MessageNotAwaitingError,\n );\n expect(await savedAnswer(storage)).toMatchObject({ status: \"awaiting_approval\", parts: [theirs] });\n });\n\n it(\"не из ожидания — MessageNotAwaitingError; ожидающее не пишется как идущее\", async () => {\n const storage = await storageWithAwaitingAnswer();\n await storage.insertMessage(streamingAnswer(\"a2\", \"u1\", \"2099-01-01T00:00:02.000Z\"));\n await expect(storage.updateAwaitingMessage(\"a2\", { parts: [] })).rejects.toBeInstanceOf(MessageNotAwaitingError);\n await expect(storage.updateAwaitingMessage(\"u1\", { parts: [] })).rejects.toBeInstanceOf(MessageNotAwaitingError);\n await expect(storage.updateAwaitingMessage(\"missing\", { parts: [] })).rejects.toThrow(\"Сообщения missing нет\");\n await expect(storage.updateStreamingMessage(\"a1\", { parts: [] })).rejects.toBeInstanceOf(MessageAlreadyFinishedError);\n });\n });\n\n describe(\"ждущий виджет и несколько копий сервера (SC-002, SC-003)\", () => {\n it(\"служба, созданная заново на том же хранилище, видит ждущий виджет и принимает ответ\", async () => {\n const storage = await createStorage();\n const asking = widgetService(storage);\n const chat = await asking.createChat(\"anna\");\n await drain(await asking.sendMessage(\"anna\", chat.id, widgetQuestion()));\n const restarted = widgetService(storage);\n expect(await restarted.answerWidget({ chatId: chat.id, ownerId: \"anna\", toolCallId: \"w1\", answer: { выбрано: \"Про\" } })).toEqual({ resumed: true });\n await drain((await restarted.subscribe(\"anna\", chat.id))!);\n const answer = (await storage.listMessages(chat.id)).at(-1)!;\n expect(answer.status).toBe(\"complete\");\n expect(answer.parts.find((part) => (part as { toolCallId?: string }).toolCallId === \"w1\")).toMatchObject({ state: \"output-available\", output: { выбрано: \"Про\" } });\n });\n\n it(\"две копии одновременно отвечают на один виджет: принят ровно один ответ, второй — WidgetNotPendingError (20 повторов)\", async () => {\n const storage = await createStorage();\n const [first, second] = [widgetService(storage), widgetService(storage)];\n for (let round = 0; round < 20; round++) {\n const chat = await first.createChat(\"anna\");\n await drain(await first.sendMessage(\"anna\", chat.id, widgetQuestion(`u${round}`)));\n const answers = [\n { service: first, choice: \"Базовый\" },\n { service: second, choice: \"Про\" },\n ];\n const results = await Promise.allSettled(\n answers.map(({ service, choice }) => service.answerWidget({ chatId: chat.id, ownerId: \"anna\", toolCallId: \"w1\", answer: { выбрано: choice } })),\n );\n const accepted = results.flatMap((result, index) => (result.status === \"fulfilled\" ? [answers[index]!] : []));\n expect(accepted).toHaveLength(1);\n expect(results.find((result) => result.status === \"rejected\")).toMatchObject({ reason: expect.any(WidgetNotPendingError) });\n // Ход мог кончиться раньше подписки (`subscribe` → null): тогда ждём записанный ответ.\n const stream = await accepted[0]!.service.subscribe(\"anna\", chat.id);\n if (stream) await drain(stream);\n await vi.waitFor(async () => expect((await storage.listMessages(chat.id)).at(-1)!.status).toBe(\"complete\"));\n const answer = (await storage.listMessages(chat.id)).at(-1)!;\n expect(answer.parts.find((part) => (part as { toolCallId?: string }).toolCallId === \"w1\")).toMatchObject({ output: { выбрано: accepted[0]!.choice } });\n }\n // 20 кругов на встроенной базе: при полном прогоне под нагрузкой 5 с по умолчанию не хватает.\n }, 30_000);\n });\n\n describe(\"правка ответа агента (editAnswer)\", () => {\n async function answeredChat(storage: ChatStorage, lockedToolOutputs?: readonly string[]) {\n const editing = editAnswerService(storage, lockedToolOutputs);\n const chat = await editing.service.createChat(\"anna\");\n await drain(await editing.service.sendMessage(\"anna\", chat.id, { id: \"u1\", role: \"user\", parts: [{ type: \"text\", text: \"найди отчёт\" }] }));\n const answer = (await storage.listMessages(chat.id)).find((message) => message.role === \"assistant\")!;\n return { ...editing, chat, answer };\n }\n const toolPart = (message: StoredMessage, toolCallId: string) =>\n message.parts.find((part) => (part as { toolCallId?: string }).toolCallId === toolCallId);\n\n it(\"новый ответ — сосед прежнего под тем же вопросом и текущая ветка; прежний не тронут; модель не вызывается\", async () => {\n const storage = await createStorage();\n const { service, chat, answer, prompts } = await answeredChat(storage);\n const calls = prompts.length;\n const edited = await service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Отчёт не найден.\", toolOutputs: { f1: \"ничего нет\" } });\n expect(prompts).toHaveLength(calls);\n expect(edited).toMatchObject({ chatId: chat.id, parentId: answer.parentId, role: \"assistant\", status: \"complete\", usage: null, modelId: answer.modelId, providerId: answer.providerId });\n expect(edited.id).not.toBe(answer.id);\n expect(edited.parts.filter((part) => part.type === \"text\")).toEqual([{ type: \"text\", text: \"Отчёт не найден.\", state: \"done\" }]);\n expect(toolPart(edited, \"f1\")).toMatchObject({ state: \"output-available\", output: \"ничего нет\", input: { name: \"отчёт\" } });\n expect(await storage.getMessage(answer.id)).toEqual(answer);\n expect(await storage.getMessage(edited.id)).toEqual(edited);\n expect((await service.getHistory(\"anna\", chat.id)).messages.map((message) => message.id)).toEqual([\"u1\", edited.id]);\n expect((await service.getBranchForks(\"anna\", chat.id)).forks).toEqual([expect.objectContaining({ messageId: edited.id })]);\n });\n\n it(\"следующий вопрос видит правленый ответ и новый результат инструмента\", async () => {\n const storage = await createStorage();\n const { service, chat, answer, prompts } = await answeredChat(storage);\n await service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Отчёт не найден.\", toolOutputs: { f1: \"ничего нет\" } });\n const calls = prompts.length;\n await drain(await service.sendMessage(\"anna\", chat.id, { id: \"u2\", role: \"user\", parts: [{ type: \"text\", text: \"а теперь?\" }] }));\n const sent = JSON.stringify(prompts[calls]);\n expect(sent).toContain(\"Отчёт не найден.\");\n expect(sent).toContain(\"ничего нет\");\n expect(sent).not.toContain(\"Нашёл отчёт.\");\n expect(sent).not.toContain(\"отчёт.pdf\");\n });\n\n it(\"результат инструмента из lockedToolOutputs не правится, текст рядом с ним — правится\", async () => {\n const storage = await createStorage();\n const { service, chat, answer } = await answeredChat(storage, [\"find\"]);\n await expect(service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Новый.\", toolOutputs: { f1: \"ничего\" } })).rejects.toMatchObject({\n kind: \"invalid_tool_output\",\n });\n expect(toolPart(await service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Новый.\" }), \"f1\")).toEqual(toolPart(answer, \"f1\"));\n });\n\n it(\"ошибки правки: kind в AnswerEditError, ничего не записано\", async () => {\n const storage = await createStorage();\n const { service, chat, answer } = await answeredChat(storage);\n const kindOf = (attempt: Promise<unknown>) => attempt.then(() => \"принято\", (error: unknown) => (error instanceof AnswerEditError ? error.kind : error));\n expect(await kindOf(service.editAnswer(\"boris\", chat.id, answer.id, { text: \"Чужое.\" }))).toBe(\"chat_not_found\");\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, \"нет-такого\", { text: \"Новый.\" }))).toBe(\"message_not_found\");\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, \"u1\", { text: \"Новый.\" }))).toBe(\"not_an_answer\");\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, answer.id, { text: \" \" }))).toBe(\"empty_text\");\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Новый.\", toolOutputs: { чужой: 1 } }))).toBe(\"invalid_tool_output\");\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Ищу отчёт.\\n\\nНашёл отчёт.\" }))).toBe(\"nothing_changed\");\n const before = await storage.listMessages(chat.id);\n expect(before).toHaveLength(2);\n await service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Новый.\" });\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Ещё новее.\" }))).toBe(\"not_on_current_branch\");\n await storage.insertMessage({ ...streamingAnswer(\"a-broken\", \"u1\", \"2099-01-01T00:00:00.000Z\"), chatId: chat.id });\n await storage.finishMessage(\"a-broken\", { status: \"error\" });\n await service.selectBranch(\"anna\", chat.id, \"a-broken\");\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, \"a-broken\", { text: \"Новый.\" }))).toBe(\"answer_busy\");\n });\n });\n\n it(\"getMessage отдаёт сообщение целиком по id, неизвестного нет\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a9\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n expect(await storage.getMessage(\"a9\")).toMatchObject({ id: \"a9\", chatId: chatInput.id, status: \"streaming\" });\n expect(await storage.getMessage(\"нет-такого\")).toBeNull();\n });\n\n it(\"listStreamingMessageIds возвращает только идущие ответы\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a2\", \"u1\", \"2099-01-01T00:00:02.000Z\"));\n await storage.finishMessage(\"a1\", { status: \"complete\" });\n expect(await storage.listStreamingMessageIds()).toEqual([\"a2\"]);\n });\n\n describe(\"знак жизни идущего ответа (FR-060)\", () => {\n /** Давно: ответ, созданный тогда и без знака жизни, молчит дольше любого порога. */\n const longAgo = (second: number) => `2000-01-01T00:00:${String(second).padStart(2, \"0\")}.000Z`;\n const minute = 60_000;\n const silent = (storage: ChatStorage, filter: { silentForMs: number; chatId?: string }) =>\n storage.listSilentAnswerIds!(filter).then((ids) => ids.sort());\n\n it(\"молчащие ответы: без знака считается время создания; знак «сейчас» делает ответ живым, «брошен» — молчащим сразу\", async (context) => {\n const storage = await storageWithChat();\n if (!storage.listSilentAnswerIds) return context.skip();\n await storage.insertMessage(userMessage(\"u1\", longAgo(0)));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", longAgo(1)));\n await storage.insertMessage({ ...streamingAnswer(\"a2\", \"u1\", longAgo(2)), alive: \"now\" });\n await storage.insertMessage({ ...streamingAnswer(\"a3\", \"u1\", longAgo(3)), alive: \"now\" });\n await storage.updateStreamingMessage(\"a3\", { parts: [], alive: \"released\" });\n expect(await silent(storage, { silentForMs: minute })).toEqual([\"a1\", \"a3\"]);\n expect((await storage.listStreamingMessageIds()).sort()).toEqual([\"a1\", \"a2\", \"a3\"]);\n });\n\n it(\"«сейчас» — по часам хранилища: знак стареет со временем; запись без знака знак не стирает\", async (context) => {\n const storage = await storageWithChat();\n if (!storage.listSilentAnswerIds) return context.skip();\n await storage.insertMessage(userMessage(\"u1\", longAgo(0)));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", longAgo(1)));\n await storage.updateStreamingMessage(\"a1\", { parts: [], alive: \"now\" });\n await storage.updateStreamingMessage(\"a1\", { parts: [{ type: \"text\", text: \"ещё\", state: \"done\" }] });\n expect(await silent(storage, { silentForMs: minute })).toEqual([]);\n await new Promise((resolve) => setTimeout(resolve, 60));\n expect(await silent(storage, { silentForMs: 20 })).toEqual([\"a1\"]);\n });\n\n it(\"только ответы нужного чата, если он задан\", async (context) => {\n const storage = await storageWithChat();\n if (!storage.listSilentAnswerIds) return context.skip();\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n await storage.insertMessage(userMessage(\"u1\", longAgo(0)));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", longAgo(1)));\n await storage.insertMessage({ ...userMessage(\"b1\", longAgo(0)), chatId: \"chat-2\" });\n await storage.insertMessage({ ...streamingAnswer(\"b2\", \"b1\", longAgo(1)), chatId: \"chat-2\" });\n expect(await silent(storage, { silentForMs: minute, chatId: \"chat-2\" })).toEqual([\"b2\"]);\n expect(await silent(storage, { silentForMs: minute })).toEqual([\"a1\", \"b2\"]);\n });\n\n it(\"ответ, вернувшийся в работу после подтверждения, получает знак жизни\", async (context) => {\n const storage = await storageWithChat();\n if (!storage.listSilentAnswerIds) return context.skip();\n await storage.insertMessage(userMessage(\"u1\", longAgo(0)));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", longAgo(1)));\n await storage.finishMessage(\"a1\", { status: \"awaiting_approval\" });\n await storage.updateAwaitingMessage(\"a1\", { parts: [], status: \"streaming\", alive: \"now\" });\n expect(await silent(storage, { silentForMs: minute })).toEqual([]);\n expect(await storage.listStreamingMessageIds()).toEqual([\"a1\"]);\n });\n\n it(\"лёгкая отметка «жив» пишет только знак: части и расход прежние; законченный ответ — MessageAlreadyFinishedError\", async (context) => {\n const storage = await storageWithChat();\n if (!storage.markAnswerAlive || !storage.listSilentAnswerIds) return context.skip();\n await storage.insertMessage(userMessage(\"u1\", longAgo(0)));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", longAgo(1)));\n const parts = [{ type: \"text\" as const, text: \"начало\", state: \"streaming\" as const }];\n const usage = { inputTokens: 10, cachedInputTokens: 0, outputTokens: 2, reasoningTokens: 0 };\n await storage.updateStreamingMessage(\"a1\", { parts, usage });\n await storage.markAnswerAlive(\"a1\");\n expect(await silent(storage, { silentForMs: minute })).toEqual([]);\n expect(await storage.getMessage(\"a1\")).toMatchObject({ parts, usage, status: \"streaming\" });\n await storage.finishMessage(\"a1\", { status: \"interrupted\" });\n await expect(storage.markAnswerAlive(\"a1\")).rejects.toBeInstanceOf(MessageAlreadyFinishedError);\n await expect(storage.markAnswerAlive(\"missing\")).rejects.toThrow(\"Сообщения missing нет\");\n });\n\n it(\"знак жизни не возвращается при чтении\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", longAgo(0)));\n await storage.insertMessage({ ...streamingAnswer(\"a1\", \"u1\", longAgo(1)), alive: \"now\" });\n for (const message of [await storage.getMessage(\"a1\"), (await storage.listMessages(chatInput.id)).find((found) => found.id === \"a1\")]) {\n expect(message).not.toHaveProperty(\"alive\");\n expect(message).not.toHaveProperty(\"aliveAt\");\n }\n });\n });\n\n it(\"сообщения с одинаковым временем создания отдаются в порядке записи\", async () => {\n const storage = await storageWithChat();\n const sameTime = \"2099-01-01T00:00:00.000Z\";\n const ids = [\"m5\", \"m1\", \"m4\", \"m2\", \"m3\"];\n for (const id of ids) await storage.insertMessage(userMessage(id, sameTime));\n expect((await storage.listMessages(chatInput.id)).map((message) => message.id)).toEqual(ids);\n });\n\n it(\"запись в ответ, которого нет, — ошибка «Сообщения … нет»\", async () => {\n const storage = await storageWithChat();\n await expect(storage.updateStreamingMessage(\"missing\", { parts: [] })).rejects.toThrow(\"Сообщения missing нет\");\n await expect(storage.finishMessage(\"missing\", { status: \"complete\" })).rejects.toThrow(\"Сообщения missing нет\");\n });\n\n it(\"чаты не путаются: сообщения и идущие ответы каждого чата свои\", async () => {\n const storage = await storageWithChat();\n await storage.createChat({ ...chatInput, id: \"chat-2\", ownerId: \"boris\" });\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.insertMessage({ ...userMessage(\"b1\", \"2099-01-01T00:00:00.000Z\"), chatId: \"chat-2\" });\n expect((await storage.listMessages(chatInput.id)).map((message) => message.id)).toEqual([\"u1\", \"a1\"]);\n expect((await storage.listMessages(\"chat-2\")).map((message) => message.id)).toEqual([\"b1\"]);\n expect((await storage.getChat(\"chat-2\"))?.ownerId).toBe(\"boris\");\n expect((await storage.getChat(chatInput.id))?.updatedAt).toBe(\"2099-01-01T00:00:01.000Z\");\n expect((await storage.getChat(\"chat-2\"))?.updatedAt).toBe(\"2099-01-01T00:00:00.000Z\");\n expect(await storage.listStreamingMessageIds()).toEqual([\"a1\"]);\n });\n\n it(\"поля без значения возвращаются как null, а пустые рассуждения — как {}\", async () => {\n const storage = await storageWithChat();\n const message = userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\");\n await storage.insertMessage(message);\n const [saved] = await storage.listMessages(chatInput.id);\n expect(saved).toEqual(message);\n expect(saved?.usage).toBeNull();\n expect(saved?.error).toBeNull();\n expect(saved?.modelId).toBeNull();\n expect(saved?.parentId).toBeNull();\n expect(saved?.reasoningDurationsMs).toEqual({});\n });\n\n it(\"очень длинный ответ сохраняется и читается целиком\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const text = \"Длинный ответ, «кавычки», \\\\ обратная косая, эмодзи 🙂. \".repeat(6000);\n await storage.finishMessage(\"a1\", { status: \"complete\", parts: [{ type: \"text\", text, state: \"done\" }] });\n const saved = (await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\");\n expect(saved?.parts).toEqual([{ type: \"text\", text, state: \"done\" }]);\n });\n\n it(\"updateChatModel неизвестного чата ничего не делает\", async () => {\n const storage = await storageWithChat();\n await expect(storage.updateChatModel(\"missing\", { modelId: \"m\", providerId: \"p\" })).resolves.toBeUndefined();\n expect(await storage.getChat(\"missing\")).toBeNull();\n });\n\n it(\"чтение formatVersion больше известной — UnsupportedFormatVersionError, запись не меняется\", async () => {\n const storage = await storageWithChat();\n const fromFuture = { ...userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"), formatVersion: CURRENT_FORMAT_VERSION + 1 };\n await storage.insertMessage(fromFuture);\n await expect(storage.listMessages(chatInput.id)).rejects.toBeInstanceOf(UnsupportedFormatVersionError);\n await expect(storage.listMessages(chatInput.id)).rejects.toBeInstanceOf(UnsupportedFormatVersionError);\n await expect(storage.insertMessage(fromFuture)).rejects.toBeInstanceOf(DuplicateMessageError);\n });\n describe(\"список, название и удаление чатов\", () => {\n it(\"у нового чата названия нет; renameChat пишет и стирает его, updatedAt не меняется\", async () => {\n const storage = await storageWithChat();\n expect((await storage.getChat(chatInput.id))?.title).toBeUndefined();\n const before = (await storage.getChat(chatInput.id))?.updatedAt;\n await storage.renameChat(chatInput.id, \"Отпуск в Греции «2026» 🙂\");\n expect(await storage.getChat(chatInput.id)).toMatchObject({ title: \"Отпуск в Греции «2026» 🙂\", updatedAt: before });\n await storage.renameChat(chatInput.id, null);\n expect((await storage.getChat(chatInput.id))?.title).toBeUndefined();\n });\n\n it(\"renameChat неизвестного чата ничего не делает\", async () => {\n const storage = await storageWithChat();\n await expect(storage.renameChat(\"missing\", \"Название\")).resolves.toBeUndefined();\n expect(await storage.getChat(\"missing\")).toBeNull();\n });\n\n it(\"listChats отдаёт только чаты владельца, самые недавние первыми\", async () => {\n const storage = await createStorage();\n await storage.createChat({ ...chatInput, id: \"old\" });\n await storage.createChat({ ...chatInput, id: \"new\" });\n await storage.createChat({ ...chatInput, id: \"boris-chat\", ownerId: \"boris\" });\n await storage.insertMessage({ ...userMessage(\"m-old\", \"2099-01-01T00:00:01.000Z\"), chatId: \"old\" });\n await storage.insertMessage({ ...userMessage(\"m-new\", \"2099-01-01T00:00:05.000Z\"), chatId: \"new\" });\n await storage.insertMessage({ ...userMessage(\"m-boris\", \"2099-01-01T00:00:09.000Z\"), chatId: \"boris-chat\" });\n expect((await storage.listChats(\"anna\")).map((chat) => chat.id)).toEqual([\"new\", \"old\"]);\n expect((await storage.listChats(\"boris\")).map((chat) => chat.id)).toEqual([\"boris-chat\"]);\n expect(await storage.listChats(\"nobody\")).toEqual([]);\n });\n\n it(\"listChats: переписка поднимает чат, переименование порядок не меняет\", async () => {\n const storage = await createStorage();\n await storage.createChat({ ...chatInput, id: \"first\" });\n await storage.createChat({ ...chatInput, id: \"second\" });\n await storage.insertMessage({ ...userMessage(\"m1\", \"2099-01-01T00:00:01.000Z\"), chatId: \"first\" });\n await storage.insertMessage({ ...userMessage(\"m2\", \"2099-01-01T00:00:02.000Z\"), chatId: \"second\" });\n await storage.renameChat(\"first\", \"Переименован\");\n expect((await storage.listChats(\"anna\")).map((chat) => chat.id)).toEqual([\"second\", \"first\"]);\n await storage.insertMessage({ ...userMessage(\"m3\", \"2099-01-01T00:00:03.000Z\"), chatId: \"first\" });\n expect((await storage.listChats(\"anna\")).map((chat) => chat.id)).toEqual([\"first\", \"second\"]);\n expect((await storage.listChats(\"anna\"))[0]).toMatchObject({ id: \"first\", title: \"Переименован\", ownerId: \"anna\" });\n });\n\n it(\"listChats: при равном времени последнего сообщения — по времени создания, затем по id, новее и больше первыми\", async () => {\n const storage = await createStorage();\n for (const id of [\"b\", \"a\", \"c\", \"d\"]) {\n await storage.createChat({ ...chatInput, id });\n await storage.insertMessage({ ...userMessage(`m-${id}`, \"2099-01-01T00:00:00.000Z\"), chatId: id });\n }\n const listed = await storage.listChats(\"anna\");\n expect(listed).toHaveLength(4);\n const expected = [...listed].sort(\n (left, right) => right.createdAt.localeCompare(left.createdAt) || right.id.localeCompare(left.id),\n );\n expect(listed.map((chat) => chat.id)).toEqual(expected.map((chat) => chat.id));\n expect((await storage.listChats(\"anna\")).map((chat) => chat.id)).toEqual(listed.map((chat) => chat.id));\n });\n\n it(\"deleteChat удаляет чат, сообщения всех веток, записи сжатия и выбор веток; другие чаты целы\", async () => {\n const storage = await storageWithChat();\n await storage.createChat({ ...chatInput, id: \"chat-2\", ownerId: \"boris\" });\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.insertMessage({ ...streamingAnswer(\"a2\", \"u1\", \"2099-01-01T00:00:02.000Z\"), status: \"complete\" });\n await storage.insertCompaction({\n id: \"c1\",\n chatId: chatInput.id,\n fromMessageId: \"u1\",\n throughMessageId: \"a1\",\n summary: \"сводка\",\n summaryTokens: 1,\n modelId: \"m\",\n providerId: \"p\",\n usage: null,\n createdAt: \"2099-01-01T00:00:10.000Z\",\n });\n await storage.insertBranchSelection({ id: \"s1\", chatId: chatInput.id, messageId: \"a2\", selectedAt: \"2099-01-01T00:00:11.000Z\" });\n await storage.insertMessage({ ...userMessage(\"b1\", \"2099-01-01T00:00:00.000Z\"), chatId: \"chat-2\" });\n await storage.insertBranchSelection({ id: \"s2\", chatId: \"chat-2\", messageId: \"b1\", selectedAt: \"2099-01-01T00:00:11.000Z\" });\n await storage.insertCompaction({\n id: \"c2\",\n chatId: \"chat-2\",\n fromMessageId: \"b1\",\n throughMessageId: \"b1\",\n summary: \"чужая сводка\",\n summaryTokens: 1,\n modelId: \"m\",\n providerId: \"p\",\n usage: null,\n createdAt: \"2099-01-01T00:00:10.000Z\",\n });\n\n await storage.deleteChat(chatInput.id);\n\n expect(await storage.getChat(chatInput.id)).toBeNull();\n expect(await storage.listMessages(chatInput.id)).toEqual([]);\n expect(await storage.listMessageLinks(chatInput.id)).toEqual([]);\n expect(await storage.listCompactions(chatInput.id)).toEqual([]);\n expect(await storage.listBranchSelections(chatInput.id)).toEqual([]);\n expect((await storage.listChats(\"anna\")).map((chat) => chat.id)).toEqual([]);\n expect(await storage.listStreamingMessageIds()).toEqual([]);\n expect((await storage.listMessages(\"chat-2\")).map((message) => message.id)).toEqual([\"b1\"]);\n expect((await storage.listCompactions(\"chat-2\")).map((record) => record.id)).toEqual([\"c2\"]);\n expect((await storage.listBranchSelections(\"chat-2\")).map((record) => record.id)).toEqual([\"s2\"]);\n expect(await storage.getChat(\"chat-2\")).not.toBeNull();\n });\n\n it(\"deleteChat неизвестного чата ничего не делает; удалённый id можно занять снова\", async () => {\n const storage = await storageWithChat();\n await expect(storage.deleteChat(\"missing\")).resolves.toBeUndefined();\n expect(await storage.getChat(chatInput.id)).not.toBeNull();\n await storage.deleteChat(chatInput.id);\n await storage.deleteChat(chatInput.id);\n await storage.createChat(chatInput);\n expect(await storage.listMessages(chatInput.id)).toEqual([]);\n });\n\n it(\"после удаления запись в сообщения удалённого чата не появляется тихо: чата нет\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.deleteChat(chatInput.id);\n await expect(storage.updateStreamingMessage(\"a1\", { parts: [] })).rejects.toThrow(\"Сообщения a1 нет\");\n });\n });\n\n describe(\"записи сжатия\", () => {\n function compaction(id: string, extra: Partial<StoredCompaction> = {}): StoredCompaction {\n return {\n id,\n chatId: chatInput.id,\n fromMessageId: \"u1\",\n throughMessageId: \"a1\",\n summary: `## Цель\\nсводка ${id} «в кавычках» 🙂`,\n summaryTokens: 321,\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n usage: { inputTokens: 1000, cachedInputTokens: 800, outputTokens: 400, reasoningTokens: 79, contextTokens: 1400 },\n createdAt: \"2099-01-01T00:00:10.000Z\",\n ...extra,\n };\n }\n\n it(\"insertCompaction и listCompactions возвращают запись как записана; у чата без сжатий — пусто\", async () => {\n const storage = await storageWithChat();\n expect(await storage.listCompactions(chatInput.id)).toEqual([]);\n expect(await storage.listCompactions(\"missing\")).toEqual([]);\n await storage.insertCompaction(compaction(\"c1\"));\n expect(await storage.listCompactions(chatInput.id)).toEqual([compaction(\"c1\")]);\n });\n\n it(\"записи отдаются в порядке добавления, даже при одинаковом или обратном времени\", async () => {\n const storage = await storageWithChat();\n await storage.insertCompaction(compaction(\"c2\", { createdAt: \"2099-01-01T00:00:10.000Z\" }));\n await storage.insertCompaction(compaction(\"c1\", { createdAt: \"2099-01-01T00:00:10.000Z\" }));\n await storage.insertCompaction(compaction(\"c3\", { createdAt: \"2099-01-01T00:00:05.000Z\" }));\n expect((await storage.listCompactions(chatInput.id)).map((record) => record.id)).toEqual([\"c2\", \"c1\", \"c3\"]);\n });\n\n it(\"расход на сжатие может быть пустым\", async () => {\n const storage = await storageWithChat();\n await storage.insertCompaction(compaction(\"c1\", { usage: null }));\n expect((await storage.listCompactions(chatInput.id))[0]?.usage).toBeNull();\n });\n\n it(\"записи чатов не путаются\", async () => {\n const storage = await storageWithChat();\n await storage.createChat({ ...chatInput, id: \"chat-2\", ownerId: \"boris\" });\n await storage.insertCompaction(compaction(\"c1\"));\n await storage.insertCompaction(compaction(\"c2\", { chatId: \"chat-2\" }));\n expect((await storage.listCompactions(chatInput.id)).map((record) => record.id)).toEqual([\"c1\"]);\n expect((await storage.listCompactions(\"chat-2\")).map((record) => record.id)).toEqual([\"c2\"]);\n });\n\n it(\"повтор id записи — ошибка, прежняя запись не меняется\", async () => {\n const storage = await storageWithChat();\n await storage.insertCompaction(compaction(\"c1\"));\n await expect(storage.insertCompaction(compaction(\"c1\", { summary: \"другая\" }))).rejects.toThrow();\n expect(await storage.listCompactions(chatInput.id)).toEqual([compaction(\"c1\")]);\n });\n\n it(\"сжатие не трогает оригиналы сообщений и время обновления чата\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const before = await storage.listMessages(chatInput.id);\n const updatedAt = (await storage.getChat(chatInput.id))?.updatedAt;\n await storage.insertCompaction(compaction(\"c1\"));\n expect(await storage.listMessages(chatInput.id)).toEqual(before);\n expect((await storage.getChat(chatInput.id))?.updatedAt).toBe(updatedAt);\n });\n\n it(\"итог ответа хранит contextTokens\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const usage = { inputTokens: 10, cachedInputTokens: 0, outputTokens: 5, reasoningTokens: 0, contextTokens: 15 };\n await storage.finishMessage(\"a1\", { status: \"complete\", usage });\n expect((await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\")?.usage).toEqual(usage);\n });\n\n it(\"идущий ответ хранит расход хода с пометкой «примерно»\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const usage = { inputTokens: 300, cachedInputTokens: 0, outputTokens: 40, reasoningTokens: 0, contextTokens: 340, estimated: true as const };\n await storage.updateStreamingMessage(\"a1\", { parts: [], usage });\n expect((await storage.getMessage(\"a1\"))?.usage).toEqual(usage);\n });\n });\n\n describe(\"выбор ветки\", () => {\n function selection(id: string, extra: Partial<StoredBranchSelection> = {}): StoredBranchSelection {\n return { id, chatId: chatInput.id, messageId: \"a1\", selectedAt: \"2099-01-01T00:00:10.000Z\", ...extra };\n }\n\n it(\"insertBranchSelection и listBranchSelections возвращают запись как записана; у чата без выбора — пусто\", async () => {\n const storage = await storageWithChat();\n expect(await storage.listBranchSelections(chatInput.id)).toEqual([]);\n expect(await storage.listBranchSelections(\"missing\")).toEqual([]);\n await storage.insertBranchSelection(selection(\"s1\"));\n expect(await storage.listBranchSelections(chatInput.id)).toEqual([selection(\"s1\")]);\n });\n\n it(\"записи отдаются в порядке добавления, даже при одинаковом или обратном времени\", async () => {\n const storage = await storageWithChat();\n await storage.insertBranchSelection(selection(\"s2\", { selectedAt: \"2099-01-01T00:00:10.000Z\" }));\n await storage.insertBranchSelection(selection(\"s1\", { selectedAt: \"2099-01-01T00:00:10.000Z\" }));\n await storage.insertBranchSelection(selection(\"s3\", { selectedAt: \"2099-01-01T00:00:05.000Z\" }));\n expect((await storage.listBranchSelections(chatInput.id)).map((record) => record.id)).toEqual([\"s2\", \"s1\", \"s3\"]);\n });\n\n it(\"записи чатов не путаются\", async () => {\n const storage = await storageWithChat();\n await storage.createChat({ ...chatInput, id: \"chat-2\", ownerId: \"boris\" });\n await storage.insertBranchSelection(selection(\"s1\"));\n await storage.insertBranchSelection(selection(\"s2\", { chatId: \"chat-2\" }));\n expect((await storage.listBranchSelections(chatInput.id)).map((record) => record.id)).toEqual([\"s1\"]);\n expect((await storage.listBranchSelections(\"chat-2\")).map((record) => record.id)).toEqual([\"s2\"]);\n });\n\n it(\"повтор id записи — ошибка, прежняя запись не меняется\", async () => {\n const storage = await storageWithChat();\n await storage.insertBranchSelection(selection(\"s1\"));\n await expect(storage.insertBranchSelection(selection(\"s1\", { messageId: \"другое\" }))).rejects.toThrow();\n expect(await storage.listBranchSelections(chatInput.id)).toEqual([selection(\"s1\")]);\n });\n\n it(\"выбор не меняет ни сообщения, ни записи сжатия, ни время обновления чата\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.insertCompaction({\n id: \"c1\",\n chatId: chatInput.id,\n fromMessageId: \"u1\",\n throughMessageId: \"a1\",\n summary: \"сводка\",\n summaryTokens: 5,\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n usage: null,\n createdAt: \"2099-01-01T00:00:05.000Z\",\n });\n const messagesBefore = await storage.listMessages(chatInput.id);\n const compactionsBefore = await storage.listCompactions(chatInput.id);\n const updatedAt = (await storage.getChat(chatInput.id))?.updatedAt;\n await storage.insertBranchSelection(selection(\"s1\"));\n expect(await storage.listMessages(chatInput.id)).toEqual(messagesBefore);\n expect(await storage.listCompactions(chatInput.id)).toEqual(compactionsBefore);\n expect((await storage.getChat(chatInput.id))?.updatedAt).toBe(updatedAt);\n });\n });\n describe(\"записи расхода\", () => {\n function usageRecord(id: string, fields: Partial<UsageRecord> = {}): UsageRecord {\n return {\n id,\n ownerId: \"anna\",\n chatId: chatInput.id,\n messageId: `a-${id}`,\n source: \"answer\",\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n inputTokens: 1000,\n cachedInputTokens: 400,\n cacheWriteTokens: 0,\n outputTokens: 200,\n reasoningTokens: 50,\n costUsd: 0.25,\n createdAt: \"2099-01-15T10:00:00.000Z\",\n ...fields,\n };\n }\n\n it(\"пустой расход — пустая сумма\", async () => {\n const storage = await storageWithChat();\n expect(await storage.sumUsage({ ownerId: \"anna\" })).toEqual([]);\n });\n\n it(\"суммирует токены записей одной пары «модель × провайдер»\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\"));\n await storage.insertUsageRecord(usageRecord(\"r2\", { inputTokens: 500, cacheWriteTokens: 30, source: \"compaction\", messageId: null }));\n expect(await storage.sumUsage({ ownerId: \"anna\" })).toEqual([\n {\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n inputTokens: 1500,\n cachedInputTokens: 800,\n cacheWriteTokens: 30,\n outputTokens: 400,\n reasoningTokens: 100,\n costUsd: 0.5,\n },\n ]);\n });\n\n it(\"запись «примерно» принимается и считается в сумме вместе с остальными\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\"));\n await storage.insertUsageRecord(usageRecord(\"r2\", { estimated: true, inputTokens: 300 }));\n expect((await storage.sumUsage({ ownerId: \"anna\" }))[0]?.inputTokens).toBe(1300);\n });\n\n it(\"деньги суммируются из записей: цена на момент расхода, а не пересчёт по токенам\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\", { costUsd: 0.1 }));\n await storage.insertUsageRecord(usageRecord(\"r2\", { costUsd: 0.2, inputTokens: 0, outputTokens: 0 }));\n await storage.insertUsageRecord(usageRecord(\"r3\", { costUsd: 0 }));\n const [sum] = await storage.sumUsage({ ownerId: \"anna\" });\n expect(sum?.costUsd).toBeCloseTo(0.3, 12);\n });\n\n it(\"разные пары «модель × провайдер» суммируются отдельно\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\"));\n await storage.insertUsageRecord(usageRecord(\"r2\", { providerId: \"openrouter\" }));\n const sums = await storage.sumUsage({ ownerId: \"anna\" });\n expect(sums.map((sum) => sum.providerId).sort()).toEqual([\"deepseek\", \"openrouter\"]);\n });\n\n it(\"фильтр по владельцу и по чату\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\"));\n await storage.insertUsageRecord(usageRecord(\"r2\", { chatId: \"chat-2\", outputTokens: 7 }));\n await storage.insertUsageRecord(usageRecord(\"r3\", { ownerId: \"boris\", chatId: \"chat-3\", outputTokens: 11 }));\n expect((await storage.sumUsage({ ownerId: \"anna\" }))[0]?.outputTokens).toBe(207);\n expect((await storage.sumUsage({ chatId: \"chat-2\" }))[0]?.outputTokens).toBe(7);\n expect((await storage.sumUsage({ ownerId: \"boris\" }))[0]?.outputTokens).toBe(11);\n expect((await storage.sumUsage({ ownerId: \"anna\", chatId: \"chat-3\" }))).toEqual([]);\n expect(await storage.sumUsage({ ownerId: \"nobody\" })).toEqual([]);\n });\n\n it(\"фильтр по сообщению и источнику: только расход ответа этого сообщения\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\", { messageId: \"m1\", outputTokens: 1 }));\n await storage.insertUsageRecord(usageRecord(\"r2\", { messageId: \"m1\", outputTokens: 10 }));\n await storage.insertUsageRecord(usageRecord(\"r3\", { messageId: \"m2\", outputTokens: 100 }));\n await storage.insertUsageRecord(usageRecord(\"r4\", { messageId: \"m1\", source: \"speech\", outputTokens: 1000 }));\n expect((await storage.sumUsage({ chatId: \"chat-1\", messageId: \"m1\", source: \"answer\" }))[0]?.outputTokens).toBe(11);\n expect((await storage.sumUsage({ messageId: \"m1\" }))[0]?.outputTokens).toBe(1011);\n expect(await storage.sumUsage({ messageId: \"m3\" })).toEqual([]);\n });\n\n it(\"«since» включает границу и отсекает более раннее\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\", { createdAt: \"2099-01-31T23:59:59.999Z\", outputTokens: 1 }));\n await storage.insertUsageRecord(usageRecord(\"r2\", { createdAt: \"2099-02-01T00:00:00.000Z\", outputTokens: 10 }));\n await storage.insertUsageRecord(usageRecord(\"r3\", { createdAt: \"2099-02-10T00:00:00.000Z\", outputTokens: 100 }));\n expect((await storage.sumUsage({ ownerId: \"anna\", since: \"2099-02-01T00:00:00.000Z\" }))[0]?.outputTokens).toBe(110);\n expect((await storage.sumUsage({ ownerId: \"anna\" }))[0]?.outputTokens).toBe(111);\n });\n\n it(\"повтор id — ошибка, сумма не меняется\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\"));\n await expect(storage.insertUsageRecord(usageRecord(\"r1\", { outputTokens: 999 }))).rejects.toThrow();\n expect((await storage.sumUsage({ ownerId: \"anna\" }))[0]?.outputTokens).toBe(200);\n });\n\n it(\"поиск записи расхода по id: есть — true, нет — false\", async (context) => {\n const storage = await createStorage();\n if (!storage.hasUsageRecord) return context.skip();\n expect(await storage.hasUsageRecord(\"r1\")).toBe(false);\n await storage.insertUsageRecord(usageRecord(\"r1\", { chatId: \"deleted-chat\" }));\n expect(await storage.hasUsageRecord(\"r1\")).toBe(true);\n expect(await storage.hasUsageRecord(\"r2\")).toBe(false);\n });\n\n it(\"запись не требует чата и не меняет время его обновления\", async () => {\n const storage = await createStorage();\n await storage.insertUsageRecord(usageRecord(\"r1\", { chatId: \"deleted-chat\" }));\n expect((await storage.sumUsage({ chatId: \"deleted-chat\" }))[0]?.inputTokens).toBe(1000);\n await storage.createChat(chatInput);\n const updatedAt = (await storage.getChat(chatInput.id))?.updatedAt;\n await storage.insertUsageRecord(usageRecord(\"r2\"));\n expect((await storage.getChat(chatInput.id))?.updatedAt).toBe(updatedAt);\n });\n\n it(\"десять записей одновременно дают точную сумму\", async () => {\n const storage = await storageWithChat();\n await Promise.all(Array.from({ length: 10 }, (_, index) => storage.insertUsageRecord(usageRecord(`p${index}`, { outputTokens: 3 }))));\n expect((await storage.sumUsage({ ownerId: \"anna\" }))[0]?.outputTokens).toBe(30);\n });\n\n describe(\"сумма по списку чатов (sumUsageByChat, необязательный)\", () => {\n async function storageWithUsageByChat(context: { skip: () => never }) {\n const storage = await createStorage();\n if (!storage.sumUsageByChat) {\n if (options.usageByChat === \"required\") throw new Error(\"У хранилища нет sumUsageByChat\");\n context.skip();\n }\n return storage as ChatStorage & Required<Pick<ChatStorage, \"sumUsageByChat\">>;\n }\n const byChat = <T extends { chatId: string; modelId: string }>(sums: T[]) =>\n [...sums].sort((left, right) => `${left.chatId}:${left.modelId}`.localeCompare(`${right.chatId}:${right.modelId}`));\n\n it(\"по чату и паре «модель × провайдер»; чужие чаты из списка не попадают, чаты без записей — тоже\", async (context) => {\n const storage = await storageWithUsageByChat(context);\n await storage.insertUsageRecord(usageRecord(\"r1\", { chatId: \"chat-1\" }));\n await storage.insertUsageRecord(usageRecord(\"r2\", { chatId: \"chat-1\", outputTokens: 5, costUsd: 0.5 }));\n await storage.insertUsageRecord(usageRecord(\"r3\", { chatId: \"chat-1\", modelId: \"gpt-x\", providerId: \"openai\", outputTokens: 7 }));\n await storage.insertUsageRecord(usageRecord(\"r4\", { chatId: \"chat-2\", outputTokens: 11 }));\n await storage.insertUsageRecord(usageRecord(\"r5\", { chatId: \"chat-3\", outputTokens: 13 }));\n const sums = byChat(await storage.sumUsageByChat({ chatIds: [\"chat-1\", \"chat-2\", \"chat-empty\"] }));\n expect(sums.map(({ chatId, modelId, outputTokens }) => [chatId, modelId, outputTokens])).toEqual([\n [\"chat-1\", \"deepseek-4.1-flash\", 205],\n [\"chat-1\", \"gpt-x\", 7],\n [\"chat-2\", \"deepseek-4.1-flash\", 11],\n ]);\n expect(sums[0]).toEqual({\n chatId: \"chat-1\",\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n inputTokens: 2000,\n cachedInputTokens: 800,\n cacheWriteTokens: 0,\n outputTokens: 205,\n reasoningTokens: 100,\n costUsd: 0.75,\n });\n });\n\n it(\"фильтры source, ownerId и since; пустой список — пустая сумма\", async (context) => {\n const storage = await storageWithUsageByChat(context);\n await storage.insertUsageRecord(usageRecord(\"r1\", { chatId: \"chat-1\", source: \"first_message\", outputTokens: 3 }));\n await storage.insertUsageRecord(usageRecord(\"r2\", { chatId: \"chat-1\", outputTokens: 5, createdAt: \"2099-03-01T00:00:00.000Z\" }));\n await storage.insertUsageRecord(usageRecord(\"r3\", { chatId: \"chat-2\", ownerId: \"boris\", source: \"first_message\", outputTokens: 7 }));\n const outputs = async (filter: Parameters<typeof storage.sumUsageByChat>[0]) =>\n byChat(await storage.sumUsageByChat(filter)).map(({ chatId, outputTokens }) => [chatId, outputTokens]);\n expect(await outputs({ chatIds: [\"chat-1\", \"chat-2\"], source: \"first_message\" })).toEqual([[\"chat-1\", 3], [\"chat-2\", 7]]);\n expect(await outputs({ chatIds: [\"chat-1\", \"chat-2\"], ownerId: \"anna\" })).toEqual([[\"chat-1\", 8]]);\n expect(await outputs({ chatIds: [\"chat-1\", \"chat-2\"], since: \"2099-02-01T00:00:00.000Z\" })).toEqual([[\"chat-1\", 5]]);\n expect(await storage.sumUsageByChat({ chatIds: [] })).toEqual([]);\n });\n });\n });\n\n describe(\"озвучка в расходах (source: speech)\", () => {\n function speechRecord(id: string, fields: Partial<UsageRecord> = {}): UsageRecord {\n return {\n id,\n ownerId: \"anna\",\n chatId: chatInput.id,\n messageId: `a-${id}`,\n source: \"speech\",\n modelId: \"eleven_v4_turbo\",\n providerId: \"elevenlabs\",\n inputTokens: 200,\n cachedInputTokens: 0,\n cacheWriteTokens: 0,\n outputTokens: 0,\n reasoningTokens: 0,\n costUsd: 0.012,\n createdAt: \"2099-01-15T10:00:00.000Z\",\n ...fields,\n };\n }\n\n it(\"запись озвучки сохраняется и суммируется отдельной парой «модель × провайдер»\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(speechRecord(\"s1\"));\n await storage.insertUsageRecord(speechRecord(\"s2\", { inputTokens: 300, costUsd: 0.018 }));\n const [sum] = await storage.sumUsage({ ownerId: \"anna\" });\n expect(sum).toMatchObject({ modelId: \"eleven_v4_turbo\", providerId: \"elevenlabs\", inputTokens: 500, outputTokens: 0 });\n expect(sum!.costUsd).toBeCloseTo(0.03, 10);\n });\n\n it(\"озвучка приближает лимит: сумма денег включает и ответы, и озвучку\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord({\n id: \"answer-1\",\n ownerId: \"anna\",\n chatId: chatInput.id,\n messageId: \"a-1\",\n source: \"answer\",\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n inputTokens: 1000,\n cachedInputTokens: 0,\n cacheWriteTokens: 0,\n outputTokens: 100,\n reasoningTokens: 0,\n costUsd: 0.25,\n createdAt: \"2099-01-15T09:00:00.000Z\",\n });\n const before = (await storage.sumUsage({ ownerId: \"anna\" })).reduce((total, sum) => total + sum.costUsd, 0);\n await storage.insertUsageRecord(speechRecord(\"s1\", { costUsd: 0.1 }));\n const after = (await storage.sumUsage({ ownerId: \"anna\" })).reduce((total, sum) => total + sum.costUsd, 0);\n expect(after - before).toBeCloseTo(0.1, 10);\n });\n\n it(\"озвучка чужого человека в сумму не попадает\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(speechRecord(\"s1\", { ownerId: \"boris\" }));\n expect(await storage.sumUsage({ ownerId: \"anna\" })).toEqual([]);\n });\n });\n\n describe(\"чаты объектов (необязательные методы)\", () => {\n type SubjectStorage = ChatStorage & Required<Pick<ChatStorage, \"findChatBySubject\">>;\n\n /** Хранилище без `findChatBySubject` договор не нарушает: ядро тогда не включает чаты объектов и говорит об этом при старте. */\n async function subjectStorage(context: { skip: () => never }): Promise<SubjectStorage> {\n const storage = await createStorage();\n if (!storage.findChatBySubject) {\n if (options.subjectChats === \"required\") throw new Error(\"У хранилища нет чатов объектов\");\n context.skip();\n }\n return storage as SubjectStorage;\n }\n\n const lessonData = { lesson: { id: 7, title: \"Дроби\", tags: [\"математика\", \"5 класс\"] }, open: true, score: null };\n\n it(\"ключ и данные объекта пишутся и читаются; чат без ключа — без этих полей\", async (context) => {\n const storage = await subjectStorage(context);\n const created = await storage.createChat({ ...chatInput, id: \"lesson-chat\", subjectKey: \"lesson:7\", subjectData: lessonData });\n expect(created).toMatchObject({ subjectKey: \"lesson:7\", subjectData: lessonData });\n expect(await storage.getChat(\"lesson-chat\")).toMatchObject({ subjectKey: \"lesson:7\", subjectData: lessonData });\n\n await storage.createChat({ ...chatInput, id: \"plain\" });\n const plain = await storage.getChat(\"plain\");\n expect(plain).not.toHaveProperty(\"subjectKey\");\n expect(plain).not.toHaveProperty(\"subjectData\");\n });\n\n it(\"ключ без данных: subjectData нет\", async (context) => {\n const storage = await subjectStorage(context);\n await storage.createChat({ ...chatInput, id: \"lesson-chat\", subjectKey: \"lesson:7\" });\n const chat = await storage.getChat(\"lesson-chat\");\n expect(chat?.subjectKey).toBe(\"lesson:7\");\n expect(chat).not.toHaveProperty(\"subjectData\");\n });\n\n it(\"findChatBySubject находит чат владельца по ключу; чужой владелец и неизвестный ключ — null\", async (context) => {\n const storage = await subjectStorage(context);\n await storage.createChat({ ...chatInput, id: \"lesson-chat\", subjectKey: \"lesson:7\", subjectData: lessonData });\n expect(await storage.findChatBySubject(chatInput.ownerId, \"lesson:7\")).toMatchObject({ id: \"lesson-chat\", subjectData: lessonData });\n expect(await storage.findChatBySubject(\"boris\", \"lesson:7\")).toBeNull();\n expect(await storage.findChatBySubject(chatInput.ownerId, \"lesson:8\")).toBeNull();\n });\n\n it(\"повтор ключа у того же владельца — DuplicateChatSubjectError, второй чат не записан; у другого владельца — можно\", async (context) => {\n const storage = await subjectStorage(context);\n await storage.createChat({ ...chatInput, id: \"first\", subjectKey: \"lesson:7\" });\n await expect(storage.createChat({ ...chatInput, id: \"second\", subjectKey: \"lesson:7\" })).rejects.toBeInstanceOf(DuplicateChatSubjectError);\n expect(await storage.getChat(\"second\")).toBeNull();\n expect((await storage.findChatBySubject(chatInput.ownerId, \"lesson:7\"))?.id).toBe(\"first\");\n\n await storage.createChat({ ...chatInput, id: \"boris-chat\", ownerId: \"boris\", subjectKey: \"lesson:7\" });\n expect((await storage.findChatBySubject(\"boris\", \"lesson:7\"))?.id).toBe(\"boris-chat\");\n });\n\n it(\"чатов без ключа у владельца может быть сколько угодно\", async (context) => {\n const storage = await subjectStorage(context);\n for (const id of [\"a\", \"b\", \"c\"]) await storage.createChat({ ...chatInput, id });\n expect(await storage.listChats(chatInput.ownerId)).toHaveLength(3);\n });\n\n it(\"удаление чата освобождает ключ\", async (context) => {\n const storage = await subjectStorage(context);\n await storage.createChat({ ...chatInput, id: \"first\", subjectKey: \"lesson:7\" });\n await storage.deleteChat(\"first\");\n expect(await storage.findChatBySubject(chatInput.ownerId, \"lesson:7\")).toBeNull();\n await storage.createChat({ ...chatInput, id: \"again\", subjectKey: \"lesson:7\" });\n expect((await storage.findChatBySubject(chatInput.ownerId, \"lesson:7\"))?.id).toBe(\"again\");\n });\n\n it(\"listChats: по умолчанию и с exclude — без чатов с ключом; include — все; only — только с ключом; порядок прежний\", async (context) => {\n const storage = await subjectStorage(context);\n await storage.createChat({ ...chatInput, id: \"plain-old\" });\n await storage.createChat({ ...chatInput, id: \"lesson-old\", subjectKey: \"lesson:1\" });\n await storage.createChat({ ...chatInput, id: \"plain-new\" });\n await storage.createChat({ ...chatInput, id: \"lesson-new\", subjectKey: \"lesson:2\" });\n await storage.createChat({ ...chatInput, id: \"boris-lesson\", ownerId: \"boris\", subjectKey: \"lesson:1\" });\n const touch = async (chatId: string, at: string) => storage.insertMessage({ ...userMessage(`m-${chatId}`, at), chatId });\n await touch(\"plain-old\", \"2099-01-01T00:00:01.000Z\");\n await touch(\"lesson-old\", \"2099-01-01T00:00:02.000Z\");\n await touch(\"plain-new\", \"2099-01-01T00:00:03.000Z\");\n await touch(\"lesson-new\", \"2099-01-01T00:00:04.000Z\");\n\n const ids = async (subjects?: \"exclude\" | \"include\" | \"only\") =>\n (await storage.listChats(chatInput.ownerId, subjects ? { subjects } : undefined)).map((chat) => chat.id);\n expect(await ids()).toEqual([\"plain-new\", \"plain-old\"]);\n expect(await ids(\"exclude\")).toEqual([\"plain-new\", \"plain-old\"]);\n expect(await ids(\"include\")).toEqual([\"lesson-new\", \"plain-new\", \"lesson-old\", \"plain-old\"]);\n expect(await ids(\"only\")).toEqual([\"lesson-new\", \"lesson-old\"]);\n expect((await storage.listChats(chatInput.ownerId, { subjects: \"only\" }))[0]?.subjectKey).toBe(\"lesson:2\");\n });\n\n it(\"createChat с названием и датой: дата создания и обновления — заданная, название — заданное\", async (context) => {\n const storage = await subjectStorage(context);\n const createdAt = \"2024-03-05T10:20:30.000Z\";\n const created = await storage.createChat({ ...chatInput, id: \"dated\", title: \"Урок 7. Дроби\", createdAt });\n expect(created).toMatchObject({ title: \"Урок 7. Дроби\", createdAt, updatedAt: createdAt });\n expect(await storage.getChat(\"dated\")).toMatchObject({ title: \"Урок 7. Дроби\", createdAt, updatedAt: createdAt });\n });\n\n it(\"данные объекта — копия: правка отданного объекта хранилище не меняет\", async (context) => {\n const storage = await subjectStorage(context);\n const data = structuredClone(lessonData);\n await storage.createChat({ ...chatInput, id: \"lesson-chat\", subjectKey: \"lesson:7\", subjectData: data });\n data.lesson.tags.push(\"лишнее\");\n const read = await storage.getChat(\"lesson-chat\");\n (read?.subjectData as typeof lessonData).lesson.tags.push(\"ещё\");\n expect((await storage.getChat(\"lesson-chat\"))?.subjectData).toEqual(lessonData);\n });\n });\n\n describe(\"данные чата (data, updateChatData, фильтр data в listChats; необязательные)\", () => {\n type ChatDataStorage = ChatStorage & Required<Pick<ChatStorage, \"updateChatData\">>;\n\n /** Хранилище без `updateChatData` договор не нарушает: ядро тогда данных чата не обещает. */\n async function chatDataStorage(context: { skip: () => never }): Promise<ChatDataStorage> {\n const storage = await createStorage();\n if (!storage.updateChatData) {\n if (options.chatData === \"required\") throw new Error(\"У хранилища нет данных чата\");\n context.skip();\n }\n return storage as ChatDataStorage;\n }\n\n const maxBytes = 16 * 1024;\n const formData = { formId: \"f1\", mode: \"test\", attempts: 3, vip: true, utm: { campaign: \"autumn\" } };\n\n it(\"data у обычного чата пишется и читается; subjectData — тот же объект; чат без данных — без обоих полей\", async (context) => {\n const storage = await chatDataStorage(context);\n const created = await storage.createChat({ ...chatInput, id: \"with-data\", data: formData });\n expect(created).toMatchObject({ data: formData, subjectData: formData });\n expect(created).not.toHaveProperty(\"subjectKey\");\n expect(await storage.getChat(\"with-data\")).toMatchObject({ data: formData, subjectData: formData });\n\n await storage.createChat({ ...chatInput, id: \"plain\" });\n const plain = await storage.getChat(\"plain\");\n expect(plain).not.toHaveProperty(\"data\");\n expect(plain).not.toHaveProperty(\"subjectData\");\n });\n\n it(\"старый код: subjectData на входе читается и как data\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"old-style\", subjectKey: \"lesson:7\", subjectData: formData });\n expect(await storage.getChat(\"old-style\")).toMatchObject({ data: formData, subjectData: formData });\n });\n\n it(\"data — копия: правка отданного и прочитанного объекта хранилище не меняет\", async (context) => {\n const storage = await chatDataStorage(context);\n const data = structuredClone(formData);\n await storage.createChat({ ...chatInput, id: \"copy\", data });\n data.utm.campaign = \"правка\";\n const read = await storage.getChat(\"copy\");\n (read?.data as typeof formData).utm.campaign = \"ещё правка\";\n expect((await storage.getChat(\"copy\"))?.data).toEqual(formData);\n });\n\n it(\"updateChatData сливает верхние ключи: новые добавляются, старые заменяются целиком, прочие остаются\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"merge\", data: formData });\n const updated = await storage.updateChatData(\"merge\", { mode: \"live\", utm: { source: \"tg\" }, extra: [1, 2] }, { maxBytes });\n const expected = { formId: \"f1\", mode: \"live\", attempts: 3, vip: true, utm: { source: \"tg\" }, extra: [1, 2] };\n expect(updated).toMatchObject({ id: \"merge\", data: expected, subjectData: expected });\n expect((await storage.getChat(\"merge\"))?.data).toEqual(expected);\n });\n\n it(\"updateChatData у чата без данных создаёт их\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"empty\" });\n await storage.updateChatData(\"empty\", { source: \"telegram\" }, { maxBytes });\n expect((await storage.getChat(\"empty\"))?.data).toEqual({ source: \"telegram\" });\n });\n\n it(\"ключ со значением undefined удаляется; null остаётся значением; не осталось ключей — данных нет\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"drop\", data: { a: 1, b: 2 } });\n await storage.updateChatData(\"drop\", { a: undefined, c: null }, { maxBytes });\n expect((await storage.getChat(\"drop\"))?.data).toEqual({ b: 2, c: null });\n await storage.updateChatData(\"drop\", { b: undefined, c: undefined }, { maxBytes });\n const emptied = await storage.getChat(\"drop\");\n expect(emptied).not.toHaveProperty(\"data\");\n expect(emptied).not.toHaveProperty(\"subjectData\");\n });\n\n it(\"updateChatData: нет такого чата — null; дата обновления чата не меняется\", async (context) => {\n const storage = await chatDataStorage(context);\n expect(await storage.updateChatData(\"missing\", { a: 1 }, { maxBytes })).toBeNull();\n const created = await storage.createChat({ ...chatInput, id: \"stay\", createdAt: \"2024-01-01T00:00:00.000Z\" });\n await storage.updateChatData(\"stay\", { a: 1 }, { maxBytes });\n expect((await storage.getChat(\"stay\"))?.updatedAt).toBe(created.updatedAt);\n });\n\n it(\"итог больше предела — ChatDataTooLargeError, данные не изменены\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"big\", data: { keep: \"x\".repeat(60) } });\n await expect(storage.updateChatData(\"big\", { more: \"y\".repeat(60) }, { maxBytes: 100 })).rejects.toBeInstanceOf(ChatDataTooLargeError);\n expect((await storage.getChat(\"big\"))?.data).toEqual({ keep: \"x\".repeat(60) });\n });\n\n it(\"ключ __proto__ в правке или в фильтре — TypeError, данные не изменены: молча он не теряется\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"proto\", data: { keep: 1 } });\n const withProto = JSON.parse('{\"__proto__\":{\"admin\":true},\"other\":2}') as Record<string, unknown>;\n await expect(storage.updateChatData(\"proto\", withProto, { maxBytes })).rejects.toBeInstanceOf(TypeError);\n expect((await storage.getChat(\"proto\"))?.data).toEqual({ keep: 1 });\n await expect(storage.listChats(chatInput.ownerId, { data: JSON.parse('{\"__proto__\":1}') as never })).rejects.toBeInstanceOf(TypeError);\n });\n\n it(\"символ NUL (\\\\u0000) в ключе или значении правки и фильтра — TypeError, данные не изменены, список цел\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"nul\", data: { keep: 1 } });\n await expect(storage.updateChatData(\"nul\", { note: \"a\\u0000b\" }, { maxBytes })).rejects.toBeInstanceOf(TypeError);\n await expect(storage.updateChatData(\"nul\", { nested: { [\"k\\u0000\"]: 1 } }, { maxBytes })).rejects.toBeInstanceOf(TypeError);\n await expect(storage.updateChatData(\"nul\", { list: [\"ok\", \"\\u0000\"] }, { maxBytes })).rejects.toBeInstanceOf(TypeError);\n expect((await storage.getChat(\"nul\"))?.data).toEqual({ keep: 1 });\n await expect(storage.listChats(chatInput.ownerId, { data: { keep: \"\\u0000\" } })).rejects.toBeInstanceOf(TypeError);\n await expect(storage.listChats(chatInput.ownerId, { data: { [\"k\\u0000\"]: 1 } })).rejects.toBeInstanceOf(TypeError);\n expect((await storage.listChats(chatInput.ownerId, { data: { keep: 1 } })).map((chat) => chat.id)).toEqual([\"nul\"]);\n });\n\n it(\"одновременные правки разных ключей не затирают друг друга\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"race\", data: { start: true } });\n await Promise.all(Array.from({ length: 10 }, (_, index) => storage.updateChatData(\"race\", { [`key${index}`]: index }, { maxBytes })));\n const data = (await storage.getChat(\"race\"))?.data as Record<string, unknown>;\n expect(Object.keys(data).sort()).toEqual([\"start\", ...Array.from({ length: 10 }, (_, index) => `key${index}`)].sort());\n });\n\n describe(\"фильтр data в listChats\", () => {\n async function filled(context: { skip: () => never }) {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"test-1\", createdAt: \"2024-01-01T00:00:00.000Z\", data: { formId: \"f1\", mode: \"test\", n: 1, flag: true, none: null } });\n await storage.createChat({ ...chatInput, id: \"test-2\", createdAt: \"2024-01-02T00:00:00.000Z\", data: { formId: \"f1\", mode: \"test\", n: 2, flag: false } });\n await storage.createChat({ ...chatInput, id: \"live-1\", createdAt: \"2024-01-03T00:00:00.000Z\", data: { formId: \"f1\", mode: \"live\" } });\n await storage.createChat({ ...chatInput, id: \"other-form\", createdAt: \"2024-01-04T00:00:00.000Z\", data: { formId: \"f2\", mode: \"test\" } });\n await storage.createChat({ ...chatInput, id: \"no-data\", createdAt: \"2024-01-05T00:00:00.000Z\" });\n await storage.createChat({ ...chatInput, id: \"boris-test\", ownerId: \"boris\", createdAt: \"2024-01-06T00:00:00.000Z\", data: { formId: \"f1\", mode: \"test\" } });\n const ids = async (data: ChatDataFilter, extra: { subjects?: \"include\" | \"only\" | \"exclude\" } = {}) =>\n (await storage.listChats(chatInput.ownerId, { data, ...extra })).map((chat) => chat.id);\n return { storage, ids };\n }\n\n it(\"равенство одного ключа; чат без данных и чужой владелец не попадают; порядок обычный\", async (context) => {\n const { ids } = await filled(context);\n expect(await ids({ formId: \"f1\" })).toEqual([\"live-1\", \"test-2\", \"test-1\"]);\n expect(await ids({ mode: \"test\" })).toEqual([\"other-form\", \"test-2\", \"test-1\"]);\n });\n\n it(\"несколько ключей — все должны совпасть\", async (context) => {\n const { ids } = await filled(context);\n expect(await ids({ formId: \"f1\", mode: \"test\" })).toEqual([\"test-2\", \"test-1\"]);\n expect(await ids({ formId: \"f2\", mode: \"live\" })).toEqual([]);\n });\n\n it(\"тип значения важен: число не равно строке, true не равно 1, null не равен отсутствию ключа\", async (context) => {\n const { ids } = await filled(context);\n expect(await ids({ n: 1 })).toEqual([\"test-1\"]);\n expect(await ids({ n: \"1\" })).toEqual([]);\n expect(await ids({ flag: true })).toEqual([\"test-1\"]);\n expect(await ids({ flag: false })).toEqual([\"test-2\"]);\n expect(await ids({ flag: 1 })).toEqual([]);\n expect(await ids({ none: null })).toEqual([\"test-1\"]);\n });\n\n it(\"пустой фильтр — как без фильтра по данным\", async (context) => {\n const { ids } = await filled(context);\n expect(await ids({})).toEqual([\"no-data\", \"other-form\", \"live-1\", \"test-2\", \"test-1\"]);\n });\n\n it(\"работает вместе с subjects: чаты с ключом объекта по умолчанию скрыты\", async (context) => {\n const { storage, ids } = await filled(context);\n await storage.createChat({ ...chatInput, id: \"subject-test\", subjectKey: \"form:1\", data: { formId: \"f1\", mode: \"test\" } });\n expect(await ids({ formId: \"f1\", mode: \"test\" })).toEqual([\"test-2\", \"test-1\"]);\n expect(await ids({ formId: \"f1\", mode: \"test\" }, { subjects: \"include\" })).toContain(\"subject-test\");\n expect(await ids({ formId: \"f1\", mode: \"test\" }, { subjects: \"only\" })).toEqual([\"subject-test\"]);\n });\n\n it(\"значение-объект или массив в фильтре — TypeError: равенство только для строки, числа, булева и null\", async (context) => {\n const { storage } = await filled(context);\n await expect(storage.listChats(chatInput.ownerId, { data: { utm: { campaign: \"a\" } } as never })).rejects.toBeInstanceOf(TypeError);\n await expect(storage.listChats(chatInput.ownerId, { data: { tags: [\"a\"] } as never })).rejects.toBeInstanceOf(TypeError);\n });\n\n it(\"ключ с точкой, кавычкой и пробелом ищется как есть\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"odd-keys\", data: { \"a.b\": 1, 'q\"uote': 2, \"with space\": 3 } });\n await storage.createChat({ ...chatInput, id: \"nested\", data: { a: { b: 1 } } });\n for (const filter of [{ \"a.b\": 1 }, { 'q\"uote': 2 }, { \"with space\": 3 }] as ChatDataFilter[]) {\n expect((await storage.listChats(chatInput.ownerId, { data: filter })).map((chat) => chat.id)).toEqual([\"odd-keys\"]);\n }\n });\n\n it(\"после updateChatData чат находится по новому значению, а по старому — нет\", async (context) => {\n const { storage, ids } = await filled(context);\n await storage.updateChatData(\"live-1\", { mode: \"test\" }, { maxBytes });\n expect(await ids({ formId: \"f1\", mode: \"test\" })).toEqual([\"live-1\", \"test-2\", \"test-1\"]);\n expect(await ids({ mode: \"live\" })).toEqual([]);\n });\n });\n\n it(\"importChat переносит данные чата\", async (context) => {\n const storage = await chatDataStorage(context);\n if (!storage.importChat) context.skip();\n const at = \"2023-01-01T09:00:00.000Z\";\n await storage.importChat!(\n { ...chatInput, id: \"imported-data\", createdAt: at, updatedAt: at, data: formData },\n [newStoredMessage({ id: \"i1\", chatId: \"imported-data\", role: \"user\", parts: [{ type: \"text\", text: \"Привет\" }], createdAt: at })],\n );\n expect(await storage.getChat(\"imported-data\")).toMatchObject({ data: formData, subjectData: formData });\n });\n });\n\n describe(\"перенос чата целиком (importChat, необязательный)\", () => {\n type ImportStorage = ChatStorage & Required<Pick<ChatStorage, \"importChat\">>;\n\n async function importStorage(context: { skip: () => never }): Promise<ImportStorage> {\n const storage = await createStorage();\n if (!storage.importChat) {\n if (options.importChat === \"required\") throw new Error(\"У хранилища нет importChat\");\n context.skip();\n }\n return storage as ImportStorage;\n }\n\n const imported = {\n id: \"imported\",\n ownerId: \"anna\",\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n reasoning: \"high\",\n title: \"Старый разговор\",\n createdAt: \"2023-01-01T09:00:00.000Z\",\n updatedAt: \"2023-01-02T09:00:00.000Z\",\n };\n\n function importedMessages(chatId = \"imported\", prefix = \"\"): StoredMessage[] {\n return [\n newStoredMessage({ id: `${prefix}greet`, chatId, role: \"assistant\", parts: [{ type: \"text\", text: \"Здравствуйте!\" }], createdAt: \"2023-01-01T09:00:00.000Z\" }),\n newStoredMessage({ id: `${prefix}q1`, chatId, parentId: `${prefix}greet`, role: \"user\", parts: [{ type: \"text\", text: \"Вопрос\" }], createdAt: \"2023-01-01T09:05:00.000Z\" }),\n newStoredMessage({\n id: `${prefix}a1`,\n chatId,\n parentId: `${prefix}q1`,\n role: \"assistant\",\n parts: [{ type: \"text\", text: \"Ответ\" }],\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n createdAt: \"2023-01-01T09:06:00.000Z\",\n }),\n ];\n }\n\n it(\"чат и сообщения ложатся как есть: даты чата не пересчитываются по сообщениям, порядок и содержимое прежние\", async (context) => {\n const storage = await importStorage(context);\n const messages = importedMessages();\n await storage.importChat(imported, messages);\n expect(await storage.getChat(\"imported\")).toEqual(imported);\n expect(await storage.listMessages(\"imported\")).toEqual(messages);\n expect(await storage.listChats(\"anna\")).toEqual([imported]);\n });\n\n it(\"ключ и данные объекта переносятся: чат находится по ключу\", async (context) => {\n const storage = await importStorage(context);\n await storage.importChat({ ...imported, subjectKey: \"lesson:7\", subjectData: { lesson: 7 } }, importedMessages());\n expect(await storage.getChat(\"imported\")).toMatchObject({ subjectKey: \"lesson:7\", subjectData: { lesson: 7 } });\n expect((await storage.findChatBySubject?.(\"anna\", \"lesson:7\"))?.id).toBe(\"imported\");\n });\n\n it(\"чат без сообщений переносится\", async (context) => {\n const storage = await importStorage(context);\n await storage.importChat(imported, []);\n expect(await storage.getChat(\"imported\")).toEqual(imported);\n expect(await storage.listMessages(\"imported\")).toEqual([]);\n });\n\n it(\"повтор id чата — ChatAlreadyExistsError, ничего не записано, прежний чат цел\", async (context) => {\n const storage = await importStorage(context);\n await storage.createChat({ ...chatInput, id: \"imported\" });\n await expect(storage.importChat(imported, importedMessages())).rejects.toBeInstanceOf(ChatAlreadyExistsError);\n expect(await storage.getChat(\"imported\")).toMatchObject({ ...chatInput, id: \"imported\" });\n expect(await storage.listMessages(\"imported\")).toEqual([]);\n });\n\n it(\"повтор ключа объекта — DuplicateChatSubjectError, ничего не записано\", async (context) => {\n const storage = await importStorage(context);\n await storage.createChat({ ...chatInput, id: \"first\", subjectKey: \"lesson:7\" });\n await expect(storage.importChat({ ...imported, subjectKey: \"lesson:7\" }, importedMessages())).rejects.toBeInstanceOf(DuplicateChatSubjectError);\n expect(await storage.getChat(\"imported\")).toBeNull();\n expect(await storage.getMessage(\"greet\")).toBeNull();\n });\n\n it(\"сбой на сообщении — ничего не записано: ни чата, ни сообщений (одна транзакция)\", async (context) => {\n const storage = await importStorage(context);\n await storage.importChat({ ...imported, id: \"other\" }, importedMessages(\"other\", \"x-\"));\n // Последнее сообщение повторяет id уже записанного — вставка падает на нём.\n const messages = [...importedMessages(), { ...importedMessages()[2]!, id: \"x-a1\", parentId: \"a1\", createdAt: \"2023-01-01T09:07:00.000Z\" }];\n await expect(storage.importChat(imported, messages)).rejects.toBeInstanceOf(DuplicateMessageError);\n expect(await storage.getChat(\"imported\")).toBeNull();\n expect(await storage.getMessage(\"greet\")).toBeNull();\n expect(await storage.listMessages(\"imported\")).toEqual([]);\n expect((await storage.getMessage(\"x-a1\"))?.chatId).toBe(\"other\");\n });\n\n it(\"перенесённый чат дальше живёт как обычный: новое сообщение поднимает updatedAt\", async (context) => {\n const storage = await importStorage(context);\n await storage.importChat(imported, importedMessages());\n await storage.insertMessage({ ...userMessage(\"q2\", \"2099-01-01T00:00:00.000Z\", \"a1\"), chatId: \"imported\" });\n expect((await storage.getChat(\"imported\"))?.updatedAt).toBe(\"2099-01-01T00:00:00.000Z\");\n expect((await storage.listMessages(\"imported\")).map((message) => message.id)).toEqual([\"greet\", \"q1\", \"a1\", \"q2\"]);\n });\n });\n\n describe(\"состояние хука итога у сообщения (необязательные методы)\", () => {\n type AfterTurnStorage = ChatStorage & Required<Pick<ChatStorage, \"setAfterTurnState\" | \"listPendingAfterTurn\">>;\n\n async function afterTurnStorage(context: { skip: () => never }): Promise<AfterTurnStorage> {\n const storage = await createStorage();\n if (!storage.setAfterTurnState || !storage.listPendingAfterTurn) {\n if (options.afterTurnState === \"required\") throw new Error(\"У хранилища нет состояния хука итога\");\n context.skip();\n }\n await storage.createChat(chatInput);\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n return storage as AfterTurnStorage;\n }\n\n it(\"у сообщения без состояния его нет; ждущих — пусто\", async (context) => {\n const storage = await afterTurnStorage(context);\n expect((await storage.getMessage(\"a1\"))?.afterTurn ?? null).toBeNull();\n expect(await storage.listPendingAfterTurn()).toEqual([]);\n });\n\n it(\"pendingForMs: ждущий свежее порога не отдаётся; отметка — переход в pending по часам хранилища, а не дата создания\", async (context) => {\n const storage = await afterTurnStorage(context);\n const old = \"2020-01-01T00:00:00.000Z\";\n await storage.insertMessage(userMessage(\"u0\", old));\n await storage.insertMessage(streamingAnswer(\"finished-now\", \"u0\", old));\n await storage.finishMessage(\"finished-now\", { status: \"complete\", afterTurn: \"pending\" });\n await storage.insertMessage({ ...streamingAnswer(\"left-long-ago\", \"u0\", old), status: \"complete\", afterTurn: \"pending\" });\n await storage.insertMessage({ ...streamingAnswer(\"reopened-now\", \"u0\", old), status: \"complete\" });\n await storage.setAfterTurnState(\"reopened-now\", \"pending\");\n\n expect((await storage.listPendingAfterTurn()).sort()).toEqual([\"finished-now\", \"left-long-ago\", \"reopened-now\"]);\n expect(await storage.listPendingAfterTurn({ pendingForMs: 60_000 })).toEqual([\"left-long-ago\"]);\n });\n\n it(\"finishMessage с afterTurn: pending ставит состояние той же записью; ответ попадает в ждущие\", async (context) => {\n const storage = await afterTurnStorage(context);\n await storage.finishMessage(\"a1\", { status: \"complete\", parts: [{ type: \"text\", text: \"готово\" }], afterTurn: \"pending\" });\n expect(await storage.getMessage(\"a1\")).toMatchObject({ status: \"complete\", afterTurn: \"pending\" });\n expect((await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\")?.afterTurn).toBe(\"pending\");\n expect(await storage.listPendingAfterTurn()).toEqual([\"a1\"]);\n });\n\n it(\"finishMessage без afterTurn состояние не ставит\", async (context) => {\n const storage = await afterTurnStorage(context);\n await storage.finishMessage(\"a1\", { status: \"complete\" });\n expect((await storage.getMessage(\"a1\"))?.afterTurn ?? null).toBeNull();\n expect(await storage.listPendingAfterTurn()).toEqual([]);\n });\n\n it(\"setAfterTurnState меняет состояние законченного ответа: done и failed уходят из ждущих\", async (context) => {\n const storage = await afterTurnStorage(context);\n await storage.insertMessage({ ...streamingAnswer(\"a2\", \"u1\", \"2099-01-01T00:00:02.000Z\"), status: \"complete\" });\n await storage.finishMessage(\"a1\", { status: \"complete\", afterTurn: \"pending\" });\n await storage.setAfterTurnState(\"a2\", \"pending\");\n expect((await storage.listPendingAfterTurn()).sort()).toEqual([\"a1\", \"a2\"]);\n\n await storage.setAfterTurnState(\"a1\", \"done\");\n await storage.setAfterTurnState(\"a2\", \"failed\");\n expect((await storage.getMessage(\"a1\"))?.afterTurn).toBe(\"done\");\n expect((await storage.getMessage(\"a2\"))?.afterTurn).toBe(\"failed\");\n expect(await storage.listPendingAfterTurn()).toEqual([]);\n });\n\n it(\"неизвестное сообщение — тихо ничего\", async (context) => {\n const storage = await afterTurnStorage(context);\n await expect(storage.setAfterTurnState(\"missing\", \"done\")).resolves.toBe(false);\n expect(await storage.getMessage(\"missing\")).toBeNull();\n });\n\n it(\"done и failed пишутся только из pending: второй закрывающий не проходит\", async (context) => {\n const storage = await afterTurnStorage(context);\n await storage.finishMessage(\"a1\", { status: \"complete\", afterTurn: \"pending\" });\n expect(await storage.setAfterTurnState(\"a1\", \"done\")).toBe(true);\n expect(await storage.setAfterTurnState(\"a1\", \"failed\")).toBe(false);\n expect((await storage.getMessage(\"a1\"))?.afterTurn).toBe(\"done\");\n await storage.insertMessage({ ...streamingAnswer(\"a2\", \"u1\", \"2099-01-01T00:00:02.000Z\"), status: \"complete\" });\n expect(await storage.setAfterTurnState(\"a2\", \"done\")).toBe(false);\n expect((await storage.getMessage(\"a2\"))?.afterTurn ?? null).toBeNull();\n });\n\n it(\"appendParts дописываются в конец частей той же записью и только из pending\", async (context) => {\n const storage = await afterTurnStorage(context);\n const event = { type: \"data-app-event\", data: { type: \"lesson_passed\", data: { score: 5 } } } as StoredMessage[\"parts\"][number];\n await storage.finishMessage(\"a1\", { status: \"complete\", parts: [{ type: \"text\", text: \"готово\" }], afterTurn: \"pending\" });\n expect(await storage.setAfterTurnState(\"a1\", \"done\", { appendParts: [event] })).toBe(true);\n expect((await storage.getMessage(\"a1\"))?.parts).toEqual([{ type: \"text\", text: \"готово\" }, event]);\n expect(await storage.setAfterTurnState(\"a1\", \"done\", { appendParts: [event] })).toBe(false);\n expect((await storage.getMessage(\"a1\"))?.parts).toHaveLength(2);\n });\n\n it(\"удаление чата убирает его ждущие ответы\", async (context) => {\n const storage = await afterTurnStorage(context);\n await storage.finishMessage(\"a1\", { status: \"complete\", afterTurn: \"pending\" });\n await storage.deleteChat(chatInput.id);\n expect(await storage.listPendingAfterTurn()).toEqual([]);\n });\n });\n\n describe(\"аренда хода чата (claimChatTurn, releaseChatTurn, clearChatTurnLeases; необязательные)\", () => {\n type LeaseStorage = ChatStorage & Required<Pick<ChatStorage, \"claimChatTurn\" | \"releaseChatTurn\">>;\n\n async function leaseStorage(context: { skip: () => never }): Promise<LeaseStorage> {\n const storage = await createStorage();\n if (!storage.claimChatTurn || !storage.releaseChatTurn) {\n if (options.chatTurnLease === \"required\") throw new Error(\"У хранилища нет аренды хода чата\");\n context.skip();\n }\n await storage.createChat(chatInput);\n return storage as LeaseStorage;\n }\n\n const minute = 60_000;\n\n it(\"свободный чат берётся; чужая аренда — false; своя продлевается; снятая своя — свободна, чужое снятие не действует\", async (context) => {\n const storage = await leaseStorage(context);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-a\", minute)).toBe(true);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-b\", minute)).toBe(false);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-a\", minute)).toBe(true);\n await storage.releaseChatTurn(chatInput.id, \"copy-b\");\n expect(await storage.claimChatTurn(chatInput.id, \"copy-b\", minute)).toBe(false);\n await storage.releaseChatTurn(chatInput.id, \"copy-a\");\n expect(await storage.claimChatTurn(chatInput.id, \"copy-b\", minute)).toBe(true);\n });\n\n it(\"просроченная аренда (копия упала) берётся другой копией — по часам хранилища\", async (context) => {\n const storage = await leaseStorage(context);\n // Аренда на секунду: под нагрузкой машины вторая попытка не должна успеть «после срока».\n expect(await storage.claimChatTurn(chatInput.id, \"copy-a\", 1_000)).toBe(true);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-b\", minute)).toBe(false);\n await new Promise((resolve) => setTimeout(resolve, 1_100));\n expect(await storage.claimChatTurn(chatInput.id, \"copy-b\", minute)).toBe(true);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-a\", minute)).toBe(false);\n });\n\n it(\"гонка: десять копий берут один чат разом — берёт ровно одна; аренды разных чатов независимы\", async (context) => {\n const storage = await leaseStorage(context);\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n const copies = Array.from({ length: 10 }, (_, index) => `copy-${index}`);\n const won = await Promise.all(copies.map((holder) => storage.claimChatTurn(chatInput.id, holder, minute)));\n expect(won.filter(Boolean)).toHaveLength(1);\n expect(await storage.claimChatTurn(\"chat-2\", \"copy-other\", minute)).toBe(true);\n const winner = copies[won.indexOf(true)]!;\n expect(await storage.claimChatTurn(chatInput.id, winner, minute)).toBe(true);\n });\n\n it(\"удалённый чат — без аренды: новый чат с тем же id свободен\", async (context) => {\n const storage = await leaseStorage(context);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-a\", minute)).toBe(true);\n await storage.deleteChat(chatInput.id);\n await storage.createChat(chatInput);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-b\", minute)).toBe(true);\n });\n\n it(\"clearChatTurnLeases снимает все живые аренды всех чатов (старт единственной копии)\", async (context) => {\n const storage = await leaseStorage(context);\n if (!storage.clearChatTurnLeases) {\n if (options.chatTurnLease === \"required\") throw new Error(\"У хранилища нет clearChatTurnLeases\");\n context.skip();\n }\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n expect(await storage.claimChatTurn(chatInput.id, \"copy-a\", minute)).toBe(true);\n expect(await storage.claimChatTurn(\"chat-2\", \"copy-b\", minute)).toBe(true);\n await storage.clearChatTurnLeases!();\n expect(await storage.claimChatTurn(chatInput.id, \"copy-c\", minute)).toBe(true);\n expect(await storage.claimChatTurn(\"chat-2\", \"copy-c\", minute)).toBe(true);\n });\n });\n\n describe(\"ждущие пачки (savePendingBurst, takeAbandonedBursts, renewPendingBurst, removePendingBurst; необязательные)\", () => {\n type BurstStorage = ChatStorage & Required<Pick<ChatStorage, \"savePendingBurst\" | \"takeAbandonedBursts\" | \"renewPendingBurst\" | \"removePendingBurst\">>;\n\n async function burstStorage(context: { skip: () => never }): Promise<BurstStorage> {\n const storage = await createStorage();\n if (!storage.savePendingBurst || !storage.takeAbandonedBursts || !storage.renewPendingBurst || !storage.removePendingBurst) {\n if (options.pendingBursts === \"required\") throw new Error(\"У хранилища нет ждущих пачек\");\n context.skip();\n }\n await storage.createChat(chatInput);\n return storage as BurstStorage;\n }\n\n const at = (seconds: number) => new Date(Date.UTC(2026, 9, 15, 12, 0, seconds)).toISOString();\n const burst = (fields: Partial<StoredPendingBurst> = {}): StoredPendingBurst => ({\n chatId: chatInput.id,\n ownerId: chatInput.ownerId,\n messageId: \"m1\",\n dueAt: at(3),\n holder: \"copy-a\",\n heldUntil: at(33),\n ...fields,\n });\n const take = (storage: BurstStorage, abandonedBefore: string, holder = \"copy-b\", limit = 10) =>\n storage.takeAbandonedBursts({ abandonedBefore, holder, heldUntil: at(50), limit });\n\n it(\"живое ожидание не берётся; брошенное — берётся один раз и переходит к взявшему\", async (context) => {\n const storage = await burstStorage(context);\n const page: TurnRequestContext = { tabId: \"tab-1\", timeZone: \"Europe/Moscow\" };\n await storage.savePendingBurst(burst({ page }));\n expect(await take(storage, at(32))).toEqual([]);\n expect(await take(storage, at(33))).toEqual([burst({ page, holder: \"copy-b\", heldUntil: at(50) })]);\n // Взятая пачка жива до нового срока: вторая копия её не получит.\n expect(await take(storage, at(40), \"copy-c\")).toEqual([]);\n expect(await take(storage, at(50), \"copy-c\")).toEqual([expect.objectContaining({ holder: \"copy-c\" })]);\n });\n\n it(\"новая запись чата заменяет прежнюю; снятие — только своего сообщения\", async (context) => {\n const storage = await burstStorage(context);\n await storage.savePendingBurst(burst());\n await storage.savePendingBurst(burst({ messageId: \"m2\", dueAt: at(5), heldUntil: at(35) }));\n await storage.removePendingBurst(chatInput.id, \"m1\");\n expect(await take(storage, at(59))).toEqual([expect.objectContaining({ messageId: \"m2\", dueAt: at(5) })]);\n await storage.removePendingBurst(chatInput.id, \"m2\");\n expect(await take(storage, \"2100-01-01T00:00:00.000Z\")).toEqual([]);\n });\n\n it(\"limit и порядок: ранние сроки первыми; удалённый чат — без записи\", async (context) => {\n const storage = await burstStorage(context);\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n await storage.createChat({ ...chatInput, id: \"chat-3\" });\n await storage.savePendingBurst(burst({ chatId: \"chat-2\", dueAt: at(9), heldUntil: at(10) }));\n await storage.savePendingBurst(burst({ dueAt: at(1), heldUntil: at(10) }));\n await storage.savePendingBurst(burst({ chatId: \"chat-3\", dueAt: at(5), heldUntil: at(10) }));\n await storage.deleteChat(\"chat-3\");\n expect((await take(storage, at(20), \"copy-b\", 1)).map((taken) => taken.chatId)).toEqual([chatInput.id]);\n expect((await take(storage, at(20), \"copy-b\", 10)).map((taken) => taken.chatId)).toEqual([\"chat-2\"]);\n });\n\n it(\"продление: только держатель и только той же пачки; продлённая не берётся до нового срока\", async (context) => {\n const storage = await burstStorage(context);\n await storage.savePendingBurst(burst());\n expect(await storage.renewPendingBurst({ chatId: chatInput.id, messageId: \"m1\", holder: \"copy-b\", heldUntil: at(59) })).toBe(false);\n expect(await storage.renewPendingBurst({ chatId: chatInput.id, messageId: \"m0\", holder: \"copy-a\", heldUntil: at(59) })).toBe(false);\n expect(await storage.renewPendingBurst({ chatId: \"chat-none\", messageId: \"m1\", holder: \"copy-a\", heldUntil: at(59) })).toBe(false);\n expect(await storage.renewPendingBurst({ chatId: chatInput.id, messageId: \"m1\", holder: \"copy-a\", heldUntil: at(45) })).toBe(true);\n expect(await take(storage, at(44))).toEqual([]);\n expect(await take(storage, at(45))).toEqual([burst({ holder: \"copy-b\", heldUntil: at(50) })]);\n // Пачку взяла другая копия: прежний держатель её не продлит.\n expect(await storage.renewPendingBurst({ chatId: chatInput.id, messageId: \"m1\", holder: \"copy-a\", heldUntil: at(59) })).toBe(false);\n });\n\n it(\"exceptHolder: свои записи не берутся, сколько бы раз ни звали; чужие — берутся\", async (context) => {\n const storage = await burstStorage(context);\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n await storage.savePendingBurst(burst());\n await storage.savePendingBurst(burst({ chatId: \"chat-2\", holder: \"copy-b\" }));\n const far = \"2100-01-01T00:00:00.000Z\";\n const takeExcept = () => storage.takeAbandonedBursts({ abandonedBefore: far, holder: \"copy-b\", heldUntil: at(50), limit: 10, exceptHolder: \"copy-b\" });\n expect((await takeExcept()).map((taken) => taken.chatId)).toEqual([chatInput.id]);\n expect(await takeExcept()).toEqual([]);\n });\n\n it(\"гонка: десять копий берут разом — каждую пачку получает ровно одна\", async (context) => {\n const storage = await burstStorage(context);\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n await storage.savePendingBurst(burst());\n await storage.savePendingBurst(burst({ chatId: \"chat-2\" }));\n const copies = Array.from({ length: 10 }, (_, index) => `copy-${index}`);\n const taken = (await Promise.all(copies.map((holder) => take(storage, at(40), holder)))).flat();\n expect(taken.map((one) => one.chatId).sort()).toEqual([chatInput.id, \"chat-2\"].sort());\n });\n });\n\n describe(\"закрытие чата (необязательный метод)\", () => {\n type ClosureStorage = ChatStorage & Required<Pick<ChatStorage, \"setChatClosed\">>;\n\n async function closureStorage(context: { skip: () => never }): Promise<ClosureStorage> {\n const storage = await createStorage();\n if (!storage.setChatClosed) {\n if (options.chatClosure === \"required\") throw new Error(\"У хранилища нет закрытия чата\");\n context.skip();\n }\n await storage.createChat(chatInput);\n return storage as ClosureStorage;\n }\n\n const closure = { code: \"form_completed\", message: \"Заявка отправлена. «Диалог» только для чтения 🙂\" };\n\n it(\"у нового чата закрытия нет; setChatClosed пишет его, null — стирает; updatedAt не меняется\", async (context) => {\n const storage = await closureStorage(context);\n const before = await storage.getChat(chatInput.id);\n expect(before).not.toHaveProperty(\"closed\");\n await storage.setChatClosed(chatInput.id, closure);\n expect(await storage.getChat(chatInput.id)).toMatchObject({ closed: closure, updatedAt: before!.updatedAt });\n expect((await storage.listChats(\"anna\"))[0]).toMatchObject({ closed: closure });\n await storage.setChatClosed(chatInput.id, null);\n expect(await storage.getChat(chatInput.id)).not.toHaveProperty(\"closed\");\n });\n\n it(\"повторное закрытие заменяет код и текст; неизвестный чат — тихо\", async (context) => {\n const storage = await closureStorage(context);\n await storage.setChatClosed(chatInput.id, closure);\n await storage.setChatClosed(chatInput.id, { code: \"form_unpublished\", message: \"Форма снята с публикации.\" });\n expect((await storage.getChat(chatInput.id))?.closed).toEqual({ code: \"form_unpublished\", message: \"Форма снята с публикации.\" });\n await expect(storage.setChatClosed(\"missing\", closure)).resolves.toBeUndefined();\n expect(await storage.getChat(\"missing\")).toBeNull();\n });\n });\n\n describe(\"голосовой режим (необязательные методы)\", () => {\n type VoiceStorage = ChatStorage & Required<Pick<ChatStorage, \"setVoiceCut\" | \"getVoiceChoice\" | \"setVoiceChoice\">>;\n\n /** Хранилище без этих методов договор не нарушает: пакет диалога тогда держит выбор и отметку в памяти. */\n async function voiceStorage(context: { skip: () => never }, withChat = true): Promise<VoiceStorage> {\n const storage = await createStorage();\n if (!storage.setVoiceCut || !storage.getVoiceChoice || !storage.setVoiceChoice) {\n if (options.voiceDialog === \"required\") throw new Error(\"У хранилища нет методов голосового режима\");\n context.skip();\n }\n if (withChat) await storage.createChat(chatInput);\n return storage as VoiceStorage;\n }\n\n const cut = { partIndex: 0, charOffset: 27, spokenTail: \"…сначала разберём, как это устроено\" };\n\n async function chatWithAnswer(storage: VoiceStorage): Promise<void> {\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage({\n ...streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"),\n status: \"complete\",\n parts: [{ type: \"text\", text: \"Сначала разберём, как это устроено, потом посмотрим на примеры.\" }],\n });\n }\n\n describe(\"отметка обрыва\", () => {\n it(\"у сообщения без отметки чтение даёт voiceCut: null\", async (context) => {\n const storage = await voiceStorage(context);\n await chatWithAnswer(storage);\n expect((await storage.getMessage(\"a1\"))?.voiceCut).toBeNull();\n expect((await storage.listMessages(chatInput.id)).map((message) => message.voiceCut)).toEqual([null, null]);\n });\n\n it(\"setVoiceCut пишет отметку владельцу: её видят getMessage и listMessages; повторная запись заменяет\", async (context) => {\n const storage = await voiceStorage(context);\n await chatWithAnswer(storage);\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: chatInput.id, messageId: \"a1\", voiceCut: cut });\n expect((await storage.getMessage(\"a1\"))?.voiceCut).toEqual(cut);\n expect((await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\")?.voiceCut).toEqual(cut);\n\n const later = { partIndex: 0, charOffset: 50, spokenTail: \"…потом посмотрим\" };\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: chatInput.id, messageId: \"a1\", voiceCut: later });\n expect((await storage.getMessage(\"a1\"))?.voiceCut).toEqual(later);\n });\n\n it(\"чужой владелец: тихо ничего, отметка не появляется\", async (context) => {\n const storage = await voiceStorage(context);\n await chatWithAnswer(storage);\n await expect(\n storage.setVoiceCut({ ownerId: \"boris\", chatId: chatInput.id, messageId: \"a1\", voiceCut: cut }),\n ).resolves.toBeUndefined();\n expect((await storage.getMessage(\"a1\"))?.voiceCut).toBeNull();\n });\n\n it(\"сообщение из другого чата или неизвестное: тихо ничего\", async (context) => {\n const storage = await voiceStorage(context);\n await chatWithAnswer(storage);\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: \"chat-2\", messageId: \"a1\", voiceCut: cut });\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: chatInput.id, messageId: \"missing\", voiceCut: cut });\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: \"missing\", messageId: \"a1\", voiceCut: cut });\n expect((await storage.getMessage(\"a1\"))?.voiceCut).toBeNull();\n });\n\n it(\"отметка, поставленная у идущего ответа, переживает его завершение и дописывание\", async (context) => {\n const storage = await voiceStorage(context);\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: chatInput.id, messageId: \"a1\", voiceCut: cut });\n await storage.updateStreamingMessage(\"a1\", { parts: [{ type: \"text\", text: \"часть\" }] });\n await storage.finishMessage(\"a1\", { status: \"stopped\", parts: [{ type: \"text\", text: \"часть ответа\" }] });\n expect(await storage.getMessage(\"a1\")).toMatchObject({ status: \"stopped\", voiceCut: cut });\n });\n\n it(\"отметка одного сообщения не задевает другие\", async (context) => {\n const storage = await voiceStorage(context);\n await chatWithAnswer(storage);\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: chatInput.id, messageId: \"a1\", voiceCut: cut });\n expect((await storage.getMessage(\"u1\"))?.voiceCut).toBeNull();\n });\n });\n\n describe(\"выбор голоса\", () => {\n it(\"у человека без выбора — null\", async (context) => {\n const storage = await voiceStorage(context, false);\n expect(await storage.getVoiceChoice(\"anna\")).toBeNull();\n });\n\n it(\"запись, чтение и замена\", async (context) => {\n const storage = await voiceStorage(context, false);\n await storage.setVoiceChoice(\"anna\", \"voice-a\");\n expect(await storage.getVoiceChoice(\"anna\")).toBe(\"voice-a\");\n await storage.setVoiceChoice(\"anna\", \"voice-b\");\n expect(await storage.getVoiceChoice(\"anna\")).toBe(\"voice-b\");\n });\n\n it(\"у каждого человека свой выбор\", async (context) => {\n const storage = await voiceStorage(context, false);\n await storage.setVoiceChoice(\"anna\", \"voice-a\");\n await storage.setVoiceChoice(\"boris\", \"voice-b\");\n expect(await storage.getVoiceChoice(\"anna\")).toBe(\"voice-a\");\n expect(await storage.getVoiceChoice(\"boris\")).toBe(\"voice-b\");\n expect(await storage.getVoiceChoice(\"clara\")).toBeNull();\n });\n\n it(\"не зависит от выбора модели (015) и от удаления чатов\", async (context) => {\n const storage = await voiceStorage(context);\n await storage.setVoiceChoice(\"anna\", \"voice-a\");\n await storage.saveUserModelChoice?.(\"anna\", { modelId: \"m\", providerId: \"p\" });\n expect(await storage.getVoiceChoice(\"anna\")).toBe(\"voice-a\");\n if (storage.getUserModelChoice) expect(await storage.getUserModelChoice(\"anna\")).toEqual({ modelId: \"m\", providerId: \"p\" });\n await storage.setVoiceChoice(\"anna\", \"voice-b\");\n if (storage.getUserModelChoice) expect(await storage.getUserModelChoice(\"anna\")).toEqual({ modelId: \"m\", providerId: \"p\" });\n await storage.deleteChat(chatInput.id);\n expect(await storage.getVoiceChoice(\"anna\")).toBe(\"voice-b\");\n });\n\n it(\"двадцать записей одновременно не ломают хранилище: остаётся одно из записанных значений\", async (context) => {\n const storage = await voiceStorage(context, false);\n await Promise.all(Array.from({ length: 20 }, (_, index) => storage.setVoiceChoice(\"anna\", `voice-${index}`)));\n expect(await storage.getVoiceChoice(\"anna\")).toMatch(/^voice-\\d+$/);\n });\n });\n });\n\n describe(\"состояние лимитов расходов (необязательные методы)\", () => {\n async function storageWithLimitState(context: { skip: () => never }) {\n const storage = await createStorage();\n if (!storage.getSpendingLimitState || !storage.saveSpendingLimitState) {\n if (options.spendingLimitState === \"required\") throw new Error(\"У хранилища нет методов состояния лимитов расходов\");\n context.skip();\n }\n return storage as ChatStorage & Required<Pick<ChatStorage, \"getSpendingLimitState\" | \"saveSpendingLimitState\">>;\n }\n\n it(\"нет записи — null; первая запись — только при expectedVersion null, версия 1\", async (context) => {\n const storage = await storageWithLimitState(context);\n expect(await storage.getSpendingLimitState(\"user:anna\")).toBeNull();\n expect(await storage.saveSpendingLimitState(\"user:anna\", \"{}\", 1)).toBe(false);\n expect(await storage.getSpendingLimitState(\"user:anna\")).toBeNull();\n expect(await storage.saveSpendingLimitState(\"user:anna\", '{\"a\":1}', null)).toBe(true);\n expect(await storage.getSpendingLimitState(\"user:anna\")).toEqual({ value: '{\"a\":1}', version: 1 });\n });\n\n it(\"запись по версии: верная — заменяет и растит версию, устаревшая или null при существующей — false и ничего\", async (context) => {\n const storage = await storageWithLimitState(context);\n await storage.saveSpendingLimitState(\"k\", \"v1\", null);\n expect(await storage.saveSpendingLimitState(\"k\", \"v2\", 1)).toBe(true);\n expect(await storage.saveSpendingLimitState(\"k\", \"stale\", 1)).toBe(false);\n expect(await storage.saveSpendingLimitState(\"k\", \"again\", null)).toBe(false);\n expect(await storage.getSpendingLimitState(\"k\")).toEqual({ value: \"v2\", version: 2 });\n });\n\n it(\"из двух одновременных записей с одной версией проходит одна\", async (context) => {\n const storage = await storageWithLimitState(context);\n await storage.saveSpendingLimitState(\"k\", \"v1\", null);\n const results = await Promise.all([storage.saveSpendingLimitState(\"k\", \"a\", 1), storage.saveSpendingLimitState(\"k\", \"b\", 1)]);\n expect(results.filter(Boolean)).toHaveLength(1);\n expect((await storage.getSpendingLimitState(\"k\"))!.version).toBe(2);\n });\n\n it(\"ключи независимы; длинная строка с юникодом хранится как есть; чаты не трогает\", async (context) => {\n const storage = await storageWithLimitState(context);\n const long = JSON.stringify({ note: \"лимит ✓\", items: Array.from({ length: 2000 }, (_, index) => index) });\n await storage.saveSpendingLimitState(\"service\", long, null);\n await storage.saveSpendingLimitState(\"user:boris\", \"b\", null);\n expect(await storage.getSpendingLimitState(\"service\")).toEqual({ value: long, version: 1 });\n expect(await storage.getSpendingLimitState(\"user:boris\")).toEqual({ value: \"b\", version: 1 });\n expect(await storage.listChats(\"anna\")).toEqual([]);\n });\n\n it(\"удаление по ключам: стирает только названные, лишние ключи и пустой список — не ошибка\", async (context) => {\n const storage = await storageWithLimitState(context);\n if (!storage.deleteSpendingLimitStates) {\n if (options.spendingLimitState === \"required\") throw new Error(\"У хранилища нет метода deleteSpendingLimitStates\");\n context.skip();\n }\n const keys = [\"window:chat:c1:day\", \"window:chat:c1:week\", \"window:chat:c1:day:x\", \"window:chat:чат:day\", \"window:user:anna:day\"];\n for (const key of keys) await storage.saveSpendingLimitState(key, \"v\", null);\n await storage.deleteSpendingLimitStates!([\"window:chat:c1:day\", \"window:chat:c1:week\", \"window:chat:чат:day\", \"нет-такого\"]);\n await storage.deleteSpendingLimitStates!([]);\n const left = [];\n for (const key of keys) if (await storage.getSpendingLimitState(key)) left.push(key);\n expect(left).toEqual([\"window:chat:c1:day:x\", \"window:user:anna:day\"]);\n expect(await storage.saveSpendingLimitState(\"window:chat:c1:day\", \"new\", null)).toBe(true);\n });\n });\n\n describe(\"запомненный выбор модели (необязательные методы)\", () => {\n /** Хранилище без этих методов договор не нарушает: ядро тогда ведёт себя как раньше. */\n async function storageWithChoiceMemory(context: { skip: () => never }) {\n const storage = await createStorage();\n if (!storage.getUserModelChoice || !storage.saveUserModelChoice) {\n if (options.choiceMemory === \"required\") throw new Error(\"У хранилища нет методов запомненного выбора модели\");\n context.skip();\n }\n return storage as ChatStorage & Required<Pick<ChatStorage, \"getUserModelChoice\" | \"saveUserModelChoice\">>;\n }\n\n it(\"у человека без выбора — null\", async (context) => {\n const storage = await storageWithChoiceMemory(context);\n expect(await storage.getUserModelChoice(\"anna\")).toBeNull();\n });\n\n it(\"хранит модель, провайдера и уровень рассуждений; без уровня — без уровня\", async (context) => {\n const storage = await storageWithChoiceMemory(context);\n await storage.saveUserModelChoice(\"anna\", { modelId: \"m\", providerId: \"p\", reasoning: \"high\" });\n expect(await storage.getUserModelChoice(\"anna\")).toEqual({ modelId: \"m\", providerId: \"p\", reasoning: \"high\" });\n\n await storage.saveUserModelChoice(\"anna\", { modelId: \"m2\", providerId: \"p2\" });\n const replaced = await storage.getUserModelChoice(\"anna\");\n expect(replaced).toEqual({ modelId: \"m2\", providerId: \"p2\" });\n expect(replaced).not.toHaveProperty(\"reasoning\");\n });\n\n it(\"у каждого человека свой выбор\", async (context) => {\n const storage = await storageWithChoiceMemory(context);\n await storage.saveUserModelChoice(\"anna\", { modelId: \"a\", providerId: \"p\" });\n await storage.saveUserModelChoice(\"boris\", { modelId: \"b\", providerId: \"p\", reasoning: \"low\" });\n expect(await storage.getUserModelChoice(\"anna\")).toEqual({ modelId: \"a\", providerId: \"p\" });\n expect(await storage.getUserModelChoice(\"boris\")).toEqual({ modelId: \"b\", providerId: \"p\", reasoning: \"low\" });\n expect(await storage.getUserModelChoice(\"clara\")).toBeNull();\n });\n\n it(\"не трогает чаты и не зависит от их удаления\", async (context) => {\n const storage = await storageWithChoiceMemory(context);\n await storage.createChat(chatInput);\n await storage.saveUserModelChoice(\"anna\", { modelId: \"other\", providerId: \"fireworks\" });\n expect(await storage.getChat(chatInput.id)).toMatchObject({ modelId: chatInput.modelId, providerId: chatInput.providerId });\n await storage.deleteChat(chatInput.id);\n expect(await storage.getUserModelChoice(\"anna\")).toEqual({ modelId: \"other\", providerId: \"fireworks\" });\n });\n\n it(\"двадцать записей одновременно не ломают хранилище: остаётся одно из записанных значений\", async (context) => {\n const storage = await storageWithChoiceMemory(context);\n await Promise.all(Array.from({ length: 20 }, (_, index) => storage.saveUserModelChoice(\"anna\", { modelId: `m${index}`, providerId: \"p\" })));\n const saved = await storage.getUserModelChoice(\"anna\");\n expect(saved?.modelId).toMatch(/^m\\d+$/);\n });\n });\n\n describe(\"долгая память (необязательные методы)\", () => {\n type MemoryStorage = ChatStorage &\n Required<\n Pick<ChatStorage, \"listMemoryNotes\" | \"insertMemoryNotes\" | \"updateMemoryNote\" | \"deleteMemoryNote\" | \"clearMemoryNotes\">\n >;\n\n /** Хранилище без этих методов договор не нарушает: приложение тогда не подключает пакет памяти. */\n async function storageWithMemory(context: { skip: () => never }): Promise<MemoryStorage> {\n const storage = await createStorage();\n const present =\n storage.listMemoryNotes &&\n storage.insertMemoryNotes &&\n storage.updateMemoryNote &&\n storage.deleteMemoryNote &&\n storage.clearMemoryNotes;\n if (!present) {\n if (options.memory === \"required\") throw new Error(\"У хранилища нет методов долгой памяти\");\n context.skip();\n }\n return storage as MemoryStorage;\n }\n\n const note = (content: string, ...categories: string[]): MemoryNoteInput => ({\n categories: categories.length > 0 ? categories : [\"О себе\"],\n content,\n });\n\n /** Порядок списка по договору: `updatedAt`, затем `createdAt`, затем `id` — новее и больше первыми. */\n function expectedOrder(notes: MemoryNote[]): string[] {\n return [...notes]\n .sort(\n (left, right) =>\n right.updatedAt.localeCompare(left.updatedAt) ||\n right.createdAt.localeCompare(left.createdAt) ||\n (right.id > left.id ? 1 : right.id < left.id ? -1 : 0),\n )\n .map((item) => item.id);\n }\n\n /** Ждёт, пока часы уйдут вперёд хотя бы на миллисекунду: пауза до условия, а не по таймеру. */\n async function untilClockMoves(): Promise<void> {\n const start = Date.now();\n while (Date.now() <= start) await new Promise((resolve) => setTimeout(resolve, 1));\n }\n\n it(\"у человека без записей список пуст\", async (context) => {\n const storage = await storageWithMemory(context);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([]);\n });\n\n it(\"вставка выдаёт записи с id, версией 1 и временем; список читает их; владельца в записи нет\", async (context) => {\n const storage = await storageWithMemory(context);\n const created = await storage.insertMemoryNotes(\"anna\", [note(\"Пишет на TypeScript\", \"О себе\", \"Работа\"), note(\"Отвечай на «ты»\", \"Правила\")]);\n expect(created).toHaveLength(2);\n expect(new Set(created.map((item) => item.id)).size).toBe(2);\n for (const item of created) {\n expect(item.id).toEqual(expect.any(String));\n expect(item.version).toBe(1);\n expect(Number.isNaN(Date.parse(item.createdAt))).toBe(false);\n expect(item.updatedAt).toBe(item.createdAt);\n expect(item).not.toHaveProperty(\"ownerId\");\n }\n expect(created.find((item) => item.content === \"Пишет на TypeScript\")?.categories).toEqual([\"О себе\", \"Работа\"]);\n\n const listed = await storage.listMemoryNotes(\"anna\");\n expect(listed).toHaveLength(2);\n expect(listed.map((item) => item.id).sort()).toEqual(created.map((item) => item.id).sort());\n for (const item of listed) expect(item).not.toHaveProperty(\"ownerId\");\n });\n\n it(\"пустой пакет — пустой ответ, ничего не создаётся\", async (context) => {\n const storage = await storageWithMemory(context);\n expect(await storage.insertMemoryNotes(\"anna\", [])).toEqual([]);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([]);\n });\n\n it(\"пакет — всё или ничего: одна негодная запись не оставляет и остальных\", async (context) => {\n const storage = await storageWithMemory(context);\n await storage.insertMemoryNotes(\"anna\", [note(\"Уже была\")]);\n const broken = { categories: [\"О себе\"], content: null } as unknown as MemoryNoteInput;\n await expect(storage.insertMemoryNotes(\"anna\", [note(\"Хорошая первая\"), broken, note(\"Хорошая третья\")])).rejects.toBeInstanceOf(Error);\n const listed = await storage.listMemoryNotes(\"anna\");\n expect(listed.map((item) => item.content)).toEqual([\"Уже была\"]);\n });\n\n it(\"у каждого человека своя память: чужие записи не видны\", async (context) => {\n const storage = await storageWithMemory(context);\n await storage.insertMemoryNotes(\"anna\", [note(\"Записка Анны\")]);\n await storage.insertMemoryNotes(\"boris\", [note(\"Записка Бориса\"), note(\"Ещё одна Бориса\")]);\n expect((await storage.listMemoryNotes(\"anna\")).map((item) => item.content)).toEqual([\"Записка Анны\"]);\n expect(await storage.listMemoryNotes(\"boris\")).toHaveLength(2);\n expect(await storage.listMemoryNotes(\"clara\")).toEqual([]);\n });\n\n it(\"чужая запись — not_found при правке и удалении, сама запись цела\", async (context) => {\n const storage = await storageWithMemory(context);\n const [annas] = await storage.insertMemoryNotes(\"anna\", [note(\"Записка Анны\")]);\n expect(await storage.updateMemoryNote(\"boris\", annas!.id, 1, note(\"Подмена\"))).toBe(\"not_found\");\n expect(await storage.deleteMemoryNote(\"boris\", annas!.id, 1)).toBe(\"not_found\");\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([annas]);\n });\n\n it(\"правка меняет разделы и текст, поднимает версию на 1, createdAt не трогает, updatedAt не уменьшает\", async (context) => {\n const storage = await storageWithMemory(context);\n const [created] = await storage.insertMemoryNotes(\"anna\", [note(\"Пишет на JavaScript\", \"О себе\")]);\n await untilClockMoves();\n const updated = await storage.updateMemoryNote(\"anna\", created!.id, 1, note(\"Пишет на TypeScript\", \"О себе\", \"Работа\"));\n expect(updated).toMatchObject({\n id: created!.id,\n version: 2,\n content: \"Пишет на TypeScript\",\n categories: [\"О себе\", \"Работа\"],\n createdAt: created!.createdAt,\n });\n expect((updated as MemoryNote).updatedAt > created!.updatedAt).toBe(true);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([updated]);\n\n const again = await storage.updateMemoryNote(\"anna\", created!.id, 2, note(\"Пишет на Rust\", \"О себе\"));\n expect(again).toMatchObject({ version: 3, content: \"Пишет на Rust\" });\n });\n\n it(\"правка с устаревшей версией — stale_version, запись не меняется\", async (context) => {\n const storage = await storageWithMemory(context);\n const [created] = await storage.insertMemoryNotes(\"anna\", [note(\"Первая редакция\")]);\n await storage.updateMemoryNote(\"anna\", created!.id, 1, note(\"Вторая редакция\"));\n expect(await storage.updateMemoryNote(\"anna\", created!.id, 1, note(\"Опоздавшая правка\"))).toBe(\"stale_version\");\n expect(await storage.updateMemoryNote(\"anna\", created!.id, 3, note(\"Версия из будущего\"))).toBe(\"stale_version\");\n const [kept] = await storage.listMemoryNotes(\"anna\");\n expect(kept).toMatchObject({ version: 2, content: \"Вторая редакция\" });\n });\n\n it(\"удаление: с верной версией — ok, с устаревшей — stale_version и запись остаётся, повтор — not_found\", async (context) => {\n const storage = await storageWithMemory(context);\n const [created] = await storage.insertMemoryNotes(\"anna\", [note(\"Временная\")]);\n await storage.updateMemoryNote(\"anna\", created!.id, 1, note(\"Временная, правка\"));\n expect(await storage.deleteMemoryNote(\"anna\", created!.id, 1)).toBe(\"stale_version\");\n expect(await storage.listMemoryNotes(\"anna\")).toHaveLength(1);\n expect(await storage.deleteMemoryNote(\"anna\", created!.id, 2)).toBe(\"ok\");\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([]);\n expect(await storage.deleteMemoryNote(\"anna\", created!.id, 2)).toBe(\"not_found\");\n });\n\n it(\"правка и удаление неизвестной записи — not_found\", async (context) => {\n const storage = await storageWithMemory(context);\n expect(await storage.updateMemoryNote(\"anna\", \"missing\", 1, note(\"Нет такой\"))).toBe(\"not_found\");\n expect(await storage.deleteMemoryNote(\"anna\", \"missing\", 1)).toBe(\"not_found\");\n });\n\n it(\"две правки с одной версией одновременно: проходит одна, вторая — stale_version\", async (context) => {\n const storage = await storageWithMemory(context);\n const [created] = await storage.insertMemoryNotes(\"anna\", [note(\"Исходная\")]);\n const results = await Promise.all([\n storage.updateMemoryNote(\"anna\", created!.id, 1, note(\"Правка А\")),\n storage.updateMemoryNote(\"anna\", created!.id, 1, note(\"Правка Б\")),\n ]);\n expect(results.filter((result) => result === \"stale_version\")).toHaveLength(1);\n expect(results.filter((result) => typeof result === \"object\")).toHaveLength(1);\n const [kept] = await storage.listMemoryNotes(\"anna\");\n expect(kept?.version).toBe(2);\n });\n\n it(\"порядок списка: новейшие по updatedAt первыми, при равенстве по createdAt, затем по id\", async (context) => {\n const storage = await storageWithMemory(context);\n const batch = await storage.insertMemoryNotes(\"anna\", [note(\"Первая\"), note(\"Вторая\"), note(\"Третья\")]);\n await untilClockMoves();\n const [later] = await storage.insertMemoryNotes(\"anna\", [note(\"Позже\")]);\n let listed = await storage.listMemoryNotes(\"anna\");\n expect(listed.map((item) => item.id)).toEqual(expectedOrder(listed));\n expect(listed[0]?.id).toBe(later!.id);\n\n // Правка поднимает запись на первое место.\n await untilClockMoves();\n await storage.updateMemoryNote(\"anna\", batch[0]!.id, 1, note(\"Первая, правка\"));\n listed = await storage.listMemoryNotes(\"anna\");\n expect(listed.map((item) => item.id)).toEqual(expectedOrder(listed));\n expect(listed[0]?.id).toBe(batch[0]!.id);\n });\n\n it(\"удаление чата память не трогает\", async (context) => {\n const storage = await storageWithMemory(context);\n await storage.createChat(chatInput);\n await storage.insertMemoryNotes(chatInput.ownerId, [note(\"Переживёт чат\")]);\n await storage.deleteChat(chatInput.id);\n expect((await storage.listMemoryNotes(chatInput.ownerId)).map((item) => item.content)).toEqual([\"Переживёт чат\"]);\n });\n\n it(\"стирание убирает всю память своего человека, возвращает число и не трогает чужую\", async (context) => {\n const storage = await storageWithMemory(context);\n await storage.insertMemoryNotes(\"anna\", [note(\"Один\"), note(\"Два\"), note(\"Три\")]);\n await storage.insertMemoryNotes(\"boris\", [note(\"Борисов\")]);\n expect(await storage.clearMemoryNotes(\"anna\")).toBe(3);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([]);\n expect(await storage.listMemoryNotes(\"boris\")).toHaveLength(1);\n expect(await storage.clearMemoryNotes(\"anna\")).toBe(0);\n expect(await storage.clearMemoryNotes(\"clara\")).toBe(0);\n });\n\n it(\"отданные записи — копии: правка ответа не меняет хранилище\", async (context) => {\n const storage = await storageWithMemory(context);\n const [created] = await storage.insertMemoryNotes(\"anna\", [note(\"Оригинал\", \"О себе\")]);\n created!.content = \"Испорчено\";\n created!.categories.push(\"Лишний\");\n const [listed] = await storage.listMemoryNotes(\"anna\");\n expect(listed).toMatchObject({ content: \"Оригинал\", categories: [\"О себе\"] });\n listed!.categories.push(\"Ещё лишний\");\n expect((await storage.listMemoryNotes(\"anna\"))[0]?.categories).toEqual([\"О себе\"]);\n });\n\n describe(\"проверка внутри операции\", () => {\n type CheckedStorage = MemoryStorage & Required<Pick<ChatStorage, \"insertMemoryNotesChecked\" | \"updateMemoryNoteChecked\">>;\n\n async function checkedStorage(context: { skip: () => never }): Promise<CheckedStorage> {\n const storage = await storageWithMemory(context);\n if (!storage.insertMemoryNotesChecked || !storage.updateMemoryNoteChecked) {\n if (options.memory === \"required\") throw new Error(\"У хранилища нет методов записи с проверкой внутри операции\");\n context.skip();\n }\n return storage as CheckedStorage;\n }\n\n const refuse: MemoryError = { kind: \"limit_reached\", message: \"Хватит\" };\n /** Пускает, пока у человека меньше `max` записей. */\n const atMost =\n (max: number): MemoryWriteGuard =>\n (existing) =>\n existing.length >= max ? refuse : null;\n\n it(\"вставка: проверка видит записи только своего человека, ничего ещё не записано; без ошибки записи появляются\", async (context) => {\n const storage = await checkedStorage(context);\n await storage.insertMemoryNotes(\"anna\", [note(\"Первая\"), note(\"Вторая\")]);\n await storage.insertMemoryNotes(\"boris\", [note(\"Борисова\")]);\n const seen: string[][] = [];\n const created = await storage.insertMemoryNotesChecked(\"anna\", [note(\"Третья\")], (existing) => {\n seen.push(existing.map((item) => item.content));\n return null;\n });\n expect(seen).toHaveLength(1);\n expect([...seen[0]!].sort()).toEqual([\"Вторая\", \"Первая\"]);\n expect(created).toEqual([expect.objectContaining({ content: \"Третья\", version: 1 })]);\n expect(await storage.listMemoryNotes(\"anna\")).toHaveLength(3);\n });\n\n it(\"вставка: ошибка проверки отдаётся как есть и ничего не записывает\", async (context) => {\n const storage = await checkedStorage(context);\n await storage.insertMemoryNotes(\"anna\", [note(\"Первая\")]);\n expect(await storage.insertMemoryNotesChecked(\"anna\", [note(\"Вторая\"), note(\"Третья\")], () => refuse)).toEqual(refuse);\n expect((await storage.listMemoryNotes(\"anna\")).map((item) => item.content)).toEqual([\"Первая\"]);\n });\n\n it(\"вставка: параллельные вставки не обходят проверку — проходят ровно те, что помещаются\", async (context) => {\n const storage = await checkedStorage(context);\n await storage.insertMemoryNotes(\"anna\", [note(\"Одна\"), note(\"Другая\")]);\n const results = await Promise.all(Array.from({ length: 6 }, (_, index) => storage.insertMemoryNotesChecked(\"anna\", [note(`Новая ${index}`)], atMost(5))));\n expect(results.filter(Array.isArray)).toHaveLength(3);\n expect(results.filter((result) => !Array.isArray(result))).toEqual([refuse, refuse, refuse]);\n expect(await storage.listMemoryNotes(\"anna\")).toHaveLength(5);\n });\n\n it(\"правка: проверка видит все записи человека, включая заменяемую; без ошибки запись меняется\", async (context) => {\n const storage = await checkedStorage(context);\n const [first] = await storage.insertMemoryNotes(\"anna\", [note(\"Первая\"), note(\"Вторая\")]);\n let seen: string[] = [];\n const updated = await storage.updateMemoryNoteChecked(\"anna\", first!.id, 1, note(\"Новая\"), (existing) => {\n seen = existing.map((item) => item.content);\n return null;\n });\n expect(seen.sort()).toEqual([\"Вторая\", \"Первая\"]);\n expect(updated).toMatchObject({ content: \"Новая\", version: 2 });\n });\n\n it(\"правка: ошибка проверки отдаётся как есть, запись не меняется, а проверка идёт раньше версии\", async (context) => {\n const storage = await checkedStorage(context);\n const [first] = await storage.insertMemoryNotes(\"anna\", [note(\"Первая\")]);\n expect(await storage.updateMemoryNoteChecked(\"anna\", first!.id, 7, note(\"Новая\"), () => refuse)).toEqual(refuse);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([first]);\n });\n\n it(\"правка: чужая запись и старая версия — как у обычной правки, если проверка пропустила\", async (context) => {\n const storage = await checkedStorage(context);\n const [first] = await storage.insertMemoryNotes(\"anna\", [note(\"Первая\")]);\n expect(await storage.updateMemoryNoteChecked(\"anna\", first!.id, 7, note(\"Новая\"), () => null)).toBe(\"stale_version\");\n expect(await storage.updateMemoryNoteChecked(\"boris\", first!.id, 1, note(\"Новая\"), () => null)).toBe(\"not_found\");\n expect(await storage.updateMemoryNoteChecked(\"anna\", \"missing\", 1, note(\"Новая\"), () => null)).toBe(\"not_found\");\n });\n\n it(\"правка: параллельные правки не обходят проверку\", async (context) => {\n const storage = await checkedStorage(context);\n const [first, second] = await storage.insertMemoryNotes(\"anna\", [note(\"Первая\"), note(\"Вторая\")]);\n const sameTextTaken: MemoryWriteGuard = (existing) => (existing.some((item) => item.content === \"Общий текст\") ? { kind: \"duplicate\", message: \"Повтор\" } : null);\n const results = await Promise.all([\n storage.updateMemoryNoteChecked(\"anna\", first!.id, 1, note(\"Общий текст\"), sameTextTaken),\n storage.updateMemoryNoteChecked(\"anna\", second!.id, 1, note(\"Общий текст\"), sameTextTaken),\n ]);\n expect(results.filter((result) => typeof result === \"object\" && \"content\" in result)).toHaveLength(1);\n expect((await storage.listMemoryNotes(\"anna\")).filter((item) => item.content === \"Общий текст\")).toHaveLength(1);\n });\n });\n });\n describe(\"оптимизация дублей (необязательные методы)\", () => {\n type OptimizerStorage = ChatStorage &\n Required<\n Pick<\n ChatStorage,\n | \"listMemoryNotes\"\n | \"insertMemoryNotes\"\n | \"updateMemoryNote\"\n | \"deleteMemoryNote\"\n | \"clearMemoryNotes\"\n | \"claimMemoryOptimizationRun\"\n | \"finishMemoryOptimizationRun\"\n | \"applyMemoryMerge\"\n | \"revertMemoryMerge\"\n | \"listMemoryOptimizationRuns\"\n | \"listMergedMemoryNotes\"\n >\n >;\n\n const MINUTE = 60_000;\n const rules: MemoryOptimizationRules = { minIntervalMs: 24 * 60 * MINUTE, retryAfterFailureMs: 60 * MINUTE, leaseMs: 3 * MINUTE };\n /** Время запуска: минуты от условного начала; хранилище берёт часы у вызывающего. */\n const at = (minutes: number) => new Date(Date.UTC(2026, 0, 1) + minutes * MINUTE).toISOString();\n\n async function storageWithOptimizer(context: { skip: () => never }): Promise<OptimizerStorage> {\n const storage = await createStorage();\n const present =\n storage.listMemoryNotes &&\n storage.insertMemoryNotes &&\n storage.updateMemoryNote &&\n storage.deleteMemoryNote &&\n storage.clearMemoryNotes &&\n storage.claimMemoryOptimizationRun &&\n storage.finishMemoryOptimizationRun &&\n storage.applyMemoryMerge &&\n storage.revertMemoryMerge &&\n storage.listMemoryOptimizationRuns &&\n storage.listMergedMemoryNotes;\n if (!present) {\n if (options.memoryOptimization === \"required\") throw new Error(\"У хранилища нет методов оптимизации дублей\");\n context.skip();\n }\n return storage as OptimizerStorage;\n }\n\n const note = (content: string, ...categories: string[]): MemoryNoteInput => ({\n categories: categories.length > 0 ? categories : [\"О себе\"],\n content,\n });\n\n async function claimed(storage: OptimizerStorage, ownerId = \"anna\", minutes = 0) {\n const run = await storage.claimMemoryOptimizationRun(ownerId, rules, at(minutes));\n expect(run).not.toBeNull();\n return run!;\n }\n\n /** Три записи и запуск: то, с чего начинается слияние двух из них. */\n async function withRun(storage: OptimizerStorage) {\n const [first, second, third] = await storage.insertMemoryNotes(\"anna\", [\n note(\"Пишет на TypeScript\", \"О себе\", \"Работа\"),\n note(\"Работает с TypeScript\", \"О себе\", \"Работа\"),\n note(\"Любит чай\", \"О себе\"),\n ]);\n const run = await claimed(storage);\n const merge = (finishedAt = at(5)) => ({\n runId: run.id,\n finishedAt,\n merges: [\n {\n result: note(\"Пишет на TypeScript на работе\", \"О себе\", \"Работа\"),\n originals: [\n { id: first!.id, version: first!.version },\n { id: second!.id, version: second!.version },\n ],\n },\n ],\n });\n return { first: first!, second: second!, third: third!, run, merge };\n }\n\n describe(\"взятие запуска\", () => {\n it(\"без запусков берёт новый: идёт, начат в назначенное время, склеек и ошибки нет\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const run = await storage.claimMemoryOptimizationRun(\"anna\", rules, at(0));\n expect(run).toMatchObject({ status: \"running\", startedAt: at(0), finishedAt: null, groups: [], error: null, usageRecordId: null });\n expect(typeof run?.id).toBe(\"string\");\n expect(await storage.listMemoryOptimizationRuns(\"anna\")).toEqual([run]);\n });\n\n it(\"пока запуск идёт, второй не берётся\", async (context) => {\n const storage = await storageWithOptimizer(context);\n await claimed(storage, \"anna\", 0);\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(2))).toBeNull();\n expect(await storage.listMemoryOptimizationRuns(\"anna\")).toHaveLength(1);\n });\n\n it(\"просроченный запуск становится неудачным с концом в момент истечения; повтор — после паузы неудачи\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const lost = await claimed(storage, \"anna\", 0);\n // Срок аренды вышел, но пауза после неудачи (час от конца запуска) — ещё нет.\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(10))).toBeNull();\n const [expired] = await storage.listMemoryOptimizationRuns(\"anna\");\n expect(expired).toMatchObject({ id: lost.id, status: \"failed\", error: \"lease_expired\", finishedAt: at(3) });\n // Пауза считается от конца запуска (минута 3), а не от того, когда о нём узнали.\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(3 + 59))).toBeNull();\n const next = await storage.claimMemoryOptimizationRun(\"anna\", rules, at(3 + 60));\n expect(next).toMatchObject({ status: \"running\", startedAt: at(3 + 60) });\n expect(next?.id).not.toBe(lost.id);\n });\n\n it(\"после законченного запуска следующий — не раньше срока между запусками\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const run = await claimed(storage, \"anna\", 0);\n expect(await storage.finishMemoryOptimizationRun(\"anna\", run.id, { status: \"no_changes\", finishedAt: at(1) })).toBe(\"ok\");\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(1 + 24 * 60 - 1))).toBeNull();\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(1 + 24 * 60))).toMatchObject({ status: \"running\" });\n });\n\n it(\"после неудачи повтор — не раньше чем через час, и суточный срок его не ждёт\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const run = await claimed(storage, \"anna\", 0);\n await storage.finishMemoryOptimizationRun(\"anna\", run.id, { status: \"failed\", finishedAt: at(1), error: \"model_error\" });\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(1 + 59))).toBeNull();\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(1 + 60))).toMatchObject({ status: \"running\" });\n });\n\n it(\"неудачи подряд растят паузу (1 ч → 6 ч → 24 ч), а законченный запуск начинает счёт заново\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const ladder: MemoryOptimizationRules = { ...rules, retryAfterFailureMs: [60 * MINUTE, 360 * MINUTE, 1440 * MINUTE] };\n const HOUR = 60;\n async function failAt(start: number) {\n const run = await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(start));\n expect(run).not.toBeNull();\n await storage.finishMemoryOptimizationRun(\"anna\", run!.id, { status: \"failed\", finishedAt: at(start + 1), error: \"model_error\" });\n return start + 1;\n }\n let end = await failAt(0);\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(end + HOUR - 1))).toBeNull();\n end = await failAt(end + HOUR);\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(end + 6 * HOUR - 1))).toBeNull();\n end = await failAt(end + 6 * HOUR);\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(end + 24 * HOUR - 1))).toBeNull();\n end = await failAt(end + 24 * HOUR);\n // Дальше пауза остаётся суточной.\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(end + 24 * HOUR - 1))).toBeNull();\n const success = await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(end + 24 * HOUR));\n await storage.finishMemoryOptimizationRun(\"anna\", success!.id, { status: \"no_changes\", finishedAt: at(end + 24 * HOUR + 1) });\n // После законченного запуска первая же неудача снова ждёт только час.\n const restart = end + 24 * HOUR + 1 + 24 * HOUR;\n const again = await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(restart));\n await storage.finishMemoryOptimizationRun(\"anna\", again!.id, { status: \"failed\", finishedAt: at(restart + 1), error: \"model_error\" });\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(restart + 1 + HOUR - 1))).toBeNull();\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(restart + 1 + HOUR))).toMatchObject({ status: \"running\" });\n });\n\n it(\"просроченный запуск тоже считается неудачей подряд\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const ladder: MemoryOptimizationRules = { ...rules, retryAfterFailureMs: [60 * MINUTE, 360 * MINUTE] };\n await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(0));\n // Аренда вышла в минуту 3, пауза первой неудачи — до минуты 63.\n const second = await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(3 + 60));\n expect(second).not.toBeNull();\n await storage.finishMemoryOptimizationRun(\"anna\", second!.id, { status: \"failed\", finishedAt: at(65), error: \"model_error\" });\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(65 + 359))).toBeNull();\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(65 + 360))).toMatchObject({ status: \"running\" });\n });\n\n it(\"слитый и отменённый запуски тоже считаются законченными\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { merge, run } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge(at(5)));\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(60))).toBeNull();\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"ok\");\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(60))).toBeNull();\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(5 + 24 * 60))).toMatchObject({ status: \"running\" });\n });\n\n it(\"запуски разных людей не мешают друг другу\", async (context) => {\n const storage = await storageWithOptimizer(context);\n await claimed(storage, \"anna\", 0);\n expect(await storage.claimMemoryOptimizationRun(\"boris\", rules, at(0))).toMatchObject({ status: \"running\" });\n expect(await storage.listMemoryOptimizationRuns(\"boris\")).toHaveLength(1);\n });\n\n it(\"несколько одновременных попыток дают ровно один запуск\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const results = await Promise.all(Array.from({ length: 6 }, () => storage.claimMemoryOptimizationRun(\"anna\", rules, at(0))));\n expect(results.filter((run) => run !== null)).toHaveLength(1);\n expect(await storage.listMemoryOptimizationRuns(\"anna\")).toHaveLength(1);\n });\n });\n\n describe(\"закрытие запуска без слияния\", () => {\n it(\"«нечего сливать» и «не удалось» записывают конец, ошибку и расход\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const first = await claimed(storage, \"anna\", 0);\n expect(\n await storage.finishMemoryOptimizationRun(\"anna\", first.id, { status: \"no_changes\", finishedAt: at(1), usageRecordId: \"usage-1\" }),\n ).toBe(\"ok\");\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]).toMatchObject({\n id: first.id,\n status: \"no_changes\",\n finishedAt: at(1),\n error: null,\n usageRecordId: \"usage-1\",\n });\n const second = await claimed(storage, \"anna\", 2000);\n await storage.finishMemoryOptimizationRun(\"anna\", second.id, { status: \"failed\", finishedAt: at(2001), error: \"invalid_proposal\" });\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]).toMatchObject({ id: second.id, status: \"failed\", error: \"invalid_proposal\" });\n });\n\n it(\"чужой, отсутствующий и уже закрытый запуск — not_found и не меняется\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const run = await claimed(storage, \"anna\", 0);\n expect(await storage.finishMemoryOptimizationRun(\"boris\", run.id, { status: \"failed\", finishedAt: at(1), error: \"x\" })).toBe(\"not_found\");\n expect(await storage.finishMemoryOptimizationRun(\"anna\", \"missing\", { status: \"failed\", finishedAt: at(1), error: \"x\" })).toBe(\"not_found\");\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.status).toBe(\"running\");\n await storage.finishMemoryOptimizationRun(\"anna\", run.id, { status: \"no_changes\", finishedAt: at(1) });\n expect(await storage.finishMemoryOptimizationRun(\"anna\", run.id, { status: \"failed\", finishedAt: at(2), error: \"x\" })).toBe(\"not_found\");\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]).toMatchObject({ status: \"no_changes\", finishedAt: at(1) });\n });\n });\n\n describe(\"слияние\", () => {\n it(\"вставляет результат (версия 1), прячет оригиналы, закрывает запуск как слитый со склейкой\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, second, third, run, merge } = await withRun(storage);\n const applied = await storage.applyMemoryMerge(\"anna\", merge(at(5)));\n expect(typeof applied).toBe(\"object\");\n const visible = await storage.listMemoryNotes(\"anna\");\n expect(visible.map((item) => item.content).sort()).toEqual([\"Любит чай\", \"Пишет на TypeScript на работе\"]);\n const result = visible.find((item) => item.content === \"Пишет на TypeScript на работе\")!;\n expect(result).toMatchObject({ version: 1, categories: [\"О себе\", \"Работа\"] });\n expect(applied).toEqual({\n id: run.id,\n startedAt: run.startedAt,\n finishedAt: at(5),\n status: \"applied\",\n groups: [{ resultId: result.id, originalIds: [first.id, second.id], resultVersion: 1 }],\n error: null,\n usageRecordId: null,\n });\n expect(await storage.listMemoryOptimizationRuns(\"anna\")).toEqual([applied]);\n expect(visible.find((item) => item.id === third.id)).toEqual(third);\n });\n\n it(\"скрытые оригиналы читаются отдельным списком с id результата и прежними версией и временем\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, second, merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n const [result] = (await storage.listMemoryNotes(\"anna\")).filter((item) => item.content.endsWith(\"на работе\"));\n const hidden = await storage.listMergedMemoryNotes(\"anna\");\n expect(hidden.map((item) => item.id).sort()).toEqual([first.id, second.id].sort());\n for (const item of hidden) {\n expect(item.mergedInto).toBe(result!.id);\n expect(item).toMatchObject({ version: 1, categories: [\"О себе\", \"Работа\"] });\n }\n expect(await storage.listMergedMemoryNotes(\"boris\")).toEqual([]);\n });\n\n it(\"оригинал, изменённый за время работы модели, — stale_version, и ничего не меняется\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, run, merge } = await withRun(storage);\n await storage.updateMemoryNote(\"anna\", first.id, 1, note(\"Пишет на Rust\", \"О себе\"));\n const before = await storage.listMemoryNotes(\"anna\");\n expect(await storage.applyMemoryMerge(\"anna\", merge())).toBe(\"stale_version\");\n expect(await storage.listMemoryNotes(\"anna\")).toEqual(before);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]).toMatchObject({ id: run.id, status: \"running\", groups: [] });\n });\n\n it(\"оригинал удалён — stale_version\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { second, merge } = await withRun(storage);\n await storage.deleteMemoryNote(\"anna\", second.id, 1);\n expect(await storage.applyMemoryMerge(\"anna\", merge())).toBe(\"stale_version\");\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n });\n\n it(\"оригинал чужой — stale_version, чужая запись цела\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const [theirs] = await storage.insertMemoryNotes(\"boris\", [note(\"Чужая\")]);\n const run = await claimed(storage, \"anna\", 0);\n const merge = { runId: run.id, finishedAt: at(1), merges: [{ result: note(\"Присвоено\"), originals: [{ id: theirs!.id, version: 1 }] }] };\n expect(await storage.applyMemoryMerge(\"anna\", merge)).toBe(\"stale_version\");\n expect(await storage.listMemoryNotes(\"boris\")).toEqual([theirs]);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([]);\n });\n\n it(\"уже скрытый оригинал вторым слиянием не берётся — stale_version\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n const again = await storage.claimMemoryOptimizationRun(\"anna\", { ...rules, minIntervalMs: 0 }, at(10));\n expect(again).not.toBeNull();\n const second = { runId: again!.id, finishedAt: at(11), merges: [{ result: note(\"Ещё раз\"), originals: [{ id: first.id, version: 1 }] }] };\n expect(await storage.applyMemoryMerge(\"anna\", second)).toBe(\"stale_version\");\n });\n\n it(\"несколько склеек — все или ни одной\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const [a, b, c, d] = await storage.insertMemoryNotes(\"anna\", [note(\"Кот Барсик\"), note(\"Кот по имени Барсик\"), note(\"Живёт на Бали\"), note(\"Живёт на Бали в Чангу\")]);\n await storage.updateMemoryNote(\"anna\", d!.id, 1, note(\"Живёт на Бали, Чангу\"));\n const run = await claimed(storage);\n const before = await storage.listMemoryNotes(\"anna\");\n const outcome = await storage.applyMemoryMerge(\"anna\", {\n runId: run.id,\n finishedAt: at(1),\n merges: [\n { result: note(\"Кот Барсик\"), originals: [{ id: a!.id, version: 1 }, { id: b!.id, version: 1 }] },\n { result: note(\"Живёт на Бали в Чангу\"), originals: [{ id: c!.id, version: 1 }, { id: d!.id, version: 1 }] },\n ],\n });\n expect(outcome).toBe(\"stale_version\");\n expect(await storage.listMemoryNotes(\"anna\")).toEqual(before);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n });\n\n it(\"запуск, которого нет, чужой или уже закрытый, — run_not_active\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, run, merge } = await withRun(storage);\n expect(await storage.applyMemoryMerge(\"anna\", { ...merge(), runId: \"missing\" })).toBe(\"run_not_active\");\n expect(await storage.applyMemoryMerge(\"boris\", merge())).toBe(\"run_not_active\");\n await storage.finishMemoryOptimizationRun(\"anna\", run.id, { status: \"failed\", finishedAt: at(1), error: \"x\" });\n expect(await storage.applyMemoryMerge(\"anna\", merge())).toBe(\"run_not_active\");\n expect((await storage.listMemoryNotes(\"anna\")).find((item) => item.id === first.id)).toBeDefined();\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n });\n\n it(\"негодный вызов — исключение, и ничего не меняется\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, second, run } = await withRun(storage);\n const before = await storage.listMemoryNotes(\"anna\");\n const original = (item: MemoryNote) => ({ id: item.id, version: item.version });\n const bad = [\n { runId: run.id, finishedAt: at(1), merges: [] },\n { runId: run.id, finishedAt: at(1), merges: [{ result: note(\"Пусто\"), originals: [] }] },\n {\n runId: run.id,\n finishedAt: at(1),\n merges: [\n { result: note(\"Раз\"), originals: [original(first), original(second)] },\n { result: note(\"Два\"), originals: [original(first)] },\n ],\n },\n {\n runId: run.id,\n finishedAt: at(1),\n merges: [{ result: { categories: [\"О себе\"], content: null } as unknown as MemoryNoteInput, originals: [original(first), original(second)] }],\n },\n ];\n for (const merge of bad) await expect(storage.applyMemoryMerge(\"anna\", merge)).rejects.toBeInstanceOf(Error);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual(before);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.status).toBe(\"running\");\n });\n });\n\n describe(\"скрытые записи\", () => {\n it(\"правка и удаление скрытой записи — not_found; список её не показывает\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n expect(await storage.updateMemoryNote(\"anna\", first.id, 1, note(\"Правка скрытой\"))).toBe(\"not_found\");\n expect(await storage.deleteMemoryNote(\"anna\", first.id, 1)).toBe(\"not_found\");\n expect((await storage.listMemoryNotes(\"anna\")).some((item) => item.id === first.id)).toBe(false);\n expect((await storage.listMergedMemoryNotes(\"anna\")).some((item) => item.id === first.id && item.content === \"Пишет на TypeScript\")).toBe(true);\n });\n\n it(\"удаление результата удаляет и скрытые оригиналы; устаревшая версия ничего не удаляет\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { third, merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n const result = (await storage.listMemoryNotes(\"anna\")).find((item) => item.content.endsWith(\"на работе\"))!;\n expect(await storage.deleteMemoryNote(\"anna\", result.id, 7)).toBe(\"stale_version\");\n expect(await storage.listMergedMemoryNotes(\"anna\")).toHaveLength(2);\n expect(await storage.deleteMemoryNote(\"anna\", result.id, 1)).toBe(\"ok\");\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n expect((await storage.listMemoryNotes(\"anna\")).map((item) => item.id)).toEqual([third.id]);\n });\n\n it(\"стирание памяти убирает скрытые оригиналы и запуски, считает только видимые, чужое не трогает\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n await storage.insertMemoryNotes(\"boris\", [note(\"Борисова\")]);\n const boris = await claimed(storage, \"boris\", 0);\n // Видны: результат и «Любит чай»; скрытых двое — они не считаются.\n expect(await storage.clearMemoryNotes(\"anna\")).toBe(2);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n expect(await storage.listMemoryOptimizationRuns(\"anna\")).toEqual([]);\n expect(await storage.listMemoryNotes(\"boris\")).toHaveLength(1);\n expect(await storage.listMemoryOptimizationRuns(\"boris\")).toEqual([expect.objectContaining({ id: boris.id })]);\n });\n });\n\n describe(\"возврат слияния\", () => {\n it(\"возвращает оригиналы как были, убирает результат, запуск становится отменённым\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run, merge } = await withRun(storage);\n const before = await storage.listMemoryNotes(\"anna\");\n const applied = (await storage.applyMemoryMerge(\"anna\", merge())) as { groups: unknown };\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"ok\");\n expect(await storage.listMemoryNotes(\"anna\")).toEqual(before);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n const [reverted] = await storage.listMemoryOptimizationRuns(\"anna\");\n expect(reverted).toMatchObject({ id: run.id, status: \"reverted\", groups: applied.groups });\n expect(reverted?.finishedAt).toBe(at(5));\n });\n\n it(\"результат менялся — conflict, ничего не меняется\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run, merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n const result = (await storage.listMemoryNotes(\"anna\")).find((item) => item.content.endsWith(\"на работе\"))!;\n await storage.updateMemoryNote(\"anna\", result.id, 1, note(\"Пишет на TypeScript в компании\", \"О себе\", \"Работа\"));\n const visible = await storage.listMemoryNotes(\"anna\");\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"conflict\");\n expect(await storage.listMemoryNotes(\"anna\")).toEqual(visible);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toHaveLength(2);\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.status).toBe(\"applied\");\n });\n\n it(\"результат удалён (вместе с оригиналами) — conflict\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run, merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n const result = (await storage.listMemoryNotes(\"anna\")).find((item) => item.content.endsWith(\"на работе\"))!;\n await storage.deleteMemoryNote(\"anna\", result.id, 1);\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"conflict\");\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.status).toBe(\"applied\");\n });\n\n it(\"запуск, которого нет, чужой, идущий, без слияния или уже отменённый, — not_found\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run, merge } = await withRun(storage);\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"not_found\");\n expect(await storage.revertMemoryMerge(\"anna\", \"missing\")).toBe(\"not_found\");\n await storage.applyMemoryMerge(\"anna\", merge());\n expect(await storage.revertMemoryMerge(\"boris\", run.id)).toBe(\"not_found\");\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"ok\");\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"not_found\");\n const quiet = await storageWithOptimizer(context);\n const idle = await claimed(quiet);\n await quiet.finishMemoryOptimizationRun(\"anna\", idle.id, { status: \"no_changes\", finishedAt: at(1) });\n expect(await quiet.revertMemoryMerge(\"anna\", idle.id)).toBe(\"not_found\");\n });\n\n describe(\"проверка пределов при возврате\", () => {\n /** Слияние применено; результат — «… на работе». Гарды пишут, что видели. */\n async function applied(storage: OptimizerStorage) {\n const setup = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", setup.merge());\n return setup;\n }\n\n it(\"проверка видит записи без результатов слияния и оригиналы, что вернутся; пропустила — возврат выполнен\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run, first, second } = await applied(storage);\n const seen: { remaining: string[]; restored: string[] }[] = [];\n const result = await storage.revertMemoryMerge(\"anna\", run.id, (remaining, restored) => {\n seen.push({ remaining: remaining.map((item) => item.content), restored: restored.map((item) => item.id).sort() });\n return null;\n });\n expect(result).toBe(\"ok\");\n expect(seen).toEqual([{ remaining: [\"Любит чай\"], restored: [first.id, second.id].sort() }]);\n expect(await storage.listMemoryNotes(\"anna\")).toHaveLength(3);\n });\n\n for (const kind of [\"limit_reached\", \"duplicate\"] as const) {\n it(`ошибка проверки ${kind} — тот же результат, ничего не изменено, запуск остаётся слитым`, async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run } = await applied(storage);\n const visible = await storage.listMemoryNotes(\"anna\");\n const hidden = await storage.listMergedMemoryNotes(\"anna\");\n expect(await storage.revertMemoryMerge(\"anna\", run.id, () => ({ kind, message: \"Нельзя\" }))).toBe(kind);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual(visible);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual(hidden);\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.status).toBe(\"applied\");\n // Место освободили — тот же возврат теперь проходит.\n expect(await storage.revertMemoryMerge(\"anna\", run.id, () => null)).toBe(\"ok\");\n });\n }\n\n it(\"проверка не зовётся, если возврат невозможен: конфликт, чужой или несуществующий запуск\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run } = await applied(storage);\n const result = (await storage.listMemoryNotes(\"anna\")).find((item) => item.content.endsWith(\"на работе\"))!;\n await storage.updateMemoryNote(\"anna\", result.id, 1, note(\"Пишет на TypeScript в компании\", \"О себе\", \"Работа\"));\n let calls = 0;\n const guard = () => {\n calls += 1;\n return null;\n };\n expect(await storage.revertMemoryMerge(\"anna\", run.id, guard)).toBe(\"conflict\");\n expect(await storage.revertMemoryMerge(\"boris\", run.id, guard)).toBe(\"not_found\");\n expect(await storage.revertMemoryMerge(\"anna\", \"missing\", guard)).toBe(\"not_found\");\n expect(calls).toBe(0);\n });\n });\n });\n\n describe(\"список запусков\", () => {\n it(\"новейшие первыми, с отбором по состоянию и числу; чужих нет\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const day = 24 * 60;\n const oldest = await claimed(storage, \"anna\", 0);\n await storage.finishMemoryOptimizationRun(\"anna\", oldest.id, { status: \"no_changes\", finishedAt: at(1) });\n const middle = await claimed(storage, \"anna\", 2 * day);\n await storage.finishMemoryOptimizationRun(\"anna\", middle.id, { status: \"failed\", finishedAt: at(2 * day + 1), error: \"x\" });\n const newest = await claimed(storage, \"anna\", 4 * day);\n await claimed(storage, \"boris\", 0);\n expect((await storage.listMemoryOptimizationRuns(\"anna\")).map((run) => run.id)).toEqual([newest.id, middle.id, oldest.id]);\n expect((await storage.listMemoryOptimizationRuns(\"anna\", { limit: 2 })).map((run) => run.id)).toEqual([newest.id, middle.id]);\n expect((await storage.listMemoryOptimizationRuns(\"anna\", { status: [\"failed\", \"no_changes\"] })).map((run) => run.id)).toEqual([middle.id, oldest.id]);\n expect(await storage.listMemoryOptimizationRuns(\"anna\", { status: [\"reverted\"] })).toEqual([]);\n expect(await storage.listMemoryOptimizationRuns(\"clara\")).toEqual([]);\n });\n\n it(\"отданные запуски и скрытые записи — копии\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n const [run] = await storage.listMemoryOptimizationRuns(\"anna\");\n run!.groups[0]!.originalIds.push(\"лишний\");\n run!.groups.push({ resultId: \"x\", originalIds: [], resultVersion: 1 });\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.groups).toHaveLength(1);\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.groups[0]?.originalIds).toHaveLength(2);\n const [hidden] = await storage.listMergedMemoryNotes(\"anna\");\n hidden!.categories.push(\"Лишний\");\n expect((await storage.listMergedMemoryNotes(\"anna\"))[0]?.categories).toEqual([\"О себе\", \"Работа\"]);\n });\n });\n });\n });\n}\n\n/** Модель для проверок виджета: первый запрос в каждом чате — вызов ask_choice, дальше — короткий текст. */\nfunction widgetModel() {\n const usage = { inputTokens: { total: 10, noCache: 10, cacheRead: 0, cacheWrite: 0 }, outputTokens: { total: 2, text: 2, reasoning: 0 } };\n const finish = (reason: \"stop\" | \"tool-calls\") => ({ type: \"finish\", finishReason: { unified: reason, raw: reason }, usage });\n const asked = (prompt: unknown) => JSON.stringify(prompt).includes('\"tool-result\"');\n return {\n specificationVersion: \"v4\",\n provider: \"contract\",\n modelId: \"contract-v1\",\n supportedUrls: {},\n doGenerate: async () => {\n throw new Error(\"Проверкам виджета doGenerate не нужен\");\n },\n doStream: async ({ prompt }: { prompt: unknown }) => {\n const parts = asked(prompt)\n ? [{ type: \"text-start\", id: \"t\" }, { type: \"text-delta\", id: \"t\", delta: \"Готово\" }, { type: \"text-end\", id: \"t\" }, finish(\"stop\")]\n : [{ type: \"tool-call\", toolCallId: \"w1\", toolName: \"ask_choice\", input: JSON.stringify({ question: \"Какой тариф?\", options: [\"Базовый\", \"Про\"] }) }, finish(\"tool-calls\")];\n return {\n stream: new ReadableStream({\n start(controller) {\n for (const part of [{ type: \"stream-start\", warnings: [] }, ...parts]) controller.enqueue(part);\n controller.close();\n },\n }),\n };\n },\n };\n}\n\nconst widgetQuestion = (id = \"u1\") => ({ id, role: \"user\" as const, parts: [{ type: \"text\" as const, text: \"помоги выбрать тариф\" }] });\n\n/** Служба чата с базовыми виджетами на этом хранилище: как отдельная копия сервера. */\nfunction widgetService(storage: ChatStorage): ChatService {\n const model = widgetModel();\n const catalog = extendCatalog(standardCatalog, {\n addProviders: [\n {\n id: \"contract\",\n displayName: \"contract\",\n apiKeyEnv: \"CONTRACT_API_KEY\",\n createLanguageModel: () => model as never,\n requestOptions: () => ({}),\n },\n ],\n addModels: [\n {\n id: \"contract-model\",\n displayName: \"Contract Model\",\n contextWindowTokens: 100_000,\n acceptsImages: false,\n reasoning: { replayPastTurns: true },\n providerModelIds: { contract: \"contract-v1\" },\n },\n ],\n });\n return createChatService({\n storage,\n catalog,\n defaultChoice: { modelId: \"contract-model\", providerId: \"contract\" },\n agent: { instructions: \"Ты помощник.\", widgets: { basic: true } },\n env: { CONTRACT_API_KEY: \"не-настоящий-ключ\" },\n logError: () => {},\n });\n}\n\n/** Служба с инструментом поиска: первый шаг ответа вызывает `find`, второй — пишет текст. Запросы к модели копятся в `prompts`. */\nfunction editAnswerService(storage: ChatStorage, lockedToolOutputs?: readonly string[]): { service: ChatService; prompts: unknown[] } {\n const prompts: unknown[] = [];\n const usage = { inputTokens: { total: 10, noCache: 10, cacheRead: 0, cacheWrite: 0 }, outputTokens: { total: 5, text: 5, reasoning: 0 } };\n const finish = (reason: \"stop\" | \"tool-calls\") => ({ type: \"finish\", finishReason: { unified: reason, raw: reason }, usage });\n const text = (id: string, delta: string) => [{ type: \"text-start\", id }, { type: \"text-delta\", id, delta }, { type: \"text-end\", id }];\n const model = {\n specificationVersion: \"v4\",\n provider: \"contract\",\n modelId: \"contract-v1\",\n supportedUrls: {},\n doGenerate: async () => {\n throw new Error(\"Проверкам правки ответа doGenerate не нужен\");\n },\n doStream: async ({ prompt }: { prompt: readonly { role: string }[] }) => {\n prompts.push(prompt);\n const parts =\n prompt.at(-1)?.role === \"tool\"\n ? [...text(\"t2\", \"Нашёл отчёт.\"), finish(\"stop\")]\n : [...text(\"t1\", \"Ищу отчёт.\"), { type: \"tool-call\", toolCallId: prompts.length === 1 ? \"f1\" : `f${prompts.length}`, toolName: \"find\", input: JSON.stringify({ name: \"отчёт\" }) }, finish(\"tool-calls\")];\n return {\n stream: new ReadableStream({\n start(controller) {\n for (const part of [{ type: \"stream-start\", warnings: [] }, ...parts]) controller.enqueue(part);\n controller.close();\n },\n }),\n };\n },\n };\n const catalog = extendCatalog(standardCatalog, {\n addProviders: [\n {\n id: \"contract\",\n displayName: \"contract\",\n apiKeyEnv: \"CONTRACT_API_KEY\",\n createLanguageModel: () => model as never,\n requestOptions: () => ({}),\n },\n ],\n addModels: [\n {\n id: \"contract-model\",\n displayName: \"Contract Model\",\n contextWindowTokens: 100_000,\n acceptsImages: false,\n reasoning: { replayPastTurns: true },\n providerModelIds: { contract: \"contract-v1\" },\n },\n ],\n });\n const find = {\n description: \"Найти файл\",\n inputSchema: jsonSchema<{ name: string }>({ type: \"object\", properties: { name: { type: \"string\" } }, required: [\"name\"] }),\n execute: async () => \"нашёл: отчёт.pdf\",\n };\n const service = createChatService({\n storage,\n catalog,\n defaultChoice: { modelId: \"contract-model\", providerId: \"contract\" },\n agent: { instructions: \"Ты помощник.\", tools: { find } },\n env: { CONTRACT_API_KEY: \"не-настоящий-ключ\" },\n logError: () => {},\n ...(lockedToolOutputs && { lockedToolOutputs }),\n });\n return { service, prompts };\n}\n\nasync function drain(stream: ReadableStream<unknown>): Promise<void> {\n const reader = stream.getReader();\n while (!(await reader.read()).done);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/storage/storage-contract.ts"],"sourcesContent":["import { jsonSchema } from \"ai\";\nimport { describe, expect, it, vi } from \"vitest\";\nimport { CURRENT_FORMAT_VERSION, newStoredMessage } from \"../conversation/types\";\nimport type { StoredBranchSelection, StoredCompaction, StoredMessage, UsageRecord } from \"../conversation/types\";\nimport {\n ChatAlreadyExistsError,\n DuplicateChatSubjectError,\n DuplicateMessageError,\n MessageAlreadyFinishedError,\n MessageNotAwaitingError,\n UnsupportedFormatVersionError,\n} from \"./chat-storage\";\nimport type { ChatStorage, StoredPendingBurst } from \"./chat-storage\";\nimport type { TurnRequestContext } from \"../page-context/page-context\";\nimport { ChatDataTooLargeError } from \"./chat-data\";\nimport type { ChatDataFilter } from \"./chat-data\";\nimport { WidgetNotPendingError, createChatService } from \"../chat-service\";\nimport type { ChatService } from \"../chat-service\";\nimport { AnswerEditError } from \"../conversation/edit-answer-parts\";\nimport { extendCatalog } from \"../models/catalog-changes\";\nimport { standardCatalog } from \"../models/standard-catalog\";\nimport type { MemoryError, MemoryNote, MemoryNoteInput, MemoryWriteGuard } from \"../memory/long-term-memory\";\nimport type { MemoryOptimizationRules } from \"../memory/memory-optimization\";\n\n/**\n * Проверки договора хранилища (contracts/storage.md). Каждый адаптер подключает их\n * в своих тестах: `describeChatStorageContract(() => createMyStorage())`.\n */\nexport function describeChatStorageContract(\n createStorage: () => ChatStorage | Promise<ChatStorage>,\n options: {\n /** `choiceMemory: \"required\"` — методы запомненного выбора обязаны быть (для встроенных хранилищ); иначе их проверки пропускаются. */\n choiceMemory?: \"required\";\n /** `voiceDialog: \"required\"` — то же для методов голосового режима (`setVoiceCut`, `getVoiceChoice`, `setVoiceChoice`). */\n voiceDialog?: \"required\";\n /** `memory: \"required\"` — методы долгой памяти обязаны быть (для встроенных хранилищ). */\n memory?: \"required\";\n /** `memoryOptimization: \"required\"` — методы оптимизации дублей обязаны быть (для встроенных хранилищ). */\n memoryOptimization?: \"required\";\n /** `spendingLimitState: \"required\"` — методы состояния лимитов расходов обязаны быть (для встроенных хранилищ). */\n spendingLimitState?: \"required\";\n /** `subjectChats: \"required\"` — чаты объектов обязаны быть (`findChatBySubject`, ключ, данные, название и дата в `createChat`, `listChats` с `subjects`). */\n subjectChats?: \"required\";\n /** `chatData: \"required\"` — данные чата (`data`, `updateChatData`, фильтр `data` в `listChats`) обязаны быть. */\n chatData?: \"required\";\n /** `importChat: \"required\"` — перенос чата целиком (`importChat`) обязан быть. */\n importChat?: \"required\";\n /** `afterTurnState: \"required\"` — состояние хука итога у сообщения (`setAfterTurnState`, `listPendingAfterTurn`) обязано быть. */\n afterTurnState?: \"required\";\n /** `chatClosure: \"required\"` — закрытие чата (`setChatClosed`, поле `closed` у чата) обязано быть. */\n chatClosure?: \"required\";\n /** `partsOfTypes: \"required\"` — лёгкое чтение частей нужных типов (`listMessagePartsOfTypes`) обязано быть. */\n partsOfTypes?: \"required\";\n /** `usageByChat: \"required\"` — сумма расхода по списку чатов одним запросом (`sumUsageByChat`) обязана быть. */\n usageByChat?: \"required\";\n /**\n * `chatTurnLease: \"required\"` — аренда хода чата между копиями сервера (`claimChatTurn`, `releaseChatTurn`,\n * `clearChatTurnLeases`) обязана быть.\n */\n chatTurnLease?: \"required\";\n /**\n * `pendingBursts: \"required\"` — ждущие пачки (`savePendingBurst`, `takeAbandonedBursts`, `renewPendingBurst`,\n * `removePendingBurst`) обязаны быть.\n */\n pendingBursts?: \"required\";\n } = {},\n): void {\n const chatInput = { id: \"chat-1\", ownerId: \"anna\", modelId: \"deepseek-4.1-flash\", providerId: \"deepseek\" };\n\n function userMessage(id: string, createdAt: string, parentId: string | null = null): StoredMessage {\n return newStoredMessage({\n id,\n chatId: chatInput.id,\n parentId,\n role: \"user\",\n parts: [{ type: \"text\", text: `вопрос ${id}` }],\n createdAt,\n });\n }\n\n function streamingAnswer(id: string, parentId: string, createdAt: string): StoredMessage {\n return {\n ...userMessage(id, createdAt, parentId),\n role: \"assistant\",\n parts: [],\n status: \"streaming\",\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n };\n }\n\n async function storageWithChat(): Promise<ChatStorage> {\n const storage = await createStorage();\n await storage.createChat(chatInput);\n return storage;\n }\n\n describe(\"договор ChatStorage\", () => {\n it(\"создаёт чат и читает его; неизвестный чат — null\", async () => {\n const storage = await storageWithChat();\n const chat = await storage.getChat(chatInput.id);\n expect(chat).toMatchObject(chatInput);\n expect(typeof chat?.createdAt).toBe(\"string\");\n expect(chat?.updatedAt).toBe(chat?.createdAt);\n expect(await storage.getChat(\"missing\")).toBeNull();\n });\n\n it(\"хранит происхождение чата: из мессенджера — отдаёт, без него — поля нет\", async () => {\n const storage = await createStorage();\n const fromMessenger = await storage.createChat({ ...chatInput, id: \"from-telegram\", origin: \"telegram\" });\n expect(fromMessenger.origin).toBe(\"telegram\");\n expect((await storage.getChat(\"from-telegram\"))?.origin).toBe(\"telegram\");\n\n const web = await storage.createChat({ ...chatInput, id: \"from-web\" });\n expect(web.origin).toBeUndefined();\n const read = await storage.getChat(\"from-web\");\n expect(read).not.toHaveProperty(\"origin\");\n\n const listed = await storage.listChats(chatInput.ownerId);\n expect(listed.find((chat) => chat.id === \"from-telegram\")?.origin).toBe(\"telegram\");\n expect(listed.find((chat) => chat.id === \"from-web\")).not.toHaveProperty(\"origin\");\n\n for (const origin of [\"vk\", \"max\"] as const) {\n const chat = await storage.createChat({ ...chatInput, id: `from-${origin}`, origin });\n expect((await storage.getChat(chat.id))?.origin).toBe(origin);\n }\n\n await storage.updateChatModel(\"from-telegram\", { modelId: \"m\", providerId: \"p\" });\n expect((await storage.getChat(\"from-telegram\"))?.origin).toBe(\"telegram\");\n });\n\n it(\"updateChatModel меняет модель и провайдера чата\", async () => {\n const storage = await storageWithChat();\n await storage.updateChatModel(chatInput.id, { modelId: \"other-model\", providerId: \"fireworks\" });\n expect(await storage.getChat(chatInput.id)).toMatchObject({ modelId: \"other-model\", providerId: \"fireworks\" });\n });\n\n it(\"хранит уровень рассуждений чата: при создании и при смене модели; без него — стирает\", async () => {\n const storage = await createStorage();\n const withLevel = await storage.createChat({ ...chatInput, id: \"with-level\", reasoning: \"high\" });\n expect(withLevel.reasoning).toBe(\"high\");\n expect((await storage.getChat(\"with-level\"))?.reasoning).toBe(\"high\");\n\n const without = await storage.createChat({ ...chatInput, id: \"without-level\" });\n expect(without.reasoning).toBeUndefined();\n expect((await storage.getChat(\"without-level\"))?.reasoning).toBeUndefined();\n\n await storage.updateChatModel(\"without-level\", { modelId: \"m\", providerId: \"p\", reasoning: \"low\" });\n expect(await storage.getChat(\"without-level\")).toMatchObject({ modelId: \"m\", providerId: \"p\", reasoning: \"low\" });\n\n await storage.updateChatModel(\"without-level\", { modelId: \"m\", providerId: \"p\" });\n expect((await storage.getChat(\"without-level\"))?.reasoning).toBeUndefined();\n });\n\n it(\"insertMessage обновляет updatedAt чата\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n expect((await storage.getChat(chatInput.id))?.updatedAt).toBe(\"2099-01-01T00:00:00.000Z\");\n });\n\n it(\"insertMessage в несуществующий чат — отказ, сообщение не записано\", async () => {\n const storage = await storageWithChat();\n await expect(storage.insertMessage({ ...userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"), chatId: \"missing\" })).rejects.toThrow();\n expect(await storage.getMessage(\"u1\")).toBeNull();\n expect(await storage.listMessages(\"missing\")).toEqual([]);\n });\n\n it(\"listMessages отдаёт сообщения чата по времени создания\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u2\", \"2099-01-01T00:00:02.000Z\", \"a1\"));\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n expect((await storage.listMessages(chatInput.id)).map((message) => message.id)).toEqual([\"u1\", \"a1\", \"u2\"]);\n expect(await storage.listMessages(\"missing\")).toEqual([]);\n });\n\n it(\"listMessageLinks отдаёт только id, родителя и время создания, в том же порядке, что listMessages\", async () => {\n const storage = await storageWithChat();\n const sameTime = \"2099-01-01T00:00:02.000Z\";\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.insertMessage(userMessage(\"u3\", sameTime, \"a1\"));\n await storage.insertMessage(userMessage(\"u2\", sameTime, \"a1\"));\n expect(await storage.listMessageLinks(chatInput.id)).toEqual([\n { id: \"u1\", parentId: null, createdAt: \"2099-01-01T00:00:00.000Z\" },\n { id: \"a1\", parentId: \"u1\", createdAt: \"2099-01-01T00:00:01.000Z\" },\n { id: \"u3\", parentId: \"a1\", createdAt: sameTime },\n { id: \"u2\", parentId: \"a1\", createdAt: sameTime },\n ]);\n expect((await storage.listMessageLinks(chatInput.id)).map((link) => link.id)).toEqual(\n (await storage.listMessages(chatInput.id)).map((message) => message.id),\n );\n expect(await storage.listMessageLinks(\"missing\")).toEqual([]);\n });\n\n it(\"listMessagePartsOfTypes отдаёт связи и только части нужных типов, в порядке listMessages\", async (context) => {\n const storage = await storageWithChat();\n if (!storage.listMessagePartsOfTypes) {\n if (options.partsOfTypes === \"required\") throw new Error(\"У хранилища нет listMessagePartsOfTypes\");\n context.skip();\n }\n const sameTime = \"2099-01-01T00:00:02.000Z\";\n const record = { type: \"data-app-state\", data: { set: { \"fields.email\": \"a@x.ru\", $closed: { code: \"done\", message: \"Готово «ок» \\\\ \\\"кавычки\\\"\" } } } };\n const voice = { type: \"data-voice-mode\", data: { voice: \"alloy\" } };\n await storage.insertMessage({ ...userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"), parts: [{ type: \"text\", text: \"вопрос\" }, voice] as StoredMessage[\"parts\"] });\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.updateStreamingMessage(\"a1\", {\n parts: [{ type: \"step-start\" }, record, { type: \"text\", text: \"длинный ответ\", state: \"done\" }, { type: \"data-app-state\", data: { unset: [\"fields.email\"] } }] as StoredMessage[\"parts\"],\n reasoningDurationsMs: {},\n });\n await storage.insertMessage(userMessage(\"u3\", sameTime, \"a1\"));\n await storage.insertMessage({ ...userMessage(\"u2\", sameTime, \"a1\"), parts: [record] as StoredMessage[\"parts\"] });\n expect(await storage.listMessagePartsOfTypes!(chatInput.id, [\"data-app-state\", \"data-voice-mode\"])).toEqual([\n { id: \"u1\", parentId: null, createdAt: \"2099-01-01T00:00:00.000Z\", parts: [voice] },\n { id: \"a1\", parentId: \"u1\", createdAt: \"2099-01-01T00:00:01.000Z\", parts: [record, { type: \"data-app-state\", data: { unset: [\"fields.email\"] } }] },\n { id: \"u3\", parentId: \"a1\", createdAt: sameTime, parts: [] },\n { id: \"u2\", parentId: \"a1\", createdAt: sameTime, parts: [record] },\n ]);\n expect(await storage.listMessagePartsOfTypes!(chatInput.id, [\"data-voice-mode\"])).toMatchObject([{ parts: [voice] }, { parts: [] }, { parts: [] }, { parts: [] }]);\n expect(await storage.listMessagePartsOfTypes!(\"missing\", [\"data-app-state\"])).toEqual([]);\n });\n\n it(\"повтор id в insertMessage — DuplicateMessageError\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await expect(storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:01.000Z\"))).rejects.toBeInstanceOf(\n DuplicateMessageError,\n );\n expect(await storage.listMessages(chatInput.id)).toHaveLength(1);\n });\n\n it(\"части с providerMetadata у рассуждений читаются без изменений\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const parts: StoredMessage[\"parts\"] = [\n { type: \"step-start\" },\n {\n type: \"reasoning\",\n id: \"r1\",\n text: \"думаю о сложении\",\n state: \"done\",\n providerMetadata: { deepseek: { signature: \"штамп-провайдера\", nested: { list: [1, 2, 3] } } },\n },\n { type: \"text\", text: \"42\", state: \"done\" },\n ];\n await storage.updateStreamingMessage(\"a1\", { parts, reasoningDurationsMs: { r1: 1500 } });\n const saved = (await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\");\n expect(saved?.parts).toEqual(parts);\n expect(saved?.reasoningDurationsMs).toEqual({ r1: 1500 });\n expect(saved?.status).toBe(\"streaming\");\n });\n\n it(\"отметка голосового режима в частях сообщения человека переживает запись и чтение\", async () => {\n const storage = await storageWithChat();\n const parts: StoredMessage[\"parts\"] = [\n { type: \"text\", text: \"сказано голосом\" },\n { type: \"data-voice-mode\", data: true },\n ];\n await storage.insertMessage({ ...userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"), parts });\n expect((await storage.getMessage(\"u1\"))?.parts).toEqual(parts);\n expect((await storage.listMessages(chatInput.id)).find((message) => message.id === \"u1\")?.parts).toEqual(parts);\n });\n\n it(\"finishMessage переводит ответ в конечное состояние с итогом\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const usage = { inputTokens: 100, cachedInputTokens: 60, outputTokens: 20, reasoningTokens: 10 };\n await storage.finishMessage(\"a1\", {\n status: \"error\",\n parts: [{ type: \"text\", text: \"часть\", state: \"done\" }],\n usage,\n error: { kind: \"overloaded\" },\n });\n const saved = (await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\");\n expect(saved).toMatchObject({ status: \"error\", usage, error: { kind: \"overloaded\" } });\n expect(saved?.parts).toEqual([{ type: \"text\", text: \"часть\", state: \"done\" }]);\n });\n\n it(\"finishMessage хранит подробности сбоя провайдера (error.details) и отдаёт их как есть\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const error = {\n kind: \"insufficient_funds\" as const,\n details: { providerId: \"openrouter\", modelId: \"m\", statusCode: 403, reason: \"Key limit exceeded\", resetsAt: \"2099-11-01T00:00:00.000Z\" },\n };\n await storage.finishMessage(\"a1\", { status: \"error\", parts: [], usage: null, error });\n expect((await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\")?.error).toEqual(error);\n });\n\n it(\"finishMessage с providerId меняет провайдера ответа, без поля — провайдер прежний\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a2\", \"u1\", \"2099-01-01T00:00:02.000Z\"));\n await storage.finishMessage(\"a1\", { status: \"complete\", providerId: \"fireworks\" });\n await storage.finishMessage(\"a2\", { status: \"complete\" });\n const saved = await storage.listMessages(chatInput.id);\n expect(saved.find((message) => message.id === \"a1\")?.providerId).toBe(\"fireworks\");\n expect((await storage.getMessage(\"a1\"))?.providerId).toBe(\"fireworks\");\n expect(saved.find((message) => message.id === \"a2\")?.providerId).toBe(\"deepseek\");\n });\n\n it(\"сообщение в конечном состоянии не меняется — MessageAlreadyFinishedError\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.finishMessage(\"a1\", { status: \"stopped\" });\n await expect(storage.updateStreamingMessage(\"a1\", { parts: [] })).rejects.toBeInstanceOf(\n MessageAlreadyFinishedError,\n );\n await expect(storage.finishMessage(\"a1\", { status: \"complete\" })).rejects.toBeInstanceOf(\n MessageAlreadyFinishedError,\n );\n await expect(storage.updateStreamingMessage(\"u1\", { parts: [] })).rejects.toBeInstanceOf(\n MessageAlreadyFinishedError,\n );\n const saved = (await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\");\n expect(saved?.status).toBe(\"stopped\");\n });\n\n describe(\"ответ, который ждёт подтверждения\", () => {\n const requested = {\n type: \"tool-remove\",\n toolCallId: \"c1\",\n state: \"approval-requested\",\n input: { path: \"a\" },\n approval: { id: \"ap1\" },\n } as StoredMessage[\"parts\"][number];\n\n async function storageWithAwaitingAnswer(): Promise<ChatStorage> {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.finishMessage(\"a1\", { status: \"awaiting_approval\", parts: [requested] });\n return storage;\n }\n\n const savedAnswer = async (storage: ChatStorage) =>\n (await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\");\n\n it(\"хранится как обычное сообщение и не считается идущим\", async () => {\n const storage = await storageWithAwaitingAnswer();\n expect(await savedAnswer(storage)).toMatchObject({ status: \"awaiting_approval\", parts: [requested] });\n expect(await storage.listStreamingMessageIds()).toEqual([]);\n });\n\n it(\"updateAwaitingMessage меняет части и оставляет ожидание, если статус не указан\", async () => {\n const storage = await storageWithAwaitingAnswer();\n const responded = { ...requested, state: \"approval-responded\", approval: { id: \"ap1\", approved: true } };\n await storage.updateAwaitingMessage(\"a1\", { parts: [responded as StoredMessage[\"parts\"][number]] });\n expect(await savedAnswer(storage)).toMatchObject({ status: \"awaiting_approval\", parts: [responded] });\n });\n\n it(\"updateAwaitingMessage со статусом streaming возвращает ответ в работу, после чего он дописывается и завершается\", async () => {\n const storage = await storageWithAwaitingAnswer();\n await storage.updateAwaitingMessage(\"a1\", { parts: [requested], status: \"streaming\" });\n expect(await storage.listStreamingMessageIds()).toEqual([\"a1\"]);\n await storage.updateStreamingMessage(\"a1\", { parts: [requested, { type: \"text\", text: \"готово\", state: \"done\" }] });\n await storage.finishMessage(\"a1\", { status: \"complete\" });\n expect(await savedAnswer(storage)).toMatchObject({ status: \"complete\" });\n });\n\n it(\"updateAwaitingMessage со статусом complete закрывает ожидание\", async () => {\n const storage = await storageWithAwaitingAnswer();\n await storage.updateAwaitingMessage(\"a1\", { parts: [], status: \"complete\" });\n expect(await savedAnswer(storage)).toMatchObject({ status: \"complete\", parts: [] });\n });\n\n it(\"updateAwaitingMessage с expectedParts пишет, только если части в базе те же (порядок ключей не важен)\", async () => {\n const storage = await storageWithAwaitingAnswer();\n const read = (await savedAnswer(storage))!.parts;\n const reordered = read.map((part) => Object.fromEntries(Object.entries(part).reverse())) as StoredMessage[\"parts\"];\n const responded = { ...requested, state: \"approval-responded\", approval: { id: \"ap1\", approved: true } } as StoredMessage[\"parts\"][number];\n await storage.updateAwaitingMessage(\"a1\", { parts: [responded], expectedParts: reordered });\n expect(await savedAnswer(storage)).toMatchObject({ status: \"awaiting_approval\", parts: [responded] });\n });\n\n it(\"updateAwaitingMessage с expectedParts: части изменились с прочтения — MessageNotAwaitingError, в базе чужая запись\", async () => {\n const storage = await storageWithAwaitingAnswer();\n const read = (await savedAnswer(storage))!.parts;\n const theirs = { ...requested, state: \"approval-responded\", approval: { id: \"ap1\", approved: false } } as StoredMessage[\"parts\"][number];\n const mine = { ...requested, state: \"approval-responded\", approval: { id: \"ap1\", approved: true } } as StoredMessage[\"parts\"][number];\n await storage.updateAwaitingMessage(\"a1\", { parts: [theirs] });\n await expect(storage.updateAwaitingMessage(\"a1\", { parts: [mine], status: \"streaming\", expectedParts: read })).rejects.toBeInstanceOf(\n MessageNotAwaitingError,\n );\n expect(await savedAnswer(storage)).toMatchObject({ status: \"awaiting_approval\", parts: [theirs] });\n });\n\n it(\"не из ожидания — MessageNotAwaitingError; ожидающее не пишется как идущее\", async () => {\n const storage = await storageWithAwaitingAnswer();\n await storage.insertMessage(streamingAnswer(\"a2\", \"u1\", \"2099-01-01T00:00:02.000Z\"));\n await expect(storage.updateAwaitingMessage(\"a2\", { parts: [] })).rejects.toBeInstanceOf(MessageNotAwaitingError);\n await expect(storage.updateAwaitingMessage(\"u1\", { parts: [] })).rejects.toBeInstanceOf(MessageNotAwaitingError);\n await expect(storage.updateAwaitingMessage(\"missing\", { parts: [] })).rejects.toThrow(\"Сообщения missing нет\");\n await expect(storage.updateStreamingMessage(\"a1\", { parts: [] })).rejects.toBeInstanceOf(MessageAlreadyFinishedError);\n });\n });\n\n describe(\"ждущий виджет и несколько копий сервера (SC-002, SC-003)\", () => {\n it(\"служба, созданная заново на том же хранилище, видит ждущий виджет и принимает ответ\", async () => {\n const storage = await createStorage();\n const asking = widgetService(storage);\n const chat = await asking.createChat(\"anna\");\n await drain(await asking.sendMessage(\"anna\", chat.id, widgetQuestion()));\n const restarted = widgetService(storage);\n expect(await restarted.answerWidget({ chatId: chat.id, ownerId: \"anna\", toolCallId: \"w1\", answer: { выбрано: \"Про\" } })).toEqual({ resumed: true });\n await drain((await restarted.subscribe(\"anna\", chat.id))!);\n const answer = (await storage.listMessages(chat.id)).at(-1)!;\n expect(answer.status).toBe(\"complete\");\n expect(answer.parts.find((part) => (part as { toolCallId?: string }).toolCallId === \"w1\")).toMatchObject({ state: \"output-available\", output: { выбрано: \"Про\" } });\n });\n\n it(\"две копии одновременно отвечают на один виджет: принят ровно один ответ, второй — WidgetNotPendingError (20 повторов)\", async () => {\n const storage = await createStorage();\n const [first, second] = [widgetService(storage), widgetService(storage)];\n for (let round = 0; round < 20; round++) {\n const chat = await first.createChat(\"anna\");\n await drain(await first.sendMessage(\"anna\", chat.id, widgetQuestion(`u${round}`)));\n const answers = [\n { service: first, choice: \"Базовый\" },\n { service: second, choice: \"Про\" },\n ];\n const results = await Promise.allSettled(\n answers.map(({ service, choice }) => service.answerWidget({ chatId: chat.id, ownerId: \"anna\", toolCallId: \"w1\", answer: { выбрано: choice } })),\n );\n const accepted = results.flatMap((result, index) => (result.status === \"fulfilled\" ? [answers[index]!] : []));\n expect(accepted).toHaveLength(1);\n expect(results.find((result) => result.status === \"rejected\")).toMatchObject({ reason: expect.any(WidgetNotPendingError) });\n // Ход мог кончиться раньше подписки (`subscribe` → null): тогда ждём записанный ответ.\n const stream = await accepted[0]!.service.subscribe(\"anna\", chat.id);\n if (stream) await drain(stream);\n await vi.waitFor(async () => expect((await storage.listMessages(chat.id)).at(-1)!.status).toBe(\"complete\"));\n const answer = (await storage.listMessages(chat.id)).at(-1)!;\n expect(answer.parts.find((part) => (part as { toolCallId?: string }).toolCallId === \"w1\")).toMatchObject({ output: { выбрано: accepted[0]!.choice } });\n }\n // 20 кругов на встроенной базе: при полном прогоне под нагрузкой 5 с по умолчанию не хватает.\n }, 30_000);\n });\n\n describe(\"правка ответа агента (editAnswer)\", () => {\n async function answeredChat(storage: ChatStorage, lockedToolOutputs?: readonly string[]) {\n const editing = editAnswerService(storage, lockedToolOutputs);\n const chat = await editing.service.createChat(\"anna\");\n await drain(await editing.service.sendMessage(\"anna\", chat.id, { id: \"u1\", role: \"user\", parts: [{ type: \"text\", text: \"найди отчёт\" }] }));\n const answer = (await storage.listMessages(chat.id)).find((message) => message.role === \"assistant\")!;\n return { ...editing, chat, answer };\n }\n const toolPart = (message: StoredMessage, toolCallId: string) =>\n message.parts.find((part) => (part as { toolCallId?: string }).toolCallId === toolCallId);\n\n it(\"новый ответ — сосед прежнего под тем же вопросом и текущая ветка; прежний не тронут; модель не вызывается\", async () => {\n const storage = await createStorage();\n const { service, chat, answer, prompts } = await answeredChat(storage);\n const calls = prompts.length;\n const edited = await service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Отчёт не найден.\", toolOutputs: { f1: \"ничего нет\" } });\n expect(prompts).toHaveLength(calls);\n expect(edited).toMatchObject({ chatId: chat.id, parentId: answer.parentId, role: \"assistant\", status: \"complete\", usage: null, modelId: answer.modelId, providerId: answer.providerId });\n expect(edited.id).not.toBe(answer.id);\n expect(edited.parts.filter((part) => part.type === \"text\")).toEqual([{ type: \"text\", text: \"Отчёт не найден.\", state: \"done\" }]);\n expect(toolPart(edited, \"f1\")).toMatchObject({ state: \"output-available\", output: \"ничего нет\", input: { name: \"отчёт\" } });\n expect(await storage.getMessage(answer.id)).toEqual(answer);\n expect(await storage.getMessage(edited.id)).toEqual(edited);\n expect((await service.getHistory(\"anna\", chat.id)).messages.map((message) => message.id)).toEqual([\"u1\", edited.id]);\n expect((await service.getBranchForks(\"anna\", chat.id)).forks).toEqual([expect.objectContaining({ messageId: edited.id })]);\n });\n\n it(\"следующий вопрос видит правленый ответ и новый результат инструмента\", async () => {\n const storage = await createStorage();\n const { service, chat, answer, prompts } = await answeredChat(storage);\n await service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Отчёт не найден.\", toolOutputs: { f1: \"ничего нет\" } });\n const calls = prompts.length;\n await drain(await service.sendMessage(\"anna\", chat.id, { id: \"u2\", role: \"user\", parts: [{ type: \"text\", text: \"а теперь?\" }] }));\n const sent = JSON.stringify(prompts[calls]);\n expect(sent).toContain(\"Отчёт не найден.\");\n expect(sent).toContain(\"ничего нет\");\n expect(sent).not.toContain(\"Нашёл отчёт.\");\n expect(sent).not.toContain(\"отчёт.pdf\");\n });\n\n it(\"результат инструмента из lockedToolOutputs не правится, текст рядом с ним — правится\", async () => {\n const storage = await createStorage();\n const { service, chat, answer } = await answeredChat(storage, [\"find\"]);\n await expect(service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Новый.\", toolOutputs: { f1: \"ничего\" } })).rejects.toMatchObject({\n kind: \"invalid_tool_output\",\n });\n expect(toolPart(await service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Новый.\" }), \"f1\")).toEqual(toolPart(answer, \"f1\"));\n });\n\n it(\"ошибки правки: kind в AnswerEditError, ничего не записано\", async () => {\n const storage = await createStorage();\n const { service, chat, answer } = await answeredChat(storage);\n const kindOf = (attempt: Promise<unknown>) => attempt.then(() => \"принято\", (error: unknown) => (error instanceof AnswerEditError ? error.kind : error));\n expect(await kindOf(service.editAnswer(\"boris\", chat.id, answer.id, { text: \"Чужое.\" }))).toBe(\"chat_not_found\");\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, \"нет-такого\", { text: \"Новый.\" }))).toBe(\"message_not_found\");\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, \"u1\", { text: \"Новый.\" }))).toBe(\"not_an_answer\");\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, answer.id, { text: \" \" }))).toBe(\"empty_text\");\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Новый.\", toolOutputs: { чужой: 1 } }))).toBe(\"invalid_tool_output\");\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Ищу отчёт.\\n\\nНашёл отчёт.\" }))).toBe(\"nothing_changed\");\n const before = await storage.listMessages(chat.id);\n expect(before).toHaveLength(2);\n await service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Новый.\" });\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, answer.id, { text: \"Ещё новее.\" }))).toBe(\"not_on_current_branch\");\n await storage.insertMessage({ ...streamingAnswer(\"a-broken\", \"u1\", \"2099-01-01T00:00:00.000Z\"), chatId: chat.id });\n await storage.finishMessage(\"a-broken\", { status: \"error\" });\n await service.selectBranch(\"anna\", chat.id, \"a-broken\");\n expect(await kindOf(service.editAnswer(\"anna\", chat.id, \"a-broken\", { text: \"Новый.\" }))).toBe(\"answer_busy\");\n });\n });\n\n it(\"getMessage отдаёт сообщение целиком по id, неизвестного нет\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a9\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n expect(await storage.getMessage(\"a9\")).toMatchObject({ id: \"a9\", chatId: chatInput.id, status: \"streaming\" });\n expect(await storage.getMessage(\"нет-такого\")).toBeNull();\n });\n\n it(\"listStreamingMessageIds возвращает только идущие ответы\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a2\", \"u1\", \"2099-01-01T00:00:02.000Z\"));\n await storage.finishMessage(\"a1\", { status: \"complete\" });\n expect(await storage.listStreamingMessageIds()).toEqual([\"a2\"]);\n });\n\n describe(\"знак жизни идущего ответа (FR-060)\", () => {\n /** Давно: ответ, созданный тогда и без знака жизни, молчит дольше любого порога. */\n const longAgo = (second: number) => `2000-01-01T00:00:${String(second).padStart(2, \"0\")}.000Z`;\n const minute = 60_000;\n const silent = (storage: ChatStorage, filter: { silentForMs: number; chatId?: string }) =>\n storage.listSilentAnswerIds!(filter).then((ids) => ids.sort());\n\n it(\"молчащие ответы: без знака считается время создания; знак «сейчас» делает ответ живым, «брошен» — молчащим сразу\", async (context) => {\n const storage = await storageWithChat();\n if (!storage.listSilentAnswerIds) return context.skip();\n await storage.insertMessage(userMessage(\"u1\", longAgo(0)));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", longAgo(1)));\n await storage.insertMessage({ ...streamingAnswer(\"a2\", \"u1\", longAgo(2)), alive: \"now\" });\n await storage.insertMessage({ ...streamingAnswer(\"a3\", \"u1\", longAgo(3)), alive: \"now\" });\n await storage.updateStreamingMessage(\"a3\", { parts: [], alive: \"released\" });\n expect(await silent(storage, { silentForMs: minute })).toEqual([\"a1\", \"a3\"]);\n expect((await storage.listStreamingMessageIds()).sort()).toEqual([\"a1\", \"a2\", \"a3\"]);\n });\n\n it(\"«сейчас» — по часам хранилища: знак стареет со временем; запись без знака знак не стирает\", async (context) => {\n const storage = await storageWithChat();\n if (!storage.listSilentAnswerIds) return context.skip();\n await storage.insertMessage(userMessage(\"u1\", longAgo(0)));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", longAgo(1)));\n await storage.updateStreamingMessage(\"a1\", { parts: [], alive: \"now\" });\n await storage.updateStreamingMessage(\"a1\", { parts: [{ type: \"text\", text: \"ещё\", state: \"done\" }] });\n expect(await silent(storage, { silentForMs: minute })).toEqual([]);\n await new Promise((resolve) => setTimeout(resolve, 60));\n expect(await silent(storage, { silentForMs: 20 })).toEqual([\"a1\"]);\n });\n\n it(\"только ответы нужного чата, если он задан\", async (context) => {\n const storage = await storageWithChat();\n if (!storage.listSilentAnswerIds) return context.skip();\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n await storage.insertMessage(userMessage(\"u1\", longAgo(0)));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", longAgo(1)));\n await storage.insertMessage({ ...userMessage(\"b1\", longAgo(0)), chatId: \"chat-2\" });\n await storage.insertMessage({ ...streamingAnswer(\"b2\", \"b1\", longAgo(1)), chatId: \"chat-2\" });\n expect(await silent(storage, { silentForMs: minute, chatId: \"chat-2\" })).toEqual([\"b2\"]);\n expect(await silent(storage, { silentForMs: minute })).toEqual([\"a1\", \"b2\"]);\n });\n\n it(\"ответ, вернувшийся в работу после подтверждения, получает знак жизни\", async (context) => {\n const storage = await storageWithChat();\n if (!storage.listSilentAnswerIds) return context.skip();\n await storage.insertMessage(userMessage(\"u1\", longAgo(0)));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", longAgo(1)));\n await storage.finishMessage(\"a1\", { status: \"awaiting_approval\" });\n await storage.updateAwaitingMessage(\"a1\", { parts: [], status: \"streaming\", alive: \"now\" });\n expect(await silent(storage, { silentForMs: minute })).toEqual([]);\n expect(await storage.listStreamingMessageIds()).toEqual([\"a1\"]);\n });\n\n it(\"лёгкая отметка «жив» пишет только знак: части и расход прежние; законченный ответ — MessageAlreadyFinishedError\", async (context) => {\n const storage = await storageWithChat();\n if (!storage.markAnswerAlive || !storage.listSilentAnswerIds) return context.skip();\n await storage.insertMessage(userMessage(\"u1\", longAgo(0)));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", longAgo(1)));\n const parts = [{ type: \"text\" as const, text: \"начало\", state: \"streaming\" as const }];\n const usage = { inputTokens: 10, cachedInputTokens: 0, outputTokens: 2, reasoningTokens: 0 };\n await storage.updateStreamingMessage(\"a1\", { parts, usage });\n await storage.markAnswerAlive(\"a1\");\n expect(await silent(storage, { silentForMs: minute })).toEqual([]);\n expect(await storage.getMessage(\"a1\")).toMatchObject({ parts, usage, status: \"streaming\" });\n await storage.finishMessage(\"a1\", { status: \"interrupted\" });\n await expect(storage.markAnswerAlive(\"a1\")).rejects.toBeInstanceOf(MessageAlreadyFinishedError);\n await expect(storage.markAnswerAlive(\"missing\")).rejects.toThrow(\"Сообщения missing нет\");\n });\n\n it(\"знак жизни не возвращается при чтении\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", longAgo(0)));\n await storage.insertMessage({ ...streamingAnswer(\"a1\", \"u1\", longAgo(1)), alive: \"now\" });\n for (const message of [await storage.getMessage(\"a1\"), (await storage.listMessages(chatInput.id)).find((found) => found.id === \"a1\")]) {\n expect(message).not.toHaveProperty(\"alive\");\n expect(message).not.toHaveProperty(\"aliveAt\");\n }\n });\n });\n\n it(\"сообщения с одинаковым временем создания отдаются в порядке записи\", async () => {\n const storage = await storageWithChat();\n const sameTime = \"2099-01-01T00:00:00.000Z\";\n const ids = [\"m5\", \"m1\", \"m4\", \"m2\", \"m3\"];\n for (const id of ids) await storage.insertMessage(userMessage(id, sameTime));\n expect((await storage.listMessages(chatInput.id)).map((message) => message.id)).toEqual(ids);\n });\n\n it(\"запись в ответ, которого нет, — ошибка «Сообщения … нет»\", async () => {\n const storage = await storageWithChat();\n await expect(storage.updateStreamingMessage(\"missing\", { parts: [] })).rejects.toThrow(\"Сообщения missing нет\");\n await expect(storage.finishMessage(\"missing\", { status: \"complete\" })).rejects.toThrow(\"Сообщения missing нет\");\n });\n\n it(\"чаты не путаются: сообщения и идущие ответы каждого чата свои\", async () => {\n const storage = await storageWithChat();\n await storage.createChat({ ...chatInput, id: \"chat-2\", ownerId: \"boris\" });\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.insertMessage({ ...userMessage(\"b1\", \"2099-01-01T00:00:00.000Z\"), chatId: \"chat-2\" });\n expect((await storage.listMessages(chatInput.id)).map((message) => message.id)).toEqual([\"u1\", \"a1\"]);\n expect((await storage.listMessages(\"chat-2\")).map((message) => message.id)).toEqual([\"b1\"]);\n expect((await storage.getChat(\"chat-2\"))?.ownerId).toBe(\"boris\");\n expect((await storage.getChat(chatInput.id))?.updatedAt).toBe(\"2099-01-01T00:00:01.000Z\");\n expect((await storage.getChat(\"chat-2\"))?.updatedAt).toBe(\"2099-01-01T00:00:00.000Z\");\n expect(await storage.listStreamingMessageIds()).toEqual([\"a1\"]);\n });\n\n it(\"поля без значения возвращаются как null, а пустые рассуждения — как {}\", async () => {\n const storage = await storageWithChat();\n const message = userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\");\n await storage.insertMessage(message);\n const [saved] = await storage.listMessages(chatInput.id);\n expect(saved).toEqual(message);\n expect(saved?.usage).toBeNull();\n expect(saved?.error).toBeNull();\n expect(saved?.modelId).toBeNull();\n expect(saved?.parentId).toBeNull();\n expect(saved?.reasoningDurationsMs).toEqual({});\n });\n\n it(\"очень длинный ответ сохраняется и читается целиком\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const text = \"Длинный ответ, «кавычки», \\\\ обратная косая, эмодзи 🙂. \".repeat(6000);\n await storage.finishMessage(\"a1\", { status: \"complete\", parts: [{ type: \"text\", text, state: \"done\" }] });\n const saved = (await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\");\n expect(saved?.parts).toEqual([{ type: \"text\", text, state: \"done\" }]);\n });\n\n it(\"updateChatModel неизвестного чата ничего не делает\", async () => {\n const storage = await storageWithChat();\n await expect(storage.updateChatModel(\"missing\", { modelId: \"m\", providerId: \"p\" })).resolves.toBeUndefined();\n expect(await storage.getChat(\"missing\")).toBeNull();\n });\n\n it(\"чтение formatVersion больше известной — UnsupportedFormatVersionError, запись не меняется\", async () => {\n const storage = await storageWithChat();\n const fromFuture = { ...userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"), formatVersion: CURRENT_FORMAT_VERSION + 1 };\n await storage.insertMessage(fromFuture);\n await expect(storage.listMessages(chatInput.id)).rejects.toBeInstanceOf(UnsupportedFormatVersionError);\n await expect(storage.listMessages(chatInput.id)).rejects.toBeInstanceOf(UnsupportedFormatVersionError);\n await expect(storage.insertMessage(fromFuture)).rejects.toBeInstanceOf(DuplicateMessageError);\n });\n describe(\"список, название и удаление чатов\", () => {\n it(\"у нового чата названия нет; renameChat пишет и стирает его, updatedAt не меняется\", async () => {\n const storage = await storageWithChat();\n expect((await storage.getChat(chatInput.id))?.title).toBeUndefined();\n const before = (await storage.getChat(chatInput.id))?.updatedAt;\n await storage.renameChat(chatInput.id, \"Отпуск в Греции «2026» 🙂\");\n expect(await storage.getChat(chatInput.id)).toMatchObject({ title: \"Отпуск в Греции «2026» 🙂\", updatedAt: before });\n await storage.renameChat(chatInput.id, null);\n expect((await storage.getChat(chatInput.id))?.title).toBeUndefined();\n });\n\n it(\"renameChat неизвестного чата ничего не делает\", async () => {\n const storage = await storageWithChat();\n await expect(storage.renameChat(\"missing\", \"Название\")).resolves.toBeUndefined();\n expect(await storage.getChat(\"missing\")).toBeNull();\n });\n\n it(\"listChats отдаёт только чаты владельца, самые недавние первыми\", async () => {\n const storage = await createStorage();\n await storage.createChat({ ...chatInput, id: \"old\" });\n await storage.createChat({ ...chatInput, id: \"new\" });\n await storage.createChat({ ...chatInput, id: \"boris-chat\", ownerId: \"boris\" });\n await storage.insertMessage({ ...userMessage(\"m-old\", \"2099-01-01T00:00:01.000Z\"), chatId: \"old\" });\n await storage.insertMessage({ ...userMessage(\"m-new\", \"2099-01-01T00:00:05.000Z\"), chatId: \"new\" });\n await storage.insertMessage({ ...userMessage(\"m-boris\", \"2099-01-01T00:00:09.000Z\"), chatId: \"boris-chat\" });\n expect((await storage.listChats(\"anna\")).map((chat) => chat.id)).toEqual([\"new\", \"old\"]);\n expect((await storage.listChats(\"boris\")).map((chat) => chat.id)).toEqual([\"boris-chat\"]);\n expect(await storage.listChats(\"nobody\")).toEqual([]);\n });\n\n it(\"listChats: переписка поднимает чат, переименование порядок не меняет\", async () => {\n const storage = await createStorage();\n await storage.createChat({ ...chatInput, id: \"first\" });\n await storage.createChat({ ...chatInput, id: \"second\" });\n await storage.insertMessage({ ...userMessage(\"m1\", \"2099-01-01T00:00:01.000Z\"), chatId: \"first\" });\n await storage.insertMessage({ ...userMessage(\"m2\", \"2099-01-01T00:00:02.000Z\"), chatId: \"second\" });\n await storage.renameChat(\"first\", \"Переименован\");\n expect((await storage.listChats(\"anna\")).map((chat) => chat.id)).toEqual([\"second\", \"first\"]);\n await storage.insertMessage({ ...userMessage(\"m3\", \"2099-01-01T00:00:03.000Z\"), chatId: \"first\" });\n expect((await storage.listChats(\"anna\")).map((chat) => chat.id)).toEqual([\"first\", \"second\"]);\n expect((await storage.listChats(\"anna\"))[0]).toMatchObject({ id: \"first\", title: \"Переименован\", ownerId: \"anna\" });\n });\n\n it(\"listChats: при равном времени последнего сообщения — по времени создания, затем по id, новее и больше первыми\", async () => {\n const storage = await createStorage();\n for (const id of [\"b\", \"a\", \"c\", \"d\"]) {\n await storage.createChat({ ...chatInput, id });\n await storage.insertMessage({ ...userMessage(`m-${id}`, \"2099-01-01T00:00:00.000Z\"), chatId: id });\n }\n const listed = await storage.listChats(\"anna\");\n expect(listed).toHaveLength(4);\n const expected = [...listed].sort(\n (left, right) => right.createdAt.localeCompare(left.createdAt) || right.id.localeCompare(left.id),\n );\n expect(listed.map((chat) => chat.id)).toEqual(expected.map((chat) => chat.id));\n expect((await storage.listChats(\"anna\")).map((chat) => chat.id)).toEqual(listed.map((chat) => chat.id));\n });\n\n it(\"deleteChat удаляет чат, сообщения всех веток, записи сжатия и выбор веток; другие чаты целы\", async () => {\n const storage = await storageWithChat();\n await storage.createChat({ ...chatInput, id: \"chat-2\", ownerId: \"boris\" });\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.insertMessage({ ...streamingAnswer(\"a2\", \"u1\", \"2099-01-01T00:00:02.000Z\"), status: \"complete\" });\n await storage.insertCompaction({\n id: \"c1\",\n chatId: chatInput.id,\n fromMessageId: \"u1\",\n throughMessageId: \"a1\",\n summary: \"сводка\",\n summaryTokens: 1,\n modelId: \"m\",\n providerId: \"p\",\n usage: null,\n createdAt: \"2099-01-01T00:00:10.000Z\",\n });\n await storage.insertBranchSelection({ id: \"s1\", chatId: chatInput.id, messageId: \"a2\", selectedAt: \"2099-01-01T00:00:11.000Z\" });\n await storage.insertMessage({ ...userMessage(\"b1\", \"2099-01-01T00:00:00.000Z\"), chatId: \"chat-2\" });\n await storage.insertBranchSelection({ id: \"s2\", chatId: \"chat-2\", messageId: \"b1\", selectedAt: \"2099-01-01T00:00:11.000Z\" });\n await storage.insertCompaction({\n id: \"c2\",\n chatId: \"chat-2\",\n fromMessageId: \"b1\",\n throughMessageId: \"b1\",\n summary: \"чужая сводка\",\n summaryTokens: 1,\n modelId: \"m\",\n providerId: \"p\",\n usage: null,\n createdAt: \"2099-01-01T00:00:10.000Z\",\n });\n\n await storage.deleteChat(chatInput.id);\n\n expect(await storage.getChat(chatInput.id)).toBeNull();\n expect(await storage.listMessages(chatInput.id)).toEqual([]);\n expect(await storage.listMessageLinks(chatInput.id)).toEqual([]);\n expect(await storage.listCompactions(chatInput.id)).toEqual([]);\n expect(await storage.listBranchSelections(chatInput.id)).toEqual([]);\n expect((await storage.listChats(\"anna\")).map((chat) => chat.id)).toEqual([]);\n expect(await storage.listStreamingMessageIds()).toEqual([]);\n expect((await storage.listMessages(\"chat-2\")).map((message) => message.id)).toEqual([\"b1\"]);\n expect((await storage.listCompactions(\"chat-2\")).map((record) => record.id)).toEqual([\"c2\"]);\n expect((await storage.listBranchSelections(\"chat-2\")).map((record) => record.id)).toEqual([\"s2\"]);\n expect(await storage.getChat(\"chat-2\")).not.toBeNull();\n });\n\n it(\"deleteChat неизвестного чата ничего не делает; удалённый id можно занять снова\", async () => {\n const storage = await storageWithChat();\n await expect(storage.deleteChat(\"missing\")).resolves.toBeUndefined();\n expect(await storage.getChat(chatInput.id)).not.toBeNull();\n await storage.deleteChat(chatInput.id);\n await storage.deleteChat(chatInput.id);\n await storage.createChat(chatInput);\n expect(await storage.listMessages(chatInput.id)).toEqual([]);\n });\n\n it(\"после удаления запись в сообщения удалённого чата не появляется тихо: чата нет\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.deleteChat(chatInput.id);\n await expect(storage.updateStreamingMessage(\"a1\", { parts: [] })).rejects.toThrow(\"Сообщения a1 нет\");\n });\n });\n\n describe(\"записи сжатия\", () => {\n function compaction(id: string, extra: Partial<StoredCompaction> = {}): StoredCompaction {\n return {\n id,\n chatId: chatInput.id,\n fromMessageId: \"u1\",\n throughMessageId: \"a1\",\n summary: `## Цель\\nсводка ${id} «в кавычках» 🙂`,\n summaryTokens: 321,\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n usage: { inputTokens: 1000, cachedInputTokens: 800, outputTokens: 400, reasoningTokens: 79, contextTokens: 1400 },\n createdAt: \"2099-01-01T00:00:10.000Z\",\n ...extra,\n };\n }\n\n it(\"insertCompaction и listCompactions возвращают запись как записана; у чата без сжатий — пусто\", async () => {\n const storage = await storageWithChat();\n expect(await storage.listCompactions(chatInput.id)).toEqual([]);\n expect(await storage.listCompactions(\"missing\")).toEqual([]);\n await storage.insertCompaction(compaction(\"c1\"));\n expect(await storage.listCompactions(chatInput.id)).toEqual([compaction(\"c1\")]);\n });\n\n it(\"записи отдаются в порядке добавления, даже при одинаковом или обратном времени\", async () => {\n const storage = await storageWithChat();\n await storage.insertCompaction(compaction(\"c2\", { createdAt: \"2099-01-01T00:00:10.000Z\" }));\n await storage.insertCompaction(compaction(\"c1\", { createdAt: \"2099-01-01T00:00:10.000Z\" }));\n await storage.insertCompaction(compaction(\"c3\", { createdAt: \"2099-01-01T00:00:05.000Z\" }));\n expect((await storage.listCompactions(chatInput.id)).map((record) => record.id)).toEqual([\"c2\", \"c1\", \"c3\"]);\n });\n\n it(\"расход на сжатие может быть пустым\", async () => {\n const storage = await storageWithChat();\n await storage.insertCompaction(compaction(\"c1\", { usage: null }));\n expect((await storage.listCompactions(chatInput.id))[0]?.usage).toBeNull();\n });\n\n it(\"записи чатов не путаются\", async () => {\n const storage = await storageWithChat();\n await storage.createChat({ ...chatInput, id: \"chat-2\", ownerId: \"boris\" });\n await storage.insertCompaction(compaction(\"c1\"));\n await storage.insertCompaction(compaction(\"c2\", { chatId: \"chat-2\" }));\n expect((await storage.listCompactions(chatInput.id)).map((record) => record.id)).toEqual([\"c1\"]);\n expect((await storage.listCompactions(\"chat-2\")).map((record) => record.id)).toEqual([\"c2\"]);\n });\n\n it(\"повтор id записи — ошибка, прежняя запись не меняется\", async () => {\n const storage = await storageWithChat();\n await storage.insertCompaction(compaction(\"c1\"));\n await expect(storage.insertCompaction(compaction(\"c1\", { summary: \"другая\" }))).rejects.toThrow();\n expect(await storage.listCompactions(chatInput.id)).toEqual([compaction(\"c1\")]);\n });\n\n it(\"сжатие не трогает оригиналы сообщений и время обновления чата\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const before = await storage.listMessages(chatInput.id);\n const updatedAt = (await storage.getChat(chatInput.id))?.updatedAt;\n await storage.insertCompaction(compaction(\"c1\"));\n expect(await storage.listMessages(chatInput.id)).toEqual(before);\n expect((await storage.getChat(chatInput.id))?.updatedAt).toBe(updatedAt);\n });\n\n it(\"итог ответа хранит contextTokens\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const usage = { inputTokens: 10, cachedInputTokens: 0, outputTokens: 5, reasoningTokens: 0, contextTokens: 15 };\n await storage.finishMessage(\"a1\", { status: \"complete\", usage });\n expect((await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\")?.usage).toEqual(usage);\n });\n\n it(\"идущий ответ хранит расход хода с пометкой «примерно»\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n const usage = { inputTokens: 300, cachedInputTokens: 0, outputTokens: 40, reasoningTokens: 0, contextTokens: 340, estimated: true as const };\n await storage.updateStreamingMessage(\"a1\", { parts: [], usage });\n expect((await storage.getMessage(\"a1\"))?.usage).toEqual(usage);\n });\n });\n\n describe(\"выбор ветки\", () => {\n function selection(id: string, extra: Partial<StoredBranchSelection> = {}): StoredBranchSelection {\n return { id, chatId: chatInput.id, messageId: \"a1\", selectedAt: \"2099-01-01T00:00:10.000Z\", ...extra };\n }\n\n it(\"insertBranchSelection и listBranchSelections возвращают запись как записана; у чата без выбора — пусто\", async () => {\n const storage = await storageWithChat();\n expect(await storage.listBranchSelections(chatInput.id)).toEqual([]);\n expect(await storage.listBranchSelections(\"missing\")).toEqual([]);\n await storage.insertBranchSelection(selection(\"s1\"));\n expect(await storage.listBranchSelections(chatInput.id)).toEqual([selection(\"s1\")]);\n });\n\n it(\"записи отдаются в порядке добавления, даже при одинаковом или обратном времени\", async () => {\n const storage = await storageWithChat();\n await storage.insertBranchSelection(selection(\"s2\", { selectedAt: \"2099-01-01T00:00:10.000Z\" }));\n await storage.insertBranchSelection(selection(\"s1\", { selectedAt: \"2099-01-01T00:00:10.000Z\" }));\n await storage.insertBranchSelection(selection(\"s3\", { selectedAt: \"2099-01-01T00:00:05.000Z\" }));\n expect((await storage.listBranchSelections(chatInput.id)).map((record) => record.id)).toEqual([\"s2\", \"s1\", \"s3\"]);\n });\n\n it(\"записи чатов не путаются\", async () => {\n const storage = await storageWithChat();\n await storage.createChat({ ...chatInput, id: \"chat-2\", ownerId: \"boris\" });\n await storage.insertBranchSelection(selection(\"s1\"));\n await storage.insertBranchSelection(selection(\"s2\", { chatId: \"chat-2\" }));\n expect((await storage.listBranchSelections(chatInput.id)).map((record) => record.id)).toEqual([\"s1\"]);\n expect((await storage.listBranchSelections(\"chat-2\")).map((record) => record.id)).toEqual([\"s2\"]);\n });\n\n it(\"повтор id записи — ошибка, прежняя запись не меняется\", async () => {\n const storage = await storageWithChat();\n await storage.insertBranchSelection(selection(\"s1\"));\n await expect(storage.insertBranchSelection(selection(\"s1\", { messageId: \"другое\" }))).rejects.toThrow();\n expect(await storage.listBranchSelections(chatInput.id)).toEqual([selection(\"s1\")]);\n });\n\n it(\"выбор не меняет ни сообщения, ни записи сжатия, ни время обновления чата\", async () => {\n const storage = await storageWithChat();\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.insertCompaction({\n id: \"c1\",\n chatId: chatInput.id,\n fromMessageId: \"u1\",\n throughMessageId: \"a1\",\n summary: \"сводка\",\n summaryTokens: 5,\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n usage: null,\n createdAt: \"2099-01-01T00:00:05.000Z\",\n });\n const messagesBefore = await storage.listMessages(chatInput.id);\n const compactionsBefore = await storage.listCompactions(chatInput.id);\n const updatedAt = (await storage.getChat(chatInput.id))?.updatedAt;\n await storage.insertBranchSelection(selection(\"s1\"));\n expect(await storage.listMessages(chatInput.id)).toEqual(messagesBefore);\n expect(await storage.listCompactions(chatInput.id)).toEqual(compactionsBefore);\n expect((await storage.getChat(chatInput.id))?.updatedAt).toBe(updatedAt);\n });\n });\n describe(\"записи расхода\", () => {\n function usageRecord(id: string, fields: Partial<UsageRecord> = {}): UsageRecord {\n return {\n id,\n ownerId: \"anna\",\n chatId: chatInput.id,\n messageId: `a-${id}`,\n source: \"answer\",\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n inputTokens: 1000,\n cachedInputTokens: 400,\n cacheWriteTokens: 0,\n outputTokens: 200,\n reasoningTokens: 50,\n costUsd: 0.25,\n createdAt: \"2099-01-15T10:00:00.000Z\",\n ...fields,\n };\n }\n\n it(\"пустой расход — пустая сумма\", async () => {\n const storage = await storageWithChat();\n expect(await storage.sumUsage({ ownerId: \"anna\" })).toEqual([]);\n });\n\n it(\"суммирует токены записей одной пары «модель × провайдер»\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\"));\n await storage.insertUsageRecord(usageRecord(\"r2\", { inputTokens: 500, cacheWriteTokens: 30, source: \"compaction\", messageId: null }));\n expect(await storage.sumUsage({ ownerId: \"anna\" })).toEqual([\n {\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n inputTokens: 1500,\n cachedInputTokens: 800,\n cacheWriteTokens: 30,\n outputTokens: 400,\n reasoningTokens: 100,\n costUsd: 0.5,\n },\n ]);\n });\n\n it(\"запись «примерно» принимается и считается в сумме вместе с остальными\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\"));\n await storage.insertUsageRecord(usageRecord(\"r2\", { estimated: true, inputTokens: 300 }));\n expect((await storage.sumUsage({ ownerId: \"anna\" }))[0]?.inputTokens).toBe(1300);\n });\n\n it(\"деньги суммируются из записей: цена на момент расхода, а не пересчёт по токенам\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\", { costUsd: 0.1 }));\n await storage.insertUsageRecord(usageRecord(\"r2\", { costUsd: 0.2, inputTokens: 0, outputTokens: 0 }));\n await storage.insertUsageRecord(usageRecord(\"r3\", { costUsd: 0 }));\n const [sum] = await storage.sumUsage({ ownerId: \"anna\" });\n expect(sum?.costUsd).toBeCloseTo(0.3, 12);\n });\n\n it(\"разные пары «модель × провайдер» суммируются отдельно\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\"));\n await storage.insertUsageRecord(usageRecord(\"r2\", { providerId: \"openrouter\" }));\n const sums = await storage.sumUsage({ ownerId: \"anna\" });\n expect(sums.map((sum) => sum.providerId).sort()).toEqual([\"deepseek\", \"openrouter\"]);\n });\n\n it(\"фильтр по владельцу и по чату\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\"));\n await storage.insertUsageRecord(usageRecord(\"r2\", { chatId: \"chat-2\", outputTokens: 7 }));\n await storage.insertUsageRecord(usageRecord(\"r3\", { ownerId: \"boris\", chatId: \"chat-3\", outputTokens: 11 }));\n expect((await storage.sumUsage({ ownerId: \"anna\" }))[0]?.outputTokens).toBe(207);\n expect((await storage.sumUsage({ chatId: \"chat-2\" }))[0]?.outputTokens).toBe(7);\n expect((await storage.sumUsage({ ownerId: \"boris\" }))[0]?.outputTokens).toBe(11);\n expect((await storage.sumUsage({ ownerId: \"anna\", chatId: \"chat-3\" }))).toEqual([]);\n expect(await storage.sumUsage({ ownerId: \"nobody\" })).toEqual([]);\n });\n\n it(\"фильтр по сообщению и источнику: только расход ответа этого сообщения\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\", { messageId: \"m1\", outputTokens: 1 }));\n await storage.insertUsageRecord(usageRecord(\"r2\", { messageId: \"m1\", outputTokens: 10 }));\n await storage.insertUsageRecord(usageRecord(\"r3\", { messageId: \"m2\", outputTokens: 100 }));\n await storage.insertUsageRecord(usageRecord(\"r4\", { messageId: \"m1\", source: \"speech\", outputTokens: 1000 }));\n expect((await storage.sumUsage({ chatId: \"chat-1\", messageId: \"m1\", source: \"answer\" }))[0]?.outputTokens).toBe(11);\n expect((await storage.sumUsage({ messageId: \"m1\" }))[0]?.outputTokens).toBe(1011);\n expect(await storage.sumUsage({ messageId: \"m3\" })).toEqual([]);\n });\n\n it(\"«since» включает границу и отсекает более раннее\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\", { createdAt: \"2099-01-31T23:59:59.999Z\", outputTokens: 1 }));\n await storage.insertUsageRecord(usageRecord(\"r2\", { createdAt: \"2099-02-01T00:00:00.000Z\", outputTokens: 10 }));\n await storage.insertUsageRecord(usageRecord(\"r3\", { createdAt: \"2099-02-10T00:00:00.000Z\", outputTokens: 100 }));\n expect((await storage.sumUsage({ ownerId: \"anna\", since: \"2099-02-01T00:00:00.000Z\" }))[0]?.outputTokens).toBe(110);\n expect((await storage.sumUsage({ ownerId: \"anna\" }))[0]?.outputTokens).toBe(111);\n });\n\n it(\"повтор id — ошибка, сумма не меняется\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(usageRecord(\"r1\"));\n await expect(storage.insertUsageRecord(usageRecord(\"r1\", { outputTokens: 999 }))).rejects.toThrow();\n expect((await storage.sumUsage({ ownerId: \"anna\" }))[0]?.outputTokens).toBe(200);\n });\n\n it(\"поиск записи расхода по id: есть — true, нет — false\", async (context) => {\n const storage = await createStorage();\n if (!storage.hasUsageRecord) return context.skip();\n expect(await storage.hasUsageRecord(\"r1\")).toBe(false);\n await storage.insertUsageRecord(usageRecord(\"r1\", { chatId: \"deleted-chat\" }));\n expect(await storage.hasUsageRecord(\"r1\")).toBe(true);\n expect(await storage.hasUsageRecord(\"r2\")).toBe(false);\n });\n\n it(\"запись не требует чата и не меняет время его обновления\", async () => {\n const storage = await createStorage();\n await storage.insertUsageRecord(usageRecord(\"r1\", { chatId: \"deleted-chat\" }));\n expect((await storage.sumUsage({ chatId: \"deleted-chat\" }))[0]?.inputTokens).toBe(1000);\n await storage.createChat(chatInput);\n const updatedAt = (await storage.getChat(chatInput.id))?.updatedAt;\n await storage.insertUsageRecord(usageRecord(\"r2\"));\n expect((await storage.getChat(chatInput.id))?.updatedAt).toBe(updatedAt);\n });\n\n it(\"десять записей одновременно дают точную сумму\", async () => {\n const storage = await storageWithChat();\n await Promise.all(Array.from({ length: 10 }, (_, index) => storage.insertUsageRecord(usageRecord(`p${index}`, { outputTokens: 3 }))));\n expect((await storage.sumUsage({ ownerId: \"anna\" }))[0]?.outputTokens).toBe(30);\n });\n\n describe(\"сумма по списку чатов (sumUsageByChat, необязательный)\", () => {\n async function storageWithUsageByChat(context: { skip: () => never }) {\n const storage = await createStorage();\n if (!storage.sumUsageByChat) {\n if (options.usageByChat === \"required\") throw new Error(\"У хранилища нет sumUsageByChat\");\n context.skip();\n }\n return storage as ChatStorage & Required<Pick<ChatStorage, \"sumUsageByChat\">>;\n }\n const byChat = <T extends { chatId: string; modelId: string }>(sums: T[]) =>\n [...sums].sort((left, right) => `${left.chatId}:${left.modelId}`.localeCompare(`${right.chatId}:${right.modelId}`));\n\n it(\"по чату и паре «модель × провайдер»; чужие чаты из списка не попадают, чаты без записей — тоже\", async (context) => {\n const storage = await storageWithUsageByChat(context);\n await storage.insertUsageRecord(usageRecord(\"r1\", { chatId: \"chat-1\" }));\n await storage.insertUsageRecord(usageRecord(\"r2\", { chatId: \"chat-1\", outputTokens: 5, costUsd: 0.5 }));\n await storage.insertUsageRecord(usageRecord(\"r3\", { chatId: \"chat-1\", modelId: \"gpt-x\", providerId: \"openai\", outputTokens: 7 }));\n await storage.insertUsageRecord(usageRecord(\"r4\", { chatId: \"chat-2\", outputTokens: 11 }));\n await storage.insertUsageRecord(usageRecord(\"r5\", { chatId: \"chat-3\", outputTokens: 13 }));\n const sums = byChat(await storage.sumUsageByChat({ chatIds: [\"chat-1\", \"chat-2\", \"chat-empty\"] }));\n expect(sums.map(({ chatId, modelId, outputTokens }) => [chatId, modelId, outputTokens])).toEqual([\n [\"chat-1\", \"deepseek-4.1-flash\", 205],\n [\"chat-1\", \"gpt-x\", 7],\n [\"chat-2\", \"deepseek-4.1-flash\", 11],\n ]);\n expect(sums[0]).toEqual({\n chatId: \"chat-1\",\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n inputTokens: 2000,\n cachedInputTokens: 800,\n cacheWriteTokens: 0,\n outputTokens: 205,\n reasoningTokens: 100,\n costUsd: 0.75,\n });\n });\n\n it(\"фильтры source, ownerId и since; пустой список — пустая сумма\", async (context) => {\n const storage = await storageWithUsageByChat(context);\n await storage.insertUsageRecord(usageRecord(\"r1\", { chatId: \"chat-1\", source: \"first_message\", outputTokens: 3 }));\n await storage.insertUsageRecord(usageRecord(\"r2\", { chatId: \"chat-1\", outputTokens: 5, createdAt: \"2099-03-01T00:00:00.000Z\" }));\n await storage.insertUsageRecord(usageRecord(\"r3\", { chatId: \"chat-2\", ownerId: \"boris\", source: \"first_message\", outputTokens: 7 }));\n const outputs = async (filter: Parameters<typeof storage.sumUsageByChat>[0]) =>\n byChat(await storage.sumUsageByChat(filter)).map(({ chatId, outputTokens }) => [chatId, outputTokens]);\n expect(await outputs({ chatIds: [\"chat-1\", \"chat-2\"], source: \"first_message\" })).toEqual([[\"chat-1\", 3], [\"chat-2\", 7]]);\n expect(await outputs({ chatIds: [\"chat-1\", \"chat-2\"], ownerId: \"anna\" })).toEqual([[\"chat-1\", 8]]);\n expect(await outputs({ chatIds: [\"chat-1\", \"chat-2\"], since: \"2099-02-01T00:00:00.000Z\" })).toEqual([[\"chat-1\", 5]]);\n expect(await storage.sumUsageByChat({ chatIds: [] })).toEqual([]);\n });\n });\n });\n\n describe(\"озвучка в расходах (source: speech)\", () => {\n function speechRecord(id: string, fields: Partial<UsageRecord> = {}): UsageRecord {\n return {\n id,\n ownerId: \"anna\",\n chatId: chatInput.id,\n messageId: `a-${id}`,\n source: \"speech\",\n modelId: \"eleven_v4_turbo\",\n providerId: \"elevenlabs\",\n inputTokens: 200,\n cachedInputTokens: 0,\n cacheWriteTokens: 0,\n outputTokens: 0,\n reasoningTokens: 0,\n costUsd: 0.012,\n createdAt: \"2099-01-15T10:00:00.000Z\",\n ...fields,\n };\n }\n\n it(\"запись озвучки сохраняется и суммируется отдельной парой «модель × провайдер»\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(speechRecord(\"s1\"));\n await storage.insertUsageRecord(speechRecord(\"s2\", { inputTokens: 300, costUsd: 0.018 }));\n const [sum] = await storage.sumUsage({ ownerId: \"anna\" });\n expect(sum).toMatchObject({ modelId: \"eleven_v4_turbo\", providerId: \"elevenlabs\", inputTokens: 500, outputTokens: 0 });\n expect(sum!.costUsd).toBeCloseTo(0.03, 10);\n });\n\n it(\"озвучка приближает лимит: сумма денег включает и ответы, и озвучку\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord({\n id: \"answer-1\",\n ownerId: \"anna\",\n chatId: chatInput.id,\n messageId: \"a-1\",\n source: \"answer\",\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n inputTokens: 1000,\n cachedInputTokens: 0,\n cacheWriteTokens: 0,\n outputTokens: 100,\n reasoningTokens: 0,\n costUsd: 0.25,\n createdAt: \"2099-01-15T09:00:00.000Z\",\n });\n const before = (await storage.sumUsage({ ownerId: \"anna\" })).reduce((total, sum) => total + sum.costUsd, 0);\n await storage.insertUsageRecord(speechRecord(\"s1\", { costUsd: 0.1 }));\n const after = (await storage.sumUsage({ ownerId: \"anna\" })).reduce((total, sum) => total + sum.costUsd, 0);\n expect(after - before).toBeCloseTo(0.1, 10);\n });\n\n it(\"озвучка чужого человека в сумму не попадает\", async () => {\n const storage = await storageWithChat();\n await storage.insertUsageRecord(speechRecord(\"s1\", { ownerId: \"boris\" }));\n expect(await storage.sumUsage({ ownerId: \"anna\" })).toEqual([]);\n });\n });\n\n describe(\"чаты объектов (необязательные методы)\", () => {\n type SubjectStorage = ChatStorage & Required<Pick<ChatStorage, \"findChatBySubject\">>;\n\n /** Хранилище без `findChatBySubject` договор не нарушает: ядро тогда не включает чаты объектов и говорит об этом при старте. */\n async function subjectStorage(context: { skip: () => never }): Promise<SubjectStorage> {\n const storage = await createStorage();\n if (!storage.findChatBySubject) {\n if (options.subjectChats === \"required\") throw new Error(\"У хранилища нет чатов объектов\");\n context.skip();\n }\n return storage as SubjectStorage;\n }\n\n const lessonData = { lesson: { id: 7, title: \"Дроби\", tags: [\"математика\", \"5 класс\"] }, open: true, score: null };\n\n it(\"ключ и данные объекта пишутся и читаются; чат без ключа — без этих полей\", async (context) => {\n const storage = await subjectStorage(context);\n const created = await storage.createChat({ ...chatInput, id: \"lesson-chat\", subjectKey: \"lesson:7\", subjectData: lessonData });\n expect(created).toMatchObject({ subjectKey: \"lesson:7\", subjectData: lessonData });\n expect(await storage.getChat(\"lesson-chat\")).toMatchObject({ subjectKey: \"lesson:7\", subjectData: lessonData });\n\n await storage.createChat({ ...chatInput, id: \"plain\" });\n const plain = await storage.getChat(\"plain\");\n expect(plain).not.toHaveProperty(\"subjectKey\");\n expect(plain).not.toHaveProperty(\"subjectData\");\n });\n\n it(\"ключ без данных: subjectData нет\", async (context) => {\n const storage = await subjectStorage(context);\n await storage.createChat({ ...chatInput, id: \"lesson-chat\", subjectKey: \"lesson:7\" });\n const chat = await storage.getChat(\"lesson-chat\");\n expect(chat?.subjectKey).toBe(\"lesson:7\");\n expect(chat).not.toHaveProperty(\"subjectData\");\n });\n\n it(\"findChatBySubject находит чат владельца по ключу; чужой владелец и неизвестный ключ — null\", async (context) => {\n const storage = await subjectStorage(context);\n await storage.createChat({ ...chatInput, id: \"lesson-chat\", subjectKey: \"lesson:7\", subjectData: lessonData });\n expect(await storage.findChatBySubject(chatInput.ownerId, \"lesson:7\")).toMatchObject({ id: \"lesson-chat\", subjectData: lessonData });\n expect(await storage.findChatBySubject(\"boris\", \"lesson:7\")).toBeNull();\n expect(await storage.findChatBySubject(chatInput.ownerId, \"lesson:8\")).toBeNull();\n });\n\n it(\"повтор ключа у того же владельца — DuplicateChatSubjectError, второй чат не записан; у другого владельца — можно\", async (context) => {\n const storage = await subjectStorage(context);\n await storage.createChat({ ...chatInput, id: \"first\", subjectKey: \"lesson:7\" });\n await expect(storage.createChat({ ...chatInput, id: \"second\", subjectKey: \"lesson:7\" })).rejects.toBeInstanceOf(DuplicateChatSubjectError);\n expect(await storage.getChat(\"second\")).toBeNull();\n expect((await storage.findChatBySubject(chatInput.ownerId, \"lesson:7\"))?.id).toBe(\"first\");\n\n await storage.createChat({ ...chatInput, id: \"boris-chat\", ownerId: \"boris\", subjectKey: \"lesson:7\" });\n expect((await storage.findChatBySubject(\"boris\", \"lesson:7\"))?.id).toBe(\"boris-chat\");\n });\n\n it(\"чатов без ключа у владельца может быть сколько угодно\", async (context) => {\n const storage = await subjectStorage(context);\n for (const id of [\"a\", \"b\", \"c\"]) await storage.createChat({ ...chatInput, id });\n expect(await storage.listChats(chatInput.ownerId)).toHaveLength(3);\n });\n\n it(\"удаление чата освобождает ключ\", async (context) => {\n const storage = await subjectStorage(context);\n await storage.createChat({ ...chatInput, id: \"first\", subjectKey: \"lesson:7\" });\n await storage.deleteChat(\"first\");\n expect(await storage.findChatBySubject(chatInput.ownerId, \"lesson:7\")).toBeNull();\n await storage.createChat({ ...chatInput, id: \"again\", subjectKey: \"lesson:7\" });\n expect((await storage.findChatBySubject(chatInput.ownerId, \"lesson:7\"))?.id).toBe(\"again\");\n });\n\n it(\"listChats: по умолчанию и с exclude — без чатов с ключом; include — все; only — только с ключом; порядок прежний\", async (context) => {\n const storage = await subjectStorage(context);\n await storage.createChat({ ...chatInput, id: \"plain-old\" });\n await storage.createChat({ ...chatInput, id: \"lesson-old\", subjectKey: \"lesson:1\" });\n await storage.createChat({ ...chatInput, id: \"plain-new\" });\n await storage.createChat({ ...chatInput, id: \"lesson-new\", subjectKey: \"lesson:2\" });\n await storage.createChat({ ...chatInput, id: \"boris-lesson\", ownerId: \"boris\", subjectKey: \"lesson:1\" });\n const touch = async (chatId: string, at: string) => storage.insertMessage({ ...userMessage(`m-${chatId}`, at), chatId });\n await touch(\"plain-old\", \"2099-01-01T00:00:01.000Z\");\n await touch(\"lesson-old\", \"2099-01-01T00:00:02.000Z\");\n await touch(\"plain-new\", \"2099-01-01T00:00:03.000Z\");\n await touch(\"lesson-new\", \"2099-01-01T00:00:04.000Z\");\n\n const ids = async (subjects?: \"exclude\" | \"include\" | \"only\") =>\n (await storage.listChats(chatInput.ownerId, subjects ? { subjects } : undefined)).map((chat) => chat.id);\n expect(await ids()).toEqual([\"plain-new\", \"plain-old\"]);\n expect(await ids(\"exclude\")).toEqual([\"plain-new\", \"plain-old\"]);\n expect(await ids(\"include\")).toEqual([\"lesson-new\", \"plain-new\", \"lesson-old\", \"plain-old\"]);\n expect(await ids(\"only\")).toEqual([\"lesson-new\", \"lesson-old\"]);\n expect((await storage.listChats(chatInput.ownerId, { subjects: \"only\" }))[0]?.subjectKey).toBe(\"lesson:2\");\n });\n\n it(\"createChat с названием и датой: дата создания и обновления — заданная, название — заданное\", async (context) => {\n const storage = await subjectStorage(context);\n const createdAt = \"2024-03-05T10:20:30.000Z\";\n const created = await storage.createChat({ ...chatInput, id: \"dated\", title: \"Урок 7. Дроби\", createdAt });\n expect(created).toMatchObject({ title: \"Урок 7. Дроби\", createdAt, updatedAt: createdAt });\n expect(await storage.getChat(\"dated\")).toMatchObject({ title: \"Урок 7. Дроби\", createdAt, updatedAt: createdAt });\n });\n\n it(\"данные объекта — копия: правка отданного объекта хранилище не меняет\", async (context) => {\n const storage = await subjectStorage(context);\n const data = structuredClone(lessonData);\n await storage.createChat({ ...chatInput, id: \"lesson-chat\", subjectKey: \"lesson:7\", subjectData: data });\n data.lesson.tags.push(\"лишнее\");\n const read = await storage.getChat(\"lesson-chat\");\n (read?.subjectData as typeof lessonData).lesson.tags.push(\"ещё\");\n expect((await storage.getChat(\"lesson-chat\"))?.subjectData).toEqual(lessonData);\n });\n });\n\n describe(\"данные чата (data, updateChatData, фильтр data в listChats; необязательные)\", () => {\n type ChatDataStorage = ChatStorage & Required<Pick<ChatStorage, \"updateChatData\">>;\n\n /** Хранилище без `updateChatData` договор не нарушает: ядро тогда данных чата не обещает. */\n async function chatDataStorage(context: { skip: () => never }): Promise<ChatDataStorage> {\n const storage = await createStorage();\n if (!storage.updateChatData) {\n if (options.chatData === \"required\") throw new Error(\"У хранилища нет данных чата\");\n context.skip();\n }\n return storage as ChatDataStorage;\n }\n\n const maxBytes = 16 * 1024;\n const formData = { formId: \"f1\", mode: \"test\", attempts: 3, vip: true, utm: { campaign: \"autumn\" } };\n\n it(\"data у обычного чата пишется и читается; subjectData — тот же объект; чат без данных — без обоих полей\", async (context) => {\n const storage = await chatDataStorage(context);\n const created = await storage.createChat({ ...chatInput, id: \"with-data\", data: formData });\n expect(created).toMatchObject({ data: formData, subjectData: formData });\n expect(created).not.toHaveProperty(\"subjectKey\");\n expect(await storage.getChat(\"with-data\")).toMatchObject({ data: formData, subjectData: formData });\n\n await storage.createChat({ ...chatInput, id: \"plain\" });\n const plain = await storage.getChat(\"plain\");\n expect(plain).not.toHaveProperty(\"data\");\n expect(plain).not.toHaveProperty(\"subjectData\");\n });\n\n it(\"старый код: subjectData на входе читается и как data\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"old-style\", subjectKey: \"lesson:7\", subjectData: formData });\n expect(await storage.getChat(\"old-style\")).toMatchObject({ data: formData, subjectData: formData });\n });\n\n it(\"data — копия: правка отданного и прочитанного объекта хранилище не меняет\", async (context) => {\n const storage = await chatDataStorage(context);\n const data = structuredClone(formData);\n await storage.createChat({ ...chatInput, id: \"copy\", data });\n data.utm.campaign = \"правка\";\n const read = await storage.getChat(\"copy\");\n (read?.data as typeof formData).utm.campaign = \"ещё правка\";\n expect((await storage.getChat(\"copy\"))?.data).toEqual(formData);\n });\n\n it(\"updateChatData сливает верхние ключи: новые добавляются, старые заменяются целиком, прочие остаются\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"merge\", data: formData });\n const updated = await storage.updateChatData(\"merge\", { mode: \"live\", utm: { source: \"tg\" }, extra: [1, 2] }, { maxBytes });\n const expected = { formId: \"f1\", mode: \"live\", attempts: 3, vip: true, utm: { source: \"tg\" }, extra: [1, 2] };\n expect(updated).toMatchObject({ id: \"merge\", data: expected, subjectData: expected });\n expect((await storage.getChat(\"merge\"))?.data).toEqual(expected);\n });\n\n it(\"updateChatData у чата без данных создаёт их\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"empty\" });\n await storage.updateChatData(\"empty\", { source: \"telegram\" }, { maxBytes });\n expect((await storage.getChat(\"empty\"))?.data).toEqual({ source: \"telegram\" });\n });\n\n it(\"ключ со значением undefined удаляется; null остаётся значением; не осталось ключей — данных нет\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"drop\", data: { a: 1, b: 2 } });\n await storage.updateChatData(\"drop\", { a: undefined, c: null }, { maxBytes });\n expect((await storage.getChat(\"drop\"))?.data).toEqual({ b: 2, c: null });\n await storage.updateChatData(\"drop\", { b: undefined, c: undefined }, { maxBytes });\n const emptied = await storage.getChat(\"drop\");\n expect(emptied).not.toHaveProperty(\"data\");\n expect(emptied).not.toHaveProperty(\"subjectData\");\n });\n\n it(\"updateChatData: нет такого чата — null; дата обновления чата не меняется\", async (context) => {\n const storage = await chatDataStorage(context);\n expect(await storage.updateChatData(\"missing\", { a: 1 }, { maxBytes })).toBeNull();\n const created = await storage.createChat({ ...chatInput, id: \"stay\", createdAt: \"2024-01-01T00:00:00.000Z\" });\n await storage.updateChatData(\"stay\", { a: 1 }, { maxBytes });\n expect((await storage.getChat(\"stay\"))?.updatedAt).toBe(created.updatedAt);\n });\n\n it(\"итог больше предела — ChatDataTooLargeError, данные не изменены\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"big\", data: { keep: \"x\".repeat(60) } });\n await expect(storage.updateChatData(\"big\", { more: \"y\".repeat(60) }, { maxBytes: 100 })).rejects.toBeInstanceOf(ChatDataTooLargeError);\n expect((await storage.getChat(\"big\"))?.data).toEqual({ keep: \"x\".repeat(60) });\n });\n\n it(\"ключ __proto__ в правке или в фильтре — TypeError, данные не изменены: молча он не теряется\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"proto\", data: { keep: 1 } });\n const withProto = JSON.parse('{\"__proto__\":{\"admin\":true},\"other\":2}') as Record<string, unknown>;\n await expect(storage.updateChatData(\"proto\", withProto, { maxBytes })).rejects.toBeInstanceOf(TypeError);\n expect((await storage.getChat(\"proto\"))?.data).toEqual({ keep: 1 });\n await expect(storage.listChats(chatInput.ownerId, { data: JSON.parse('{\"__proto__\":1}') as never })).rejects.toBeInstanceOf(TypeError);\n });\n\n it(\"символ NUL (\\\\u0000) в ключе или значении правки и фильтра — TypeError, данные не изменены, список цел\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"nul\", data: { keep: 1 } });\n await expect(storage.updateChatData(\"nul\", { note: \"a\\u0000b\" }, { maxBytes })).rejects.toBeInstanceOf(TypeError);\n await expect(storage.updateChatData(\"nul\", { nested: { [\"k\\u0000\"]: 1 } }, { maxBytes })).rejects.toBeInstanceOf(TypeError);\n await expect(storage.updateChatData(\"nul\", { list: [\"ok\", \"\\u0000\"] }, { maxBytes })).rejects.toBeInstanceOf(TypeError);\n expect((await storage.getChat(\"nul\"))?.data).toEqual({ keep: 1 });\n await expect(storage.listChats(chatInput.ownerId, { data: { keep: \"\\u0000\" } })).rejects.toBeInstanceOf(TypeError);\n await expect(storage.listChats(chatInput.ownerId, { data: { [\"k\\u0000\"]: 1 } })).rejects.toBeInstanceOf(TypeError);\n expect((await storage.listChats(chatInput.ownerId, { data: { keep: 1 } })).map((chat) => chat.id)).toEqual([\"nul\"]);\n });\n\n it(\"одновременные правки разных ключей не затирают друг друга\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"race\", data: { start: true } });\n await Promise.all(Array.from({ length: 10 }, (_, index) => storage.updateChatData(\"race\", { [`key${index}`]: index }, { maxBytes })));\n const data = (await storage.getChat(\"race\"))?.data as Record<string, unknown>;\n expect(Object.keys(data).sort()).toEqual([\"start\", ...Array.from({ length: 10 }, (_, index) => `key${index}`)].sort());\n });\n\n describe(\"фильтр data в listChats\", () => {\n async function filled(context: { skip: () => never }) {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"test-1\", createdAt: \"2024-01-01T00:00:00.000Z\", data: { formId: \"f1\", mode: \"test\", n: 1, flag: true, none: null } });\n await storage.createChat({ ...chatInput, id: \"test-2\", createdAt: \"2024-01-02T00:00:00.000Z\", data: { formId: \"f1\", mode: \"test\", n: 2, flag: false } });\n await storage.createChat({ ...chatInput, id: \"live-1\", createdAt: \"2024-01-03T00:00:00.000Z\", data: { formId: \"f1\", mode: \"live\" } });\n await storage.createChat({ ...chatInput, id: \"other-form\", createdAt: \"2024-01-04T00:00:00.000Z\", data: { formId: \"f2\", mode: \"test\" } });\n await storage.createChat({ ...chatInput, id: \"no-data\", createdAt: \"2024-01-05T00:00:00.000Z\" });\n await storage.createChat({ ...chatInput, id: \"boris-test\", ownerId: \"boris\", createdAt: \"2024-01-06T00:00:00.000Z\", data: { formId: \"f1\", mode: \"test\" } });\n const ids = async (data: ChatDataFilter, extra: { subjects?: \"include\" | \"only\" | \"exclude\" } = {}) =>\n (await storage.listChats(chatInput.ownerId, { data, ...extra })).map((chat) => chat.id);\n return { storage, ids };\n }\n\n it(\"равенство одного ключа; чат без данных и чужой владелец не попадают; порядок обычный\", async (context) => {\n const { ids } = await filled(context);\n expect(await ids({ formId: \"f1\" })).toEqual([\"live-1\", \"test-2\", \"test-1\"]);\n expect(await ids({ mode: \"test\" })).toEqual([\"other-form\", \"test-2\", \"test-1\"]);\n });\n\n it(\"несколько ключей — все должны совпасть\", async (context) => {\n const { ids } = await filled(context);\n expect(await ids({ formId: \"f1\", mode: \"test\" })).toEqual([\"test-2\", \"test-1\"]);\n expect(await ids({ formId: \"f2\", mode: \"live\" })).toEqual([]);\n });\n\n it(\"тип значения важен: число не равно строке, true не равно 1, null не равен отсутствию ключа\", async (context) => {\n const { ids } = await filled(context);\n expect(await ids({ n: 1 })).toEqual([\"test-1\"]);\n expect(await ids({ n: \"1\" })).toEqual([]);\n expect(await ids({ flag: true })).toEqual([\"test-1\"]);\n expect(await ids({ flag: false })).toEqual([\"test-2\"]);\n expect(await ids({ flag: 1 })).toEqual([]);\n expect(await ids({ none: null })).toEqual([\"test-1\"]);\n });\n\n it(\"пустой фильтр — как без фильтра по данным\", async (context) => {\n const { ids } = await filled(context);\n expect(await ids({})).toEqual([\"no-data\", \"other-form\", \"live-1\", \"test-2\", \"test-1\"]);\n });\n\n it(\"работает вместе с subjects: чаты с ключом объекта по умолчанию скрыты\", async (context) => {\n const { storage, ids } = await filled(context);\n await storage.createChat({ ...chatInput, id: \"subject-test\", subjectKey: \"form:1\", data: { formId: \"f1\", mode: \"test\" } });\n expect(await ids({ formId: \"f1\", mode: \"test\" })).toEqual([\"test-2\", \"test-1\"]);\n expect(await ids({ formId: \"f1\", mode: \"test\" }, { subjects: \"include\" })).toContain(\"subject-test\");\n expect(await ids({ formId: \"f1\", mode: \"test\" }, { subjects: \"only\" })).toEqual([\"subject-test\"]);\n });\n\n it(\"значение-объект или массив в фильтре — TypeError: равенство только для строки, числа, булева и null\", async (context) => {\n const { storage } = await filled(context);\n await expect(storage.listChats(chatInput.ownerId, { data: { utm: { campaign: \"a\" } } as never })).rejects.toBeInstanceOf(TypeError);\n await expect(storage.listChats(chatInput.ownerId, { data: { tags: [\"a\"] } as never })).rejects.toBeInstanceOf(TypeError);\n });\n\n it(\"ключ с точкой, кавычкой и пробелом ищется как есть\", async (context) => {\n const storage = await chatDataStorage(context);\n await storage.createChat({ ...chatInput, id: \"odd-keys\", data: { \"a.b\": 1, 'q\"uote': 2, \"with space\": 3 } });\n await storage.createChat({ ...chatInput, id: \"nested\", data: { a: { b: 1 } } });\n for (const filter of [{ \"a.b\": 1 }, { 'q\"uote': 2 }, { \"with space\": 3 }] as ChatDataFilter[]) {\n expect((await storage.listChats(chatInput.ownerId, { data: filter })).map((chat) => chat.id)).toEqual([\"odd-keys\"]);\n }\n });\n\n it(\"после updateChatData чат находится по новому значению, а по старому — нет\", async (context) => {\n const { storage, ids } = await filled(context);\n await storage.updateChatData(\"live-1\", { mode: \"test\" }, { maxBytes });\n expect(await ids({ formId: \"f1\", mode: \"test\" })).toEqual([\"live-1\", \"test-2\", \"test-1\"]);\n expect(await ids({ mode: \"live\" })).toEqual([]);\n });\n });\n\n it(\"importChat переносит данные чата\", async (context) => {\n const storage = await chatDataStorage(context);\n if (!storage.importChat) context.skip();\n const at = \"2023-01-01T09:00:00.000Z\";\n await storage.importChat!(\n { ...chatInput, id: \"imported-data\", createdAt: at, updatedAt: at, data: formData },\n [newStoredMessage({ id: \"i1\", chatId: \"imported-data\", role: \"user\", parts: [{ type: \"text\", text: \"Привет\" }], createdAt: at })],\n );\n expect(await storage.getChat(\"imported-data\")).toMatchObject({ data: formData, subjectData: formData });\n });\n });\n\n describe(\"перенос чата целиком (importChat, необязательный)\", () => {\n type ImportStorage = ChatStorage & Required<Pick<ChatStorage, \"importChat\">>;\n\n async function importStorage(context: { skip: () => never }): Promise<ImportStorage> {\n const storage = await createStorage();\n if (!storage.importChat) {\n if (options.importChat === \"required\") throw new Error(\"У хранилища нет importChat\");\n context.skip();\n }\n return storage as ImportStorage;\n }\n\n const imported = {\n id: \"imported\",\n ownerId: \"anna\",\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n reasoning: \"high\",\n title: \"Старый разговор\",\n createdAt: \"2023-01-01T09:00:00.000Z\",\n updatedAt: \"2023-01-02T09:00:00.000Z\",\n };\n\n function importedMessages(chatId = \"imported\", prefix = \"\"): StoredMessage[] {\n return [\n newStoredMessage({ id: `${prefix}greet`, chatId, role: \"assistant\", parts: [{ type: \"text\", text: \"Здравствуйте!\" }], createdAt: \"2023-01-01T09:00:00.000Z\" }),\n newStoredMessage({ id: `${prefix}q1`, chatId, parentId: `${prefix}greet`, role: \"user\", parts: [{ type: \"text\", text: \"Вопрос\" }], createdAt: \"2023-01-01T09:05:00.000Z\" }),\n newStoredMessage({\n id: `${prefix}a1`,\n chatId,\n parentId: `${prefix}q1`,\n role: \"assistant\",\n parts: [{ type: \"text\", text: \"Ответ\" }],\n modelId: \"deepseek-4.1-flash\",\n providerId: \"deepseek\",\n createdAt: \"2023-01-01T09:06:00.000Z\",\n }),\n ];\n }\n\n it(\"чат и сообщения ложатся как есть: даты чата не пересчитываются по сообщениям, порядок и содержимое прежние\", async (context) => {\n const storage = await importStorage(context);\n const messages = importedMessages();\n await storage.importChat(imported, messages);\n expect(await storage.getChat(\"imported\")).toEqual(imported);\n expect(await storage.listMessages(\"imported\")).toEqual(messages);\n expect(await storage.listChats(\"anna\")).toEqual([imported]);\n });\n\n it(\"ключ и данные объекта переносятся: чат находится по ключу\", async (context) => {\n const storage = await importStorage(context);\n await storage.importChat({ ...imported, subjectKey: \"lesson:7\", subjectData: { lesson: 7 } }, importedMessages());\n expect(await storage.getChat(\"imported\")).toMatchObject({ subjectKey: \"lesson:7\", subjectData: { lesson: 7 } });\n expect((await storage.findChatBySubject?.(\"anna\", \"lesson:7\"))?.id).toBe(\"imported\");\n });\n\n it(\"чат без сообщений переносится\", async (context) => {\n const storage = await importStorage(context);\n await storage.importChat(imported, []);\n expect(await storage.getChat(\"imported\")).toEqual(imported);\n expect(await storage.listMessages(\"imported\")).toEqual([]);\n });\n\n it(\"повтор id чата — ChatAlreadyExistsError, ничего не записано, прежний чат цел\", async (context) => {\n const storage = await importStorage(context);\n await storage.createChat({ ...chatInput, id: \"imported\" });\n await expect(storage.importChat(imported, importedMessages())).rejects.toBeInstanceOf(ChatAlreadyExistsError);\n expect(await storage.getChat(\"imported\")).toMatchObject({ ...chatInput, id: \"imported\" });\n expect(await storage.listMessages(\"imported\")).toEqual([]);\n });\n\n it(\"повтор ключа объекта — DuplicateChatSubjectError, ничего не записано\", async (context) => {\n const storage = await importStorage(context);\n await storage.createChat({ ...chatInput, id: \"first\", subjectKey: \"lesson:7\" });\n await expect(storage.importChat({ ...imported, subjectKey: \"lesson:7\" }, importedMessages())).rejects.toBeInstanceOf(DuplicateChatSubjectError);\n expect(await storage.getChat(\"imported\")).toBeNull();\n expect(await storage.getMessage(\"greet\")).toBeNull();\n });\n\n it(\"сбой на сообщении — ничего не записано: ни чата, ни сообщений (одна транзакция)\", async (context) => {\n const storage = await importStorage(context);\n await storage.importChat({ ...imported, id: \"other\" }, importedMessages(\"other\", \"x-\"));\n // Последнее сообщение повторяет id уже записанного — вставка падает на нём.\n const messages = [...importedMessages(), { ...importedMessages()[2]!, id: \"x-a1\", parentId: \"a1\", createdAt: \"2023-01-01T09:07:00.000Z\" }];\n await expect(storage.importChat(imported, messages)).rejects.toBeInstanceOf(DuplicateMessageError);\n expect(await storage.getChat(\"imported\")).toBeNull();\n expect(await storage.getMessage(\"greet\")).toBeNull();\n expect(await storage.listMessages(\"imported\")).toEqual([]);\n expect((await storage.getMessage(\"x-a1\"))?.chatId).toBe(\"other\");\n });\n\n it(\"перенесённый чат дальше живёт как обычный: новое сообщение поднимает updatedAt\", async (context) => {\n const storage = await importStorage(context);\n await storage.importChat(imported, importedMessages());\n await storage.insertMessage({ ...userMessage(\"q2\", \"2099-01-01T00:00:00.000Z\", \"a1\"), chatId: \"imported\" });\n expect((await storage.getChat(\"imported\"))?.updatedAt).toBe(\"2099-01-01T00:00:00.000Z\");\n expect((await storage.listMessages(\"imported\")).map((message) => message.id)).toEqual([\"greet\", \"q1\", \"a1\", \"q2\"]);\n });\n });\n\n describe(\"состояние хука итога у сообщения (необязательные методы)\", () => {\n type AfterTurnStorage = ChatStorage & Required<Pick<ChatStorage, \"setAfterTurnState\" | \"listPendingAfterTurn\">>;\n\n async function afterTurnStorage(context: { skip: () => never }): Promise<AfterTurnStorage> {\n const storage = await createStorage();\n if (!storage.setAfterTurnState || !storage.listPendingAfterTurn) {\n if (options.afterTurnState === \"required\") throw new Error(\"У хранилища нет состояния хука итога\");\n context.skip();\n }\n await storage.createChat(chatInput);\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n return storage as AfterTurnStorage;\n }\n\n it(\"у сообщения без состояния его нет; ждущих — пусто\", async (context) => {\n const storage = await afterTurnStorage(context);\n expect((await storage.getMessage(\"a1\"))?.afterTurn ?? null).toBeNull();\n expect(await storage.listPendingAfterTurn()).toEqual([]);\n });\n\n it(\"pendingForMs: ждущий свежее порога не отдаётся; отметка — переход в pending по часам хранилища, а не дата создания\", async (context) => {\n const storage = await afterTurnStorage(context);\n const old = \"2020-01-01T00:00:00.000Z\";\n await storage.insertMessage(userMessage(\"u0\", old));\n await storage.insertMessage(streamingAnswer(\"finished-now\", \"u0\", old));\n await storage.finishMessage(\"finished-now\", { status: \"complete\", afterTurn: \"pending\" });\n await storage.insertMessage({ ...streamingAnswer(\"left-long-ago\", \"u0\", old), status: \"complete\", afterTurn: \"pending\" });\n await storage.insertMessage({ ...streamingAnswer(\"reopened-now\", \"u0\", old), status: \"complete\" });\n await storage.setAfterTurnState(\"reopened-now\", \"pending\");\n\n expect((await storage.listPendingAfterTurn()).sort()).toEqual([\"finished-now\", \"left-long-ago\", \"reopened-now\"]);\n expect(await storage.listPendingAfterTurn({ pendingForMs: 60_000 })).toEqual([\"left-long-ago\"]);\n });\n\n it(\"finishMessage с afterTurn: pending ставит состояние той же записью; ответ попадает в ждущие\", async (context) => {\n const storage = await afterTurnStorage(context);\n await storage.finishMessage(\"a1\", { status: \"complete\", parts: [{ type: \"text\", text: \"готово\" }], afterTurn: \"pending\" });\n expect(await storage.getMessage(\"a1\")).toMatchObject({ status: \"complete\", afterTurn: \"pending\" });\n expect((await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\")?.afterTurn).toBe(\"pending\");\n expect(await storage.listPendingAfterTurn()).toEqual([\"a1\"]);\n });\n\n it(\"finishMessage без afterTurn состояние не ставит\", async (context) => {\n const storage = await afterTurnStorage(context);\n await storage.finishMessage(\"a1\", { status: \"complete\" });\n expect((await storage.getMessage(\"a1\"))?.afterTurn ?? null).toBeNull();\n expect(await storage.listPendingAfterTurn()).toEqual([]);\n });\n\n it(\"setAfterTurnState меняет состояние законченного ответа: done и failed уходят из ждущих\", async (context) => {\n const storage = await afterTurnStorage(context);\n await storage.insertMessage({ ...streamingAnswer(\"a2\", \"u1\", \"2099-01-01T00:00:02.000Z\"), status: \"complete\" });\n await storage.finishMessage(\"a1\", { status: \"complete\", afterTurn: \"pending\" });\n await storage.setAfterTurnState(\"a2\", \"pending\");\n expect((await storage.listPendingAfterTurn()).sort()).toEqual([\"a1\", \"a2\"]);\n\n await storage.setAfterTurnState(\"a1\", \"done\");\n await storage.setAfterTurnState(\"a2\", \"failed\");\n expect((await storage.getMessage(\"a1\"))?.afterTurn).toBe(\"done\");\n expect((await storage.getMessage(\"a2\"))?.afterTurn).toBe(\"failed\");\n expect(await storage.listPendingAfterTurn()).toEqual([]);\n });\n\n it(\"неизвестное сообщение — тихо ничего\", async (context) => {\n const storage = await afterTurnStorage(context);\n await expect(storage.setAfterTurnState(\"missing\", \"done\")).resolves.toBe(false);\n expect(await storage.getMessage(\"missing\")).toBeNull();\n });\n\n it(\"done и failed пишутся только из pending: второй закрывающий не проходит\", async (context) => {\n const storage = await afterTurnStorage(context);\n await storage.finishMessage(\"a1\", { status: \"complete\", afterTurn: \"pending\" });\n expect(await storage.setAfterTurnState(\"a1\", \"done\")).toBe(true);\n expect(await storage.setAfterTurnState(\"a1\", \"failed\")).toBe(false);\n expect((await storage.getMessage(\"a1\"))?.afterTurn).toBe(\"done\");\n await storage.insertMessage({ ...streamingAnswer(\"a2\", \"u1\", \"2099-01-01T00:00:02.000Z\"), status: \"complete\" });\n expect(await storage.setAfterTurnState(\"a2\", \"done\")).toBe(false);\n expect((await storage.getMessage(\"a2\"))?.afterTurn ?? null).toBeNull();\n });\n\n it(\"appendParts дописываются в конец частей той же записью и только из pending\", async (context) => {\n const storage = await afterTurnStorage(context);\n const event = { type: \"data-app-event\", data: { type: \"lesson_passed\", data: { score: 5 } } } as StoredMessage[\"parts\"][number];\n await storage.finishMessage(\"a1\", { status: \"complete\", parts: [{ type: \"text\", text: \"готово\" }], afterTurn: \"pending\" });\n expect(await storage.setAfterTurnState(\"a1\", \"done\", { appendParts: [event] })).toBe(true);\n expect((await storage.getMessage(\"a1\"))?.parts).toEqual([{ type: \"text\", text: \"готово\" }, event]);\n expect(await storage.setAfterTurnState(\"a1\", \"done\", { appendParts: [event] })).toBe(false);\n expect((await storage.getMessage(\"a1\"))?.parts).toHaveLength(2);\n });\n\n it(\"удаление чата убирает его ждущие ответы\", async (context) => {\n const storage = await afterTurnStorage(context);\n await storage.finishMessage(\"a1\", { status: \"complete\", afterTurn: \"pending\" });\n await storage.deleteChat(chatInput.id);\n expect(await storage.listPendingAfterTurn()).toEqual([]);\n });\n });\n\n describe(\"аренда хода чата (claimChatTurn, releaseChatTurn, clearChatTurnLeases; необязательные)\", () => {\n type LeaseStorage = ChatStorage & Required<Pick<ChatStorage, \"claimChatTurn\" | \"releaseChatTurn\">>;\n\n async function leaseStorage(context: { skip: () => never }): Promise<LeaseStorage> {\n const storage = await createStorage();\n if (!storage.claimChatTurn || !storage.releaseChatTurn) {\n if (options.chatTurnLease === \"required\") throw new Error(\"У хранилища нет аренды хода чата\");\n context.skip();\n }\n await storage.createChat(chatInput);\n return storage as LeaseStorage;\n }\n\n const minute = 60_000;\n\n it(\"свободный чат берётся; чужая аренда — false; своя продлевается; снятая своя — свободна, чужое снятие не действует\", async (context) => {\n const storage = await leaseStorage(context);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-a\", minute)).toBe(true);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-b\", minute)).toBe(false);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-a\", minute)).toBe(true);\n await storage.releaseChatTurn(chatInput.id, \"copy-b\");\n expect(await storage.claimChatTurn(chatInput.id, \"copy-b\", minute)).toBe(false);\n await storage.releaseChatTurn(chatInput.id, \"copy-a\");\n expect(await storage.claimChatTurn(chatInput.id, \"copy-b\", minute)).toBe(true);\n });\n\n it(\"просроченная аренда (копия упала) берётся другой копией — по часам хранилища\", async (context) => {\n const storage = await leaseStorage(context);\n // Аренда на секунду: под нагрузкой машины вторая попытка не должна успеть «после срока».\n expect(await storage.claimChatTurn(chatInput.id, \"copy-a\", 1_000)).toBe(true);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-b\", minute)).toBe(false);\n await new Promise((resolve) => setTimeout(resolve, 1_100));\n expect(await storage.claimChatTurn(chatInput.id, \"copy-b\", minute)).toBe(true);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-a\", minute)).toBe(false);\n });\n\n it(\"гонка: десять копий берут один чат разом — берёт ровно одна; аренды разных чатов независимы\", async (context) => {\n const storage = await leaseStorage(context);\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n const copies = Array.from({ length: 10 }, (_, index) => `copy-${index}`);\n const won = await Promise.all(copies.map((holder) => storage.claimChatTurn(chatInput.id, holder, minute)));\n expect(won.filter(Boolean)).toHaveLength(1);\n expect(await storage.claimChatTurn(\"chat-2\", \"copy-other\", minute)).toBe(true);\n const winner = copies[won.indexOf(true)]!;\n expect(await storage.claimChatTurn(chatInput.id, winner, minute)).toBe(true);\n });\n\n it(\"удалённый чат — без аренды: новый чат с тем же id свободен\", async (context) => {\n const storage = await leaseStorage(context);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-a\", minute)).toBe(true);\n await storage.deleteChat(chatInput.id);\n await storage.createChat(chatInput);\n expect(await storage.claimChatTurn(chatInput.id, \"copy-b\", minute)).toBe(true);\n });\n\n it(\"clearChatTurnLeases снимает все живые аренды всех чатов (старт единственной копии)\", async (context) => {\n const storage = await leaseStorage(context);\n if (!storage.clearChatTurnLeases) {\n if (options.chatTurnLease === \"required\") throw new Error(\"У хранилища нет clearChatTurnLeases\");\n context.skip();\n }\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n expect(await storage.claimChatTurn(chatInput.id, \"copy-a\", minute)).toBe(true);\n expect(await storage.claimChatTurn(\"chat-2\", \"copy-b\", minute)).toBe(true);\n await storage.clearChatTurnLeases!();\n expect(await storage.claimChatTurn(chatInput.id, \"copy-c\", minute)).toBe(true);\n expect(await storage.claimChatTurn(\"chat-2\", \"copy-c\", minute)).toBe(true);\n });\n });\n\n describe(\"ждущие пачки (savePendingBurst, takeAbandonedBursts, renewPendingBurst, removePendingBurst; необязательные)\", () => {\n type BurstStorage = ChatStorage & Required<Pick<ChatStorage, \"savePendingBurst\" | \"takeAbandonedBursts\" | \"renewPendingBurst\" | \"removePendingBurst\">>;\n\n async function burstStorage(context: { skip: () => never }): Promise<BurstStorage> {\n const storage = await createStorage();\n if (!storage.savePendingBurst || !storage.takeAbandonedBursts || !storage.renewPendingBurst || !storage.removePendingBurst) {\n if (options.pendingBursts === \"required\") throw new Error(\"У хранилища нет ждущих пачек\");\n context.skip();\n }\n await storage.createChat(chatInput);\n return storage as BurstStorage;\n }\n\n const at = (seconds: number) => new Date(Date.UTC(2026, 9, 15, 12, 0, seconds)).toISOString();\n const burst = (fields: Partial<StoredPendingBurst> = {}): StoredPendingBurst => ({\n chatId: chatInput.id,\n ownerId: chatInput.ownerId,\n messageId: \"m1\",\n dueAt: at(3),\n holder: \"copy-a\",\n heldUntil: at(33),\n ...fields,\n });\n const take = (storage: BurstStorage, abandonedBefore: string, holder = \"copy-b\", limit = 10) =>\n storage.takeAbandonedBursts({ abandonedBefore, holder, heldUntil: at(50), limit });\n\n it(\"живое ожидание не берётся; брошенное — берётся один раз и переходит к взявшему\", async (context) => {\n const storage = await burstStorage(context);\n const page: TurnRequestContext = { tabId: \"tab-1\", timeZone: \"Europe/Moscow\" };\n await storage.savePendingBurst(burst({ page }));\n expect(await take(storage, at(32))).toEqual([]);\n expect(await take(storage, at(33))).toEqual([burst({ page, holder: \"copy-b\", heldUntil: at(50) })]);\n // Взятая пачка жива до нового срока: вторая копия её не получит.\n expect(await take(storage, at(40), \"copy-c\")).toEqual([]);\n expect(await take(storage, at(50), \"copy-c\")).toEqual([expect.objectContaining({ holder: \"copy-c\" })]);\n });\n\n it(\"новая запись чата заменяет прежнюю; снятие — только своего сообщения\", async (context) => {\n const storage = await burstStorage(context);\n await storage.savePendingBurst(burst());\n await storage.savePendingBurst(burst({ messageId: \"m2\", dueAt: at(5), heldUntil: at(35) }));\n await storage.removePendingBurst(chatInput.id, \"m1\");\n expect(await take(storage, at(59))).toEqual([expect.objectContaining({ messageId: \"m2\", dueAt: at(5) })]);\n await storage.removePendingBurst(chatInput.id, \"m2\");\n expect(await take(storage, \"2100-01-01T00:00:00.000Z\")).toEqual([]);\n });\n\n it(\"limit и порядок: ранние сроки первыми; удалённый чат — без записи\", async (context) => {\n const storage = await burstStorage(context);\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n await storage.createChat({ ...chatInput, id: \"chat-3\" });\n await storage.savePendingBurst(burst({ chatId: \"chat-2\", dueAt: at(9), heldUntil: at(10) }));\n await storage.savePendingBurst(burst({ dueAt: at(1), heldUntil: at(10) }));\n await storage.savePendingBurst(burst({ chatId: \"chat-3\", dueAt: at(5), heldUntil: at(10) }));\n await storage.deleteChat(\"chat-3\");\n expect((await take(storage, at(20), \"copy-b\", 1)).map((taken) => taken.chatId)).toEqual([chatInput.id]);\n expect((await take(storage, at(20), \"copy-b\", 10)).map((taken) => taken.chatId)).toEqual([\"chat-2\"]);\n });\n\n it(\"продление: только держатель и только той же пачки; продлённая не берётся до нового срока\", async (context) => {\n const storage = await burstStorage(context);\n await storage.savePendingBurst(burst());\n expect(await storage.renewPendingBurst({ chatId: chatInput.id, messageId: \"m1\", holder: \"copy-b\", heldUntil: at(59) })).toBe(false);\n expect(await storage.renewPendingBurst({ chatId: chatInput.id, messageId: \"m0\", holder: \"copy-a\", heldUntil: at(59) })).toBe(false);\n expect(await storage.renewPendingBurst({ chatId: \"chat-none\", messageId: \"m1\", holder: \"copy-a\", heldUntil: at(59) })).toBe(false);\n expect(await storage.renewPendingBurst({ chatId: chatInput.id, messageId: \"m1\", holder: \"copy-a\", heldUntil: at(45) })).toBe(true);\n expect(await take(storage, at(44))).toEqual([]);\n expect(await take(storage, at(45))).toEqual([burst({ holder: \"copy-b\", heldUntil: at(50) })]);\n // Пачку взяла другая копия: прежний держатель её не продлит.\n expect(await storage.renewPendingBurst({ chatId: chatInput.id, messageId: \"m1\", holder: \"copy-a\", heldUntil: at(59) })).toBe(false);\n });\n\n it(\"exceptHolder: свои записи не берутся, сколько бы раз ни звали; чужие — берутся\", async (context) => {\n const storage = await burstStorage(context);\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n await storage.savePendingBurst(burst());\n await storage.savePendingBurst(burst({ chatId: \"chat-2\", holder: \"copy-b\" }));\n const far = \"2100-01-01T00:00:00.000Z\";\n const takeExcept = () => storage.takeAbandonedBursts({ abandonedBefore: far, holder: \"copy-b\", heldUntil: at(50), limit: 10, exceptHolder: \"copy-b\" });\n expect((await takeExcept()).map((taken) => taken.chatId)).toEqual([chatInput.id]);\n expect(await takeExcept()).toEqual([]);\n });\n\n it(\"гонка: десять копий берут разом — каждую пачку получает ровно одна\", async (context) => {\n const storage = await burstStorage(context);\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n await storage.savePendingBurst(burst());\n await storage.savePendingBurst(burst({ chatId: \"chat-2\" }));\n const copies = Array.from({ length: 10 }, (_, index) => `copy-${index}`);\n const taken = (await Promise.all(copies.map((holder) => take(storage, at(40), holder)))).flat();\n expect(taken.map((one) => one.chatId).sort()).toEqual([chatInput.id, \"chat-2\"].sort());\n });\n });\n\n describe(\"закрытие чата (необязательный метод)\", () => {\n type ClosureStorage = ChatStorage & Required<Pick<ChatStorage, \"setChatClosed\">>;\n\n async function closureStorage(context: { skip: () => never }): Promise<ClosureStorage> {\n const storage = await createStorage();\n if (!storage.setChatClosed) {\n if (options.chatClosure === \"required\") throw new Error(\"У хранилища нет закрытия чата\");\n context.skip();\n }\n await storage.createChat(chatInput);\n return storage as ClosureStorage;\n }\n\n const closure = { code: \"form_completed\", message: \"Заявка отправлена. «Диалог» только для чтения 🙂\" };\n\n it(\"у нового чата закрытия нет; setChatClosed пишет его, null — стирает; updatedAt не меняется\", async (context) => {\n const storage = await closureStorage(context);\n const before = await storage.getChat(chatInput.id);\n expect(before).not.toHaveProperty(\"closed\");\n await storage.setChatClosed(chatInput.id, closure);\n expect(await storage.getChat(chatInput.id)).toMatchObject({ closed: closure, updatedAt: before!.updatedAt });\n expect((await storage.listChats(\"anna\"))[0]).toMatchObject({ closed: closure });\n await storage.setChatClosed(chatInput.id, null);\n expect(await storage.getChat(chatInput.id)).not.toHaveProperty(\"closed\");\n });\n\n it(\"повторное закрытие заменяет код и текст; неизвестный чат — тихо\", async (context) => {\n const storage = await closureStorage(context);\n await storage.setChatClosed(chatInput.id, closure);\n await storage.setChatClosed(chatInput.id, { code: \"form_unpublished\", message: \"Форма снята с публикации.\" });\n expect((await storage.getChat(chatInput.id))?.closed).toEqual({ code: \"form_unpublished\", message: \"Форма снята с публикации.\" });\n await expect(storage.setChatClosed(\"missing\", closure)).resolves.toBeUndefined();\n expect(await storage.getChat(\"missing\")).toBeNull();\n });\n });\n\n describe(\"голосовой режим (необязательные методы)\", () => {\n type VoiceStorage = ChatStorage & Required<Pick<ChatStorage, \"setVoiceCut\" | \"getVoiceChoice\" | \"setVoiceChoice\">>;\n\n /** Хранилище без этих методов договор не нарушает: пакет диалога тогда держит выбор и отметку в памяти. */\n async function voiceStorage(context: { skip: () => never }, withChat = true): Promise<VoiceStorage> {\n const storage = await createStorage();\n if (!storage.setVoiceCut || !storage.getVoiceChoice || !storage.setVoiceChoice) {\n if (options.voiceDialog === \"required\") throw new Error(\"У хранилища нет методов голосового режима\");\n context.skip();\n }\n if (withChat) await storage.createChat(chatInput);\n return storage as VoiceStorage;\n }\n\n const cut = { partIndex: 0, charOffset: 27, spokenTail: \"…сначала разберём, как это устроено\" };\n\n async function chatWithAnswer(storage: VoiceStorage): Promise<void> {\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage({\n ...streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"),\n status: \"complete\",\n parts: [{ type: \"text\", text: \"Сначала разберём, как это устроено, потом посмотрим на примеры.\" }],\n });\n }\n\n describe(\"отметка обрыва\", () => {\n it(\"у сообщения без отметки чтение даёт voiceCut: null\", async (context) => {\n const storage = await voiceStorage(context);\n await chatWithAnswer(storage);\n expect((await storage.getMessage(\"a1\"))?.voiceCut).toBeNull();\n expect((await storage.listMessages(chatInput.id)).map((message) => message.voiceCut)).toEqual([null, null]);\n });\n\n it(\"setVoiceCut пишет отметку владельцу: её видят getMessage и listMessages; повторная запись заменяет\", async (context) => {\n const storage = await voiceStorage(context);\n await chatWithAnswer(storage);\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: chatInput.id, messageId: \"a1\", voiceCut: cut });\n expect((await storage.getMessage(\"a1\"))?.voiceCut).toEqual(cut);\n expect((await storage.listMessages(chatInput.id)).find((message) => message.id === \"a1\")?.voiceCut).toEqual(cut);\n\n const later = { partIndex: 0, charOffset: 50, spokenTail: \"…потом посмотрим\" };\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: chatInput.id, messageId: \"a1\", voiceCut: later });\n expect((await storage.getMessage(\"a1\"))?.voiceCut).toEqual(later);\n });\n\n it(\"чужой владелец: тихо ничего, отметка не появляется\", async (context) => {\n const storage = await voiceStorage(context);\n await chatWithAnswer(storage);\n await expect(\n storage.setVoiceCut({ ownerId: \"boris\", chatId: chatInput.id, messageId: \"a1\", voiceCut: cut }),\n ).resolves.toBeUndefined();\n expect((await storage.getMessage(\"a1\"))?.voiceCut).toBeNull();\n });\n\n it(\"сообщение из другого чата или неизвестное: тихо ничего\", async (context) => {\n const storage = await voiceStorage(context);\n await chatWithAnswer(storage);\n await storage.createChat({ ...chatInput, id: \"chat-2\" });\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: \"chat-2\", messageId: \"a1\", voiceCut: cut });\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: chatInput.id, messageId: \"missing\", voiceCut: cut });\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: \"missing\", messageId: \"a1\", voiceCut: cut });\n expect((await storage.getMessage(\"a1\"))?.voiceCut).toBeNull();\n });\n\n it(\"отметка, поставленная у идущего ответа, переживает его завершение и дописывание\", async (context) => {\n const storage = await voiceStorage(context);\n await storage.insertMessage(userMessage(\"u1\", \"2099-01-01T00:00:00.000Z\"));\n await storage.insertMessage(streamingAnswer(\"a1\", \"u1\", \"2099-01-01T00:00:01.000Z\"));\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: chatInput.id, messageId: \"a1\", voiceCut: cut });\n await storage.updateStreamingMessage(\"a1\", { parts: [{ type: \"text\", text: \"часть\" }] });\n await storage.finishMessage(\"a1\", { status: \"stopped\", parts: [{ type: \"text\", text: \"часть ответа\" }] });\n expect(await storage.getMessage(\"a1\")).toMatchObject({ status: \"stopped\", voiceCut: cut });\n });\n\n it(\"отметка одного сообщения не задевает другие\", async (context) => {\n const storage = await voiceStorage(context);\n await chatWithAnswer(storage);\n await storage.setVoiceCut({ ownerId: \"anna\", chatId: chatInput.id, messageId: \"a1\", voiceCut: cut });\n expect((await storage.getMessage(\"u1\"))?.voiceCut).toBeNull();\n });\n });\n\n describe(\"выбор голоса\", () => {\n it(\"у человека без выбора — null\", async (context) => {\n const storage = await voiceStorage(context, false);\n expect(await storage.getVoiceChoice(\"anna\")).toBeNull();\n });\n\n it(\"запись, чтение и замена\", async (context) => {\n const storage = await voiceStorage(context, false);\n await storage.setVoiceChoice(\"anna\", \"voice-a\");\n expect(await storage.getVoiceChoice(\"anna\")).toBe(\"voice-a\");\n await storage.setVoiceChoice(\"anna\", \"voice-b\");\n expect(await storage.getVoiceChoice(\"anna\")).toBe(\"voice-b\");\n });\n\n it(\"у каждого человека свой выбор\", async (context) => {\n const storage = await voiceStorage(context, false);\n await storage.setVoiceChoice(\"anna\", \"voice-a\");\n await storage.setVoiceChoice(\"boris\", \"voice-b\");\n expect(await storage.getVoiceChoice(\"anna\")).toBe(\"voice-a\");\n expect(await storage.getVoiceChoice(\"boris\")).toBe(\"voice-b\");\n expect(await storage.getVoiceChoice(\"clara\")).toBeNull();\n });\n\n it(\"не зависит от выбора модели (015) и от удаления чатов\", async (context) => {\n const storage = await voiceStorage(context);\n await storage.setVoiceChoice(\"anna\", \"voice-a\");\n await storage.saveUserModelChoice?.(\"anna\", { modelId: \"m\", providerId: \"p\" });\n expect(await storage.getVoiceChoice(\"anna\")).toBe(\"voice-a\");\n if (storage.getUserModelChoice) expect(await storage.getUserModelChoice(\"anna\")).toEqual({ modelId: \"m\", providerId: \"p\" });\n await storage.setVoiceChoice(\"anna\", \"voice-b\");\n if (storage.getUserModelChoice) expect(await storage.getUserModelChoice(\"anna\")).toEqual({ modelId: \"m\", providerId: \"p\" });\n await storage.deleteChat(chatInput.id);\n expect(await storage.getVoiceChoice(\"anna\")).toBe(\"voice-b\");\n });\n\n it(\"двадцать записей одновременно не ломают хранилище: остаётся одно из записанных значений\", async (context) => {\n const storage = await voiceStorage(context, false);\n await Promise.all(Array.from({ length: 20 }, (_, index) => storage.setVoiceChoice(\"anna\", `voice-${index}`)));\n expect(await storage.getVoiceChoice(\"anna\")).toMatch(/^voice-\\d+$/);\n });\n });\n });\n\n describe(\"состояние лимитов расходов (необязательные методы)\", () => {\n async function storageWithLimitState(context: { skip: () => never }) {\n const storage = await createStorage();\n if (!storage.getSpendingLimitState || !storage.saveSpendingLimitState) {\n if (options.spendingLimitState === \"required\") throw new Error(\"У хранилища нет методов состояния лимитов расходов\");\n context.skip();\n }\n return storage as ChatStorage & Required<Pick<ChatStorage, \"getSpendingLimitState\" | \"saveSpendingLimitState\">>;\n }\n\n it(\"нет записи — null; первая запись — только при expectedVersion null, версия 1\", async (context) => {\n const storage = await storageWithLimitState(context);\n expect(await storage.getSpendingLimitState(\"user:anna\")).toBeNull();\n expect(await storage.saveSpendingLimitState(\"user:anna\", \"{}\", 1)).toBe(false);\n expect(await storage.getSpendingLimitState(\"user:anna\")).toBeNull();\n expect(await storage.saveSpendingLimitState(\"user:anna\", '{\"a\":1}', null)).toBe(true);\n expect(await storage.getSpendingLimitState(\"user:anna\")).toEqual({ value: '{\"a\":1}', version: 1 });\n });\n\n it(\"запись по версии: верная — заменяет и растит версию, устаревшая или null при существующей — false и ничего\", async (context) => {\n const storage = await storageWithLimitState(context);\n await storage.saveSpendingLimitState(\"k\", \"v1\", null);\n expect(await storage.saveSpendingLimitState(\"k\", \"v2\", 1)).toBe(true);\n expect(await storage.saveSpendingLimitState(\"k\", \"stale\", 1)).toBe(false);\n expect(await storage.saveSpendingLimitState(\"k\", \"again\", null)).toBe(false);\n expect(await storage.getSpendingLimitState(\"k\")).toEqual({ value: \"v2\", version: 2 });\n });\n\n it(\"из двух одновременных записей с одной версией проходит одна\", async (context) => {\n const storage = await storageWithLimitState(context);\n await storage.saveSpendingLimitState(\"k\", \"v1\", null);\n const results = await Promise.all([storage.saveSpendingLimitState(\"k\", \"a\", 1), storage.saveSpendingLimitState(\"k\", \"b\", 1)]);\n expect(results.filter(Boolean)).toHaveLength(1);\n expect((await storage.getSpendingLimitState(\"k\"))!.version).toBe(2);\n });\n\n it(\"ключи независимы; длинная строка с юникодом хранится как есть; чаты не трогает\", async (context) => {\n const storage = await storageWithLimitState(context);\n const long = JSON.stringify({ note: \"лимит ✓\", items: Array.from({ length: 2000 }, (_, index) => index) });\n await storage.saveSpendingLimitState(\"service\", long, null);\n await storage.saveSpendingLimitState(\"user:boris\", \"b\", null);\n expect(await storage.getSpendingLimitState(\"service\")).toEqual({ value: long, version: 1 });\n expect(await storage.getSpendingLimitState(\"user:boris\")).toEqual({ value: \"b\", version: 1 });\n expect(await storage.listChats(\"anna\")).toEqual([]);\n });\n\n it(\"удаление по ключам: стирает только названные, лишние ключи и пустой список — не ошибка\", async (context) => {\n const storage = await storageWithLimitState(context);\n if (!storage.deleteSpendingLimitStates) {\n if (options.spendingLimitState === \"required\") throw new Error(\"У хранилища нет метода deleteSpendingLimitStates\");\n context.skip();\n }\n const keys = [\"window:chat:c1:day\", \"window:chat:c1:week\", \"window:chat:c1:day:x\", \"window:chat:чат:day\", \"window:user:anna:day\"];\n for (const key of keys) await storage.saveSpendingLimitState(key, \"v\", null);\n await storage.deleteSpendingLimitStates!([\"window:chat:c1:day\", \"window:chat:c1:week\", \"window:chat:чат:day\", \"нет-такого\"]);\n await storage.deleteSpendingLimitStates!([]);\n const left = [];\n for (const key of keys) if (await storage.getSpendingLimitState(key)) left.push(key);\n expect(left).toEqual([\"window:chat:c1:day:x\", \"window:user:anna:day\"]);\n expect(await storage.saveSpendingLimitState(\"window:chat:c1:day\", \"new\", null)).toBe(true);\n });\n });\n\n describe(\"запомненный выбор модели (необязательные методы)\", () => {\n /** Хранилище без этих методов договор не нарушает: ядро тогда ведёт себя как раньше. */\n async function storageWithChoiceMemory(context: { skip: () => never }) {\n const storage = await createStorage();\n if (!storage.getUserModelChoice || !storage.saveUserModelChoice) {\n if (options.choiceMemory === \"required\") throw new Error(\"У хранилища нет методов запомненного выбора модели\");\n context.skip();\n }\n return storage as ChatStorage & Required<Pick<ChatStorage, \"getUserModelChoice\" | \"saveUserModelChoice\">>;\n }\n\n it(\"у человека без выбора — null\", async (context) => {\n const storage = await storageWithChoiceMemory(context);\n expect(await storage.getUserModelChoice(\"anna\")).toBeNull();\n });\n\n it(\"хранит модель, провайдера и уровень рассуждений; без уровня — без уровня\", async (context) => {\n const storage = await storageWithChoiceMemory(context);\n await storage.saveUserModelChoice(\"anna\", { modelId: \"m\", providerId: \"p\", reasoning: \"high\" });\n expect(await storage.getUserModelChoice(\"anna\")).toEqual({ modelId: \"m\", providerId: \"p\", reasoning: \"high\" });\n\n await storage.saveUserModelChoice(\"anna\", { modelId: \"m2\", providerId: \"p2\" });\n const replaced = await storage.getUserModelChoice(\"anna\");\n expect(replaced).toEqual({ modelId: \"m2\", providerId: \"p2\" });\n expect(replaced).not.toHaveProperty(\"reasoning\");\n });\n\n it(\"у каждого человека свой выбор\", async (context) => {\n const storage = await storageWithChoiceMemory(context);\n await storage.saveUserModelChoice(\"anna\", { modelId: \"a\", providerId: \"p\" });\n await storage.saveUserModelChoice(\"boris\", { modelId: \"b\", providerId: \"p\", reasoning: \"low\" });\n expect(await storage.getUserModelChoice(\"anna\")).toEqual({ modelId: \"a\", providerId: \"p\" });\n expect(await storage.getUserModelChoice(\"boris\")).toEqual({ modelId: \"b\", providerId: \"p\", reasoning: \"low\" });\n expect(await storage.getUserModelChoice(\"clara\")).toBeNull();\n });\n\n it(\"не трогает чаты и не зависит от их удаления\", async (context) => {\n const storage = await storageWithChoiceMemory(context);\n await storage.createChat(chatInput);\n await storage.saveUserModelChoice(\"anna\", { modelId: \"other\", providerId: \"fireworks\" });\n expect(await storage.getChat(chatInput.id)).toMatchObject({ modelId: chatInput.modelId, providerId: chatInput.providerId });\n await storage.deleteChat(chatInput.id);\n expect(await storage.getUserModelChoice(\"anna\")).toEqual({ modelId: \"other\", providerId: \"fireworks\" });\n });\n\n it(\"двадцать записей одновременно не ломают хранилище: остаётся одно из записанных значений\", async (context) => {\n const storage = await storageWithChoiceMemory(context);\n await Promise.all(Array.from({ length: 20 }, (_, index) => storage.saveUserModelChoice(\"anna\", { modelId: `m${index}`, providerId: \"p\" })));\n const saved = await storage.getUserModelChoice(\"anna\");\n expect(saved?.modelId).toMatch(/^m\\d+$/);\n });\n });\n\n describe(\"долгая память (необязательные методы)\", () => {\n type MemoryStorage = ChatStorage &\n Required<\n Pick<ChatStorage, \"listMemoryNotes\" | \"insertMemoryNotes\" | \"updateMemoryNote\" | \"deleteMemoryNote\" | \"clearMemoryNotes\">\n >;\n\n /** Хранилище без этих методов договор не нарушает: приложение тогда не подключает пакет памяти. */\n async function storageWithMemory(context: { skip: () => never }): Promise<MemoryStorage> {\n const storage = await createStorage();\n const present =\n storage.listMemoryNotes &&\n storage.insertMemoryNotes &&\n storage.updateMemoryNote &&\n storage.deleteMemoryNote &&\n storage.clearMemoryNotes;\n if (!present) {\n if (options.memory === \"required\") throw new Error(\"У хранилища нет методов долгой памяти\");\n context.skip();\n }\n return storage as MemoryStorage;\n }\n\n const note = (content: string, ...categories: string[]): MemoryNoteInput => ({\n categories: categories.length > 0 ? categories : [\"О себе\"],\n content,\n });\n\n /** Порядок списка по договору: `updatedAt`, затем `createdAt`, затем `id` — новее и больше первыми. */\n function expectedOrder(notes: MemoryNote[]): string[] {\n return [...notes]\n .sort(\n (left, right) =>\n right.updatedAt.localeCompare(left.updatedAt) ||\n right.createdAt.localeCompare(left.createdAt) ||\n (right.id > left.id ? 1 : right.id < left.id ? -1 : 0),\n )\n .map((item) => item.id);\n }\n\n /** Ждёт, пока часы уйдут вперёд хотя бы на миллисекунду: пауза до условия, а не по таймеру. */\n async function untilClockMoves(): Promise<void> {\n const start = Date.now();\n while (Date.now() <= start) await new Promise((resolve) => setTimeout(resolve, 1));\n }\n\n it(\"у человека без записей список пуст\", async (context) => {\n const storage = await storageWithMemory(context);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([]);\n });\n\n it(\"вставка выдаёт записи с id, версией 1 и временем; список читает их; владельца в записи нет\", async (context) => {\n const storage = await storageWithMemory(context);\n const created = await storage.insertMemoryNotes(\"anna\", [note(\"Пишет на TypeScript\", \"О себе\", \"Работа\"), note(\"Отвечай на «ты»\", \"Правила\")]);\n expect(created).toHaveLength(2);\n expect(new Set(created.map((item) => item.id)).size).toBe(2);\n for (const item of created) {\n expect(item.id).toEqual(expect.any(String));\n expect(item.version).toBe(1);\n expect(Number.isNaN(Date.parse(item.createdAt))).toBe(false);\n expect(item.updatedAt).toBe(item.createdAt);\n expect(item).not.toHaveProperty(\"ownerId\");\n }\n expect(created.find((item) => item.content === \"Пишет на TypeScript\")?.categories).toEqual([\"О себе\", \"Работа\"]);\n\n const listed = await storage.listMemoryNotes(\"anna\");\n expect(listed).toHaveLength(2);\n expect(listed.map((item) => item.id).sort()).toEqual(created.map((item) => item.id).sort());\n for (const item of listed) expect(item).not.toHaveProperty(\"ownerId\");\n });\n\n it(\"пустой пакет — пустой ответ, ничего не создаётся\", async (context) => {\n const storage = await storageWithMemory(context);\n expect(await storage.insertMemoryNotes(\"anna\", [])).toEqual([]);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([]);\n });\n\n it(\"пакет — всё или ничего: одна негодная запись не оставляет и остальных\", async (context) => {\n const storage = await storageWithMemory(context);\n await storage.insertMemoryNotes(\"anna\", [note(\"Уже была\")]);\n const broken = { categories: [\"О себе\"], content: null } as unknown as MemoryNoteInput;\n await expect(storage.insertMemoryNotes(\"anna\", [note(\"Хорошая первая\"), broken, note(\"Хорошая третья\")])).rejects.toBeInstanceOf(Error);\n const listed = await storage.listMemoryNotes(\"anna\");\n expect(listed.map((item) => item.content)).toEqual([\"Уже была\"]);\n });\n\n it(\"у каждого человека своя память: чужие записи не видны\", async (context) => {\n const storage = await storageWithMemory(context);\n await storage.insertMemoryNotes(\"anna\", [note(\"Записка Анны\")]);\n await storage.insertMemoryNotes(\"boris\", [note(\"Записка Бориса\"), note(\"Ещё одна Бориса\")]);\n expect((await storage.listMemoryNotes(\"anna\")).map((item) => item.content)).toEqual([\"Записка Анны\"]);\n expect(await storage.listMemoryNotes(\"boris\")).toHaveLength(2);\n expect(await storage.listMemoryNotes(\"clara\")).toEqual([]);\n });\n\n it(\"чужая запись — not_found при правке и удалении, сама запись цела\", async (context) => {\n const storage = await storageWithMemory(context);\n const [annas] = await storage.insertMemoryNotes(\"anna\", [note(\"Записка Анны\")]);\n expect(await storage.updateMemoryNote(\"boris\", annas!.id, 1, note(\"Подмена\"))).toBe(\"not_found\");\n expect(await storage.deleteMemoryNote(\"boris\", annas!.id, 1)).toBe(\"not_found\");\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([annas]);\n });\n\n it(\"правка меняет разделы и текст, поднимает версию на 1, createdAt не трогает, updatedAt не уменьшает\", async (context) => {\n const storage = await storageWithMemory(context);\n const [created] = await storage.insertMemoryNotes(\"anna\", [note(\"Пишет на JavaScript\", \"О себе\")]);\n await untilClockMoves();\n const updated = await storage.updateMemoryNote(\"anna\", created!.id, 1, note(\"Пишет на TypeScript\", \"О себе\", \"Работа\"));\n expect(updated).toMatchObject({\n id: created!.id,\n version: 2,\n content: \"Пишет на TypeScript\",\n categories: [\"О себе\", \"Работа\"],\n createdAt: created!.createdAt,\n });\n expect((updated as MemoryNote).updatedAt > created!.updatedAt).toBe(true);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([updated]);\n\n const again = await storage.updateMemoryNote(\"anna\", created!.id, 2, note(\"Пишет на Rust\", \"О себе\"));\n expect(again).toMatchObject({ version: 3, content: \"Пишет на Rust\" });\n });\n\n it(\"правка с устаревшей версией — stale_version, запись не меняется\", async (context) => {\n const storage = await storageWithMemory(context);\n const [created] = await storage.insertMemoryNotes(\"anna\", [note(\"Первая редакция\")]);\n await storage.updateMemoryNote(\"anna\", created!.id, 1, note(\"Вторая редакция\"));\n expect(await storage.updateMemoryNote(\"anna\", created!.id, 1, note(\"Опоздавшая правка\"))).toBe(\"stale_version\");\n expect(await storage.updateMemoryNote(\"anna\", created!.id, 3, note(\"Версия из будущего\"))).toBe(\"stale_version\");\n const [kept] = await storage.listMemoryNotes(\"anna\");\n expect(kept).toMatchObject({ version: 2, content: \"Вторая редакция\" });\n });\n\n it(\"удаление: с верной версией — ok, с устаревшей — stale_version и запись остаётся, повтор — not_found\", async (context) => {\n const storage = await storageWithMemory(context);\n const [created] = await storage.insertMemoryNotes(\"anna\", [note(\"Временная\")]);\n await storage.updateMemoryNote(\"anna\", created!.id, 1, note(\"Временная, правка\"));\n expect(await storage.deleteMemoryNote(\"anna\", created!.id, 1)).toBe(\"stale_version\");\n expect(await storage.listMemoryNotes(\"anna\")).toHaveLength(1);\n expect(await storage.deleteMemoryNote(\"anna\", created!.id, 2)).toBe(\"ok\");\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([]);\n expect(await storage.deleteMemoryNote(\"anna\", created!.id, 2)).toBe(\"not_found\");\n });\n\n it(\"правка и удаление неизвестной записи — not_found\", async (context) => {\n const storage = await storageWithMemory(context);\n expect(await storage.updateMemoryNote(\"anna\", \"missing\", 1, note(\"Нет такой\"))).toBe(\"not_found\");\n expect(await storage.deleteMemoryNote(\"anna\", \"missing\", 1)).toBe(\"not_found\");\n });\n\n it(\"две правки с одной версией одновременно: проходит одна, вторая — stale_version\", async (context) => {\n const storage = await storageWithMemory(context);\n const [created] = await storage.insertMemoryNotes(\"anna\", [note(\"Исходная\")]);\n const results = await Promise.all([\n storage.updateMemoryNote(\"anna\", created!.id, 1, note(\"Правка А\")),\n storage.updateMemoryNote(\"anna\", created!.id, 1, note(\"Правка Б\")),\n ]);\n expect(results.filter((result) => result === \"stale_version\")).toHaveLength(1);\n expect(results.filter((result) => typeof result === \"object\")).toHaveLength(1);\n const [kept] = await storage.listMemoryNotes(\"anna\");\n expect(kept?.version).toBe(2);\n });\n\n it(\"порядок списка: новейшие по updatedAt первыми, при равенстве по createdAt, затем по id\", async (context) => {\n const storage = await storageWithMemory(context);\n const batch = await storage.insertMemoryNotes(\"anna\", [note(\"Первая\"), note(\"Вторая\"), note(\"Третья\")]);\n await untilClockMoves();\n const [later] = await storage.insertMemoryNotes(\"anna\", [note(\"Позже\")]);\n let listed = await storage.listMemoryNotes(\"anna\");\n expect(listed.map((item) => item.id)).toEqual(expectedOrder(listed));\n expect(listed[0]?.id).toBe(later!.id);\n\n // Правка поднимает запись на первое место.\n await untilClockMoves();\n await storage.updateMemoryNote(\"anna\", batch[0]!.id, 1, note(\"Первая, правка\"));\n listed = await storage.listMemoryNotes(\"anna\");\n expect(listed.map((item) => item.id)).toEqual(expectedOrder(listed));\n expect(listed[0]?.id).toBe(batch[0]!.id);\n });\n\n it(\"удаление чата память не трогает\", async (context) => {\n const storage = await storageWithMemory(context);\n await storage.createChat(chatInput);\n await storage.insertMemoryNotes(chatInput.ownerId, [note(\"Переживёт чат\")]);\n await storage.deleteChat(chatInput.id);\n expect((await storage.listMemoryNotes(chatInput.ownerId)).map((item) => item.content)).toEqual([\"Переживёт чат\"]);\n });\n\n it(\"стирание убирает всю память своего человека, возвращает число и не трогает чужую\", async (context) => {\n const storage = await storageWithMemory(context);\n await storage.insertMemoryNotes(\"anna\", [note(\"Один\"), note(\"Два\"), note(\"Три\")]);\n await storage.insertMemoryNotes(\"boris\", [note(\"Борисов\")]);\n expect(await storage.clearMemoryNotes(\"anna\")).toBe(3);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([]);\n expect(await storage.listMemoryNotes(\"boris\")).toHaveLength(1);\n expect(await storage.clearMemoryNotes(\"anna\")).toBe(0);\n expect(await storage.clearMemoryNotes(\"clara\")).toBe(0);\n });\n\n it(\"отданные записи — копии: правка ответа не меняет хранилище\", async (context) => {\n const storage = await storageWithMemory(context);\n const [created] = await storage.insertMemoryNotes(\"anna\", [note(\"Оригинал\", \"О себе\")]);\n created!.content = \"Испорчено\";\n created!.categories.push(\"Лишний\");\n const [listed] = await storage.listMemoryNotes(\"anna\");\n expect(listed).toMatchObject({ content: \"Оригинал\", categories: [\"О себе\"] });\n listed!.categories.push(\"Ещё лишний\");\n expect((await storage.listMemoryNotes(\"anna\"))[0]?.categories).toEqual([\"О себе\"]);\n });\n\n describe(\"проверка внутри операции\", () => {\n type CheckedStorage = MemoryStorage & Required<Pick<ChatStorage, \"insertMemoryNotesChecked\" | \"updateMemoryNoteChecked\">>;\n\n async function checkedStorage(context: { skip: () => never }): Promise<CheckedStorage> {\n const storage = await storageWithMemory(context);\n if (!storage.insertMemoryNotesChecked || !storage.updateMemoryNoteChecked) {\n if (options.memory === \"required\") throw new Error(\"У хранилища нет методов записи с проверкой внутри операции\");\n context.skip();\n }\n return storage as CheckedStorage;\n }\n\n const refuse: MemoryError = { kind: \"limit_reached\", message: \"Хватит\" };\n /** Пускает, пока у человека меньше `max` записей. */\n const atMost =\n (max: number): MemoryWriteGuard =>\n (existing) =>\n existing.length >= max ? refuse : null;\n\n it(\"вставка: проверка видит записи только своего человека, ничего ещё не записано; без ошибки записи появляются\", async (context) => {\n const storage = await checkedStorage(context);\n await storage.insertMemoryNotes(\"anna\", [note(\"Первая\"), note(\"Вторая\")]);\n await storage.insertMemoryNotes(\"boris\", [note(\"Борисова\")]);\n const seen: string[][] = [];\n const created = await storage.insertMemoryNotesChecked(\"anna\", [note(\"Третья\")], (existing) => {\n seen.push(existing.map((item) => item.content));\n return null;\n });\n expect(seen).toHaveLength(1);\n expect([...seen[0]!].sort()).toEqual([\"Вторая\", \"Первая\"]);\n expect(created).toEqual([expect.objectContaining({ content: \"Третья\", version: 1 })]);\n expect(await storage.listMemoryNotes(\"anna\")).toHaveLength(3);\n });\n\n it(\"вставка: ошибка проверки отдаётся как есть и ничего не записывает\", async (context) => {\n const storage = await checkedStorage(context);\n await storage.insertMemoryNotes(\"anna\", [note(\"Первая\")]);\n expect(await storage.insertMemoryNotesChecked(\"anna\", [note(\"Вторая\"), note(\"Третья\")], () => refuse)).toEqual(refuse);\n expect((await storage.listMemoryNotes(\"anna\")).map((item) => item.content)).toEqual([\"Первая\"]);\n });\n\n it(\"вставка: параллельные вставки не обходят проверку — проходят ровно те, что помещаются\", async (context) => {\n const storage = await checkedStorage(context);\n await storage.insertMemoryNotes(\"anna\", [note(\"Одна\"), note(\"Другая\")]);\n const results = await Promise.all(Array.from({ length: 6 }, (_, index) => storage.insertMemoryNotesChecked(\"anna\", [note(`Новая ${index}`)], atMost(5))));\n expect(results.filter(Array.isArray)).toHaveLength(3);\n expect(results.filter((result) => !Array.isArray(result))).toEqual([refuse, refuse, refuse]);\n expect(await storage.listMemoryNotes(\"anna\")).toHaveLength(5);\n });\n\n it(\"правка: проверка видит все записи человека, включая заменяемую; без ошибки запись меняется\", async (context) => {\n const storage = await checkedStorage(context);\n const [first] = await storage.insertMemoryNotes(\"anna\", [note(\"Первая\"), note(\"Вторая\")]);\n let seen: string[] = [];\n const updated = await storage.updateMemoryNoteChecked(\"anna\", first!.id, 1, note(\"Новая\"), (existing) => {\n seen = existing.map((item) => item.content);\n return null;\n });\n expect(seen.sort()).toEqual([\"Вторая\", \"Первая\"]);\n expect(updated).toMatchObject({ content: \"Новая\", version: 2 });\n });\n\n it(\"правка: ошибка проверки отдаётся как есть, запись не меняется, а проверка идёт раньше версии\", async (context) => {\n const storage = await checkedStorage(context);\n const [first] = await storage.insertMemoryNotes(\"anna\", [note(\"Первая\")]);\n expect(await storage.updateMemoryNoteChecked(\"anna\", first!.id, 7, note(\"Новая\"), () => refuse)).toEqual(refuse);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([first]);\n });\n\n it(\"правка: чужая запись и старая версия — как у обычной правки, если проверка пропустила\", async (context) => {\n const storage = await checkedStorage(context);\n const [first] = await storage.insertMemoryNotes(\"anna\", [note(\"Первая\")]);\n expect(await storage.updateMemoryNoteChecked(\"anna\", first!.id, 7, note(\"Новая\"), () => null)).toBe(\"stale_version\");\n expect(await storage.updateMemoryNoteChecked(\"boris\", first!.id, 1, note(\"Новая\"), () => null)).toBe(\"not_found\");\n expect(await storage.updateMemoryNoteChecked(\"anna\", \"missing\", 1, note(\"Новая\"), () => null)).toBe(\"not_found\");\n });\n\n it(\"правка: параллельные правки не обходят проверку\", async (context) => {\n const storage = await checkedStorage(context);\n const [first, second] = await storage.insertMemoryNotes(\"anna\", [note(\"Первая\"), note(\"Вторая\")]);\n const sameTextTaken: MemoryWriteGuard = (existing) => (existing.some((item) => item.content === \"Общий текст\") ? { kind: \"duplicate\", message: \"Повтор\" } : null);\n const results = await Promise.all([\n storage.updateMemoryNoteChecked(\"anna\", first!.id, 1, note(\"Общий текст\"), sameTextTaken),\n storage.updateMemoryNoteChecked(\"anna\", second!.id, 1, note(\"Общий текст\"), sameTextTaken),\n ]);\n expect(results.filter((result) => typeof result === \"object\" && \"content\" in result)).toHaveLength(1);\n expect((await storage.listMemoryNotes(\"anna\")).filter((item) => item.content === \"Общий текст\")).toHaveLength(1);\n });\n });\n });\n describe(\"оптимизация дублей (необязательные методы)\", () => {\n type OptimizerStorage = ChatStorage &\n Required<\n Pick<\n ChatStorage,\n | \"listMemoryNotes\"\n | \"insertMemoryNotes\"\n | \"updateMemoryNote\"\n | \"deleteMemoryNote\"\n | \"clearMemoryNotes\"\n | \"claimMemoryOptimizationRun\"\n | \"finishMemoryOptimizationRun\"\n | \"applyMemoryMerge\"\n | \"revertMemoryMerge\"\n | \"listMemoryOptimizationRuns\"\n | \"listMergedMemoryNotes\"\n >\n >;\n\n const MINUTE = 60_000;\n const rules: MemoryOptimizationRules = { minIntervalMs: 24 * 60 * MINUTE, retryAfterFailureMs: 60 * MINUTE, leaseMs: 3 * MINUTE };\n /** Время запуска: минуты от условного начала; хранилище берёт часы у вызывающего. */\n const at = (minutes: number) => new Date(Date.UTC(2026, 0, 1) + minutes * MINUTE).toISOString();\n\n async function storageWithOptimizer(context: { skip: () => never }): Promise<OptimizerStorage> {\n const storage = await createStorage();\n const present =\n storage.listMemoryNotes &&\n storage.insertMemoryNotes &&\n storage.updateMemoryNote &&\n storage.deleteMemoryNote &&\n storage.clearMemoryNotes &&\n storage.claimMemoryOptimizationRun &&\n storage.finishMemoryOptimizationRun &&\n storage.applyMemoryMerge &&\n storage.revertMemoryMerge &&\n storage.listMemoryOptimizationRuns &&\n storage.listMergedMemoryNotes;\n if (!present) {\n if (options.memoryOptimization === \"required\") throw new Error(\"У хранилища нет методов оптимизации дублей\");\n context.skip();\n }\n return storage as OptimizerStorage;\n }\n\n const note = (content: string, ...categories: string[]): MemoryNoteInput => ({\n categories: categories.length > 0 ? categories : [\"О себе\"],\n content,\n });\n\n async function claimed(storage: OptimizerStorage, ownerId = \"anna\", minutes = 0) {\n const run = await storage.claimMemoryOptimizationRun(ownerId, rules, at(minutes));\n expect(run).not.toBeNull();\n return run!;\n }\n\n /** Три записи и запуск: то, с чего начинается слияние двух из них. */\n async function withRun(storage: OptimizerStorage) {\n const [first, second, third] = await storage.insertMemoryNotes(\"anna\", [\n note(\"Пишет на TypeScript\", \"О себе\", \"Работа\"),\n note(\"Работает с TypeScript\", \"О себе\", \"Работа\"),\n note(\"Любит чай\", \"О себе\"),\n ]);\n const run = await claimed(storage);\n const merge = (finishedAt = at(5)) => ({\n runId: run.id,\n finishedAt,\n merges: [\n {\n result: note(\"Пишет на TypeScript на работе\", \"О себе\", \"Работа\"),\n originals: [\n { id: first!.id, version: first!.version },\n { id: second!.id, version: second!.version },\n ],\n },\n ],\n });\n return { first: first!, second: second!, third: third!, run, merge };\n }\n\n describe(\"взятие запуска\", () => {\n it(\"без запусков берёт новый: идёт, начат в назначенное время, склеек и ошибки нет\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const run = await storage.claimMemoryOptimizationRun(\"anna\", rules, at(0));\n expect(run).toMatchObject({ status: \"running\", startedAt: at(0), finishedAt: null, groups: [], error: null, usageRecordId: null });\n expect(typeof run?.id).toBe(\"string\");\n expect(await storage.listMemoryOptimizationRuns(\"anna\")).toEqual([run]);\n });\n\n it(\"пока запуск идёт, второй не берётся\", async (context) => {\n const storage = await storageWithOptimizer(context);\n await claimed(storage, \"anna\", 0);\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(2))).toBeNull();\n expect(await storage.listMemoryOptimizationRuns(\"anna\")).toHaveLength(1);\n });\n\n it(\"просроченный запуск становится неудачным с концом в момент истечения; повтор — после паузы неудачи\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const lost = await claimed(storage, \"anna\", 0);\n // Срок аренды вышел, но пауза после неудачи (час от конца запуска) — ещё нет.\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(10))).toBeNull();\n const [expired] = await storage.listMemoryOptimizationRuns(\"anna\");\n expect(expired).toMatchObject({ id: lost.id, status: \"failed\", error: \"lease_expired\", finishedAt: at(3) });\n // Пауза считается от конца запуска (минута 3), а не от того, когда о нём узнали.\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(3 + 59))).toBeNull();\n const next = await storage.claimMemoryOptimizationRun(\"anna\", rules, at(3 + 60));\n expect(next).toMatchObject({ status: \"running\", startedAt: at(3 + 60) });\n expect(next?.id).not.toBe(lost.id);\n });\n\n it(\"после законченного запуска следующий — не раньше срока между запусками\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const run = await claimed(storage, \"anna\", 0);\n expect(await storage.finishMemoryOptimizationRun(\"anna\", run.id, { status: \"no_changes\", finishedAt: at(1) })).toBe(\"ok\");\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(1 + 24 * 60 - 1))).toBeNull();\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(1 + 24 * 60))).toMatchObject({ status: \"running\" });\n });\n\n it(\"после неудачи повтор — не раньше чем через час, и суточный срок его не ждёт\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const run = await claimed(storage, \"anna\", 0);\n await storage.finishMemoryOptimizationRun(\"anna\", run.id, { status: \"failed\", finishedAt: at(1), error: \"model_error\" });\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(1 + 59))).toBeNull();\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(1 + 60))).toMatchObject({ status: \"running\" });\n });\n\n it(\"неудачи подряд растят паузу (1 ч → 6 ч → 24 ч), а законченный запуск начинает счёт заново\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const ladder: MemoryOptimizationRules = { ...rules, retryAfterFailureMs: [60 * MINUTE, 360 * MINUTE, 1440 * MINUTE] };\n const HOUR = 60;\n async function failAt(start: number) {\n const run = await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(start));\n expect(run).not.toBeNull();\n await storage.finishMemoryOptimizationRun(\"anna\", run!.id, { status: \"failed\", finishedAt: at(start + 1), error: \"model_error\" });\n return start + 1;\n }\n let end = await failAt(0);\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(end + HOUR - 1))).toBeNull();\n end = await failAt(end + HOUR);\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(end + 6 * HOUR - 1))).toBeNull();\n end = await failAt(end + 6 * HOUR);\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(end + 24 * HOUR - 1))).toBeNull();\n end = await failAt(end + 24 * HOUR);\n // Дальше пауза остаётся суточной.\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(end + 24 * HOUR - 1))).toBeNull();\n const success = await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(end + 24 * HOUR));\n await storage.finishMemoryOptimizationRun(\"anna\", success!.id, { status: \"no_changes\", finishedAt: at(end + 24 * HOUR + 1) });\n // После законченного запуска первая же неудача снова ждёт только час.\n const restart = end + 24 * HOUR + 1 + 24 * HOUR;\n const again = await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(restart));\n await storage.finishMemoryOptimizationRun(\"anna\", again!.id, { status: \"failed\", finishedAt: at(restart + 1), error: \"model_error\" });\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(restart + 1 + HOUR - 1))).toBeNull();\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(restart + 1 + HOUR))).toMatchObject({ status: \"running\" });\n });\n\n it(\"просроченный запуск тоже считается неудачей подряд\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const ladder: MemoryOptimizationRules = { ...rules, retryAfterFailureMs: [60 * MINUTE, 360 * MINUTE] };\n await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(0));\n // Аренда вышла в минуту 3, пауза первой неудачи — до минуты 63.\n const second = await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(3 + 60));\n expect(second).not.toBeNull();\n await storage.finishMemoryOptimizationRun(\"anna\", second!.id, { status: \"failed\", finishedAt: at(65), error: \"model_error\" });\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(65 + 359))).toBeNull();\n expect(await storage.claimMemoryOptimizationRun(\"anna\", ladder, at(65 + 360))).toMatchObject({ status: \"running\" });\n });\n\n it(\"слитый и отменённый запуски тоже считаются законченными\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { merge, run } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge(at(5)));\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(60))).toBeNull();\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"ok\");\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(60))).toBeNull();\n expect(await storage.claimMemoryOptimizationRun(\"anna\", rules, at(5 + 24 * 60))).toMatchObject({ status: \"running\" });\n });\n\n it(\"запуски разных людей не мешают друг другу\", async (context) => {\n const storage = await storageWithOptimizer(context);\n await claimed(storage, \"anna\", 0);\n expect(await storage.claimMemoryOptimizationRun(\"boris\", rules, at(0))).toMatchObject({ status: \"running\" });\n expect(await storage.listMemoryOptimizationRuns(\"boris\")).toHaveLength(1);\n });\n\n it(\"несколько одновременных попыток дают ровно один запуск\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const results = await Promise.all(Array.from({ length: 6 }, () => storage.claimMemoryOptimizationRun(\"anna\", rules, at(0))));\n expect(results.filter((run) => run !== null)).toHaveLength(1);\n expect(await storage.listMemoryOptimizationRuns(\"anna\")).toHaveLength(1);\n });\n });\n\n describe(\"закрытие запуска без слияния\", () => {\n it(\"«нечего сливать» и «не удалось» записывают конец, ошибку и расход\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const first = await claimed(storage, \"anna\", 0);\n expect(\n await storage.finishMemoryOptimizationRun(\"anna\", first.id, { status: \"no_changes\", finishedAt: at(1), usageRecordId: \"usage-1\" }),\n ).toBe(\"ok\");\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]).toMatchObject({\n id: first.id,\n status: \"no_changes\",\n finishedAt: at(1),\n error: null,\n usageRecordId: \"usage-1\",\n });\n const second = await claimed(storage, \"anna\", 2000);\n await storage.finishMemoryOptimizationRun(\"anna\", second.id, { status: \"failed\", finishedAt: at(2001), error: \"invalid_proposal\" });\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]).toMatchObject({ id: second.id, status: \"failed\", error: \"invalid_proposal\" });\n });\n\n it(\"чужой, отсутствующий и уже закрытый запуск — not_found и не меняется\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const run = await claimed(storage, \"anna\", 0);\n expect(await storage.finishMemoryOptimizationRun(\"boris\", run.id, { status: \"failed\", finishedAt: at(1), error: \"x\" })).toBe(\"not_found\");\n expect(await storage.finishMemoryOptimizationRun(\"anna\", \"missing\", { status: \"failed\", finishedAt: at(1), error: \"x\" })).toBe(\"not_found\");\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.status).toBe(\"running\");\n await storage.finishMemoryOptimizationRun(\"anna\", run.id, { status: \"no_changes\", finishedAt: at(1) });\n expect(await storage.finishMemoryOptimizationRun(\"anna\", run.id, { status: \"failed\", finishedAt: at(2), error: \"x\" })).toBe(\"not_found\");\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]).toMatchObject({ status: \"no_changes\", finishedAt: at(1) });\n });\n });\n\n describe(\"слияние\", () => {\n it(\"вставляет результат (версия 1), прячет оригиналы, закрывает запуск как слитый со склейкой\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, second, third, run, merge } = await withRun(storage);\n const applied = await storage.applyMemoryMerge(\"anna\", merge(at(5)));\n expect(typeof applied).toBe(\"object\");\n const visible = await storage.listMemoryNotes(\"anna\");\n expect(visible.map((item) => item.content).sort()).toEqual([\"Любит чай\", \"Пишет на TypeScript на работе\"]);\n const result = visible.find((item) => item.content === \"Пишет на TypeScript на работе\")!;\n expect(result).toMatchObject({ version: 1, categories: [\"О себе\", \"Работа\"] });\n expect(applied).toEqual({\n id: run.id,\n startedAt: run.startedAt,\n finishedAt: at(5),\n status: \"applied\",\n groups: [{ resultId: result.id, originalIds: [first.id, second.id], resultVersion: 1 }],\n error: null,\n usageRecordId: null,\n });\n expect(await storage.listMemoryOptimizationRuns(\"anna\")).toEqual([applied]);\n expect(visible.find((item) => item.id === third.id)).toEqual(third);\n });\n\n it(\"скрытые оригиналы читаются отдельным списком с id результата и прежними версией и временем\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, second, merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n const [result] = (await storage.listMemoryNotes(\"anna\")).filter((item) => item.content.endsWith(\"на работе\"));\n const hidden = await storage.listMergedMemoryNotes(\"anna\");\n expect(hidden.map((item) => item.id).sort()).toEqual([first.id, second.id].sort());\n for (const item of hidden) {\n expect(item.mergedInto).toBe(result!.id);\n expect(item).toMatchObject({ version: 1, categories: [\"О себе\", \"Работа\"] });\n }\n expect(await storage.listMergedMemoryNotes(\"boris\")).toEqual([]);\n });\n\n it(\"оригинал, изменённый за время работы модели, — stale_version, и ничего не меняется\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, run, merge } = await withRun(storage);\n await storage.updateMemoryNote(\"anna\", first.id, 1, note(\"Пишет на Rust\", \"О себе\"));\n const before = await storage.listMemoryNotes(\"anna\");\n expect(await storage.applyMemoryMerge(\"anna\", merge())).toBe(\"stale_version\");\n expect(await storage.listMemoryNotes(\"anna\")).toEqual(before);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]).toMatchObject({ id: run.id, status: \"running\", groups: [] });\n });\n\n it(\"оригинал удалён — stale_version\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { second, merge } = await withRun(storage);\n await storage.deleteMemoryNote(\"anna\", second.id, 1);\n expect(await storage.applyMemoryMerge(\"anna\", merge())).toBe(\"stale_version\");\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n });\n\n it(\"оригинал чужой — stale_version, чужая запись цела\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const [theirs] = await storage.insertMemoryNotes(\"boris\", [note(\"Чужая\")]);\n const run = await claimed(storage, \"anna\", 0);\n const merge = { runId: run.id, finishedAt: at(1), merges: [{ result: note(\"Присвоено\"), originals: [{ id: theirs!.id, version: 1 }] }] };\n expect(await storage.applyMemoryMerge(\"anna\", merge)).toBe(\"stale_version\");\n expect(await storage.listMemoryNotes(\"boris\")).toEqual([theirs]);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual([]);\n });\n\n it(\"уже скрытый оригинал вторым слиянием не берётся — stale_version\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n const again = await storage.claimMemoryOptimizationRun(\"anna\", { ...rules, minIntervalMs: 0 }, at(10));\n expect(again).not.toBeNull();\n const second = { runId: again!.id, finishedAt: at(11), merges: [{ result: note(\"Ещё раз\"), originals: [{ id: first.id, version: 1 }] }] };\n expect(await storage.applyMemoryMerge(\"anna\", second)).toBe(\"stale_version\");\n });\n\n it(\"несколько склеек — все или ни одной\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const [a, b, c, d] = await storage.insertMemoryNotes(\"anna\", [note(\"Кот Барсик\"), note(\"Кот по имени Барсик\"), note(\"Живёт на Бали\"), note(\"Живёт на Бали в Чангу\")]);\n await storage.updateMemoryNote(\"anna\", d!.id, 1, note(\"Живёт на Бали, Чангу\"));\n const run = await claimed(storage);\n const before = await storage.listMemoryNotes(\"anna\");\n const outcome = await storage.applyMemoryMerge(\"anna\", {\n runId: run.id,\n finishedAt: at(1),\n merges: [\n { result: note(\"Кот Барсик\"), originals: [{ id: a!.id, version: 1 }, { id: b!.id, version: 1 }] },\n { result: note(\"Живёт на Бали в Чангу\"), originals: [{ id: c!.id, version: 1 }, { id: d!.id, version: 1 }] },\n ],\n });\n expect(outcome).toBe(\"stale_version\");\n expect(await storage.listMemoryNotes(\"anna\")).toEqual(before);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n });\n\n it(\"запуск, которого нет, чужой или уже закрытый, — run_not_active\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, run, merge } = await withRun(storage);\n expect(await storage.applyMemoryMerge(\"anna\", { ...merge(), runId: \"missing\" })).toBe(\"run_not_active\");\n expect(await storage.applyMemoryMerge(\"boris\", merge())).toBe(\"run_not_active\");\n await storage.finishMemoryOptimizationRun(\"anna\", run.id, { status: \"failed\", finishedAt: at(1), error: \"x\" });\n expect(await storage.applyMemoryMerge(\"anna\", merge())).toBe(\"run_not_active\");\n expect((await storage.listMemoryNotes(\"anna\")).find((item) => item.id === first.id)).toBeDefined();\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n });\n\n it(\"негодный вызов — исключение, и ничего не меняется\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, second, run } = await withRun(storage);\n const before = await storage.listMemoryNotes(\"anna\");\n const original = (item: MemoryNote) => ({ id: item.id, version: item.version });\n const bad = [\n { runId: run.id, finishedAt: at(1), merges: [] },\n { runId: run.id, finishedAt: at(1), merges: [{ result: note(\"Пусто\"), originals: [] }] },\n {\n runId: run.id,\n finishedAt: at(1),\n merges: [\n { result: note(\"Раз\"), originals: [original(first), original(second)] },\n { result: note(\"Два\"), originals: [original(first)] },\n ],\n },\n {\n runId: run.id,\n finishedAt: at(1),\n merges: [{ result: { categories: [\"О себе\"], content: null } as unknown as MemoryNoteInput, originals: [original(first), original(second)] }],\n },\n ];\n for (const merge of bad) await expect(storage.applyMemoryMerge(\"anna\", merge)).rejects.toBeInstanceOf(Error);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual(before);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.status).toBe(\"running\");\n });\n });\n\n describe(\"скрытые записи\", () => {\n it(\"правка и удаление скрытой записи — not_found; список её не показывает\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { first, merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n expect(await storage.updateMemoryNote(\"anna\", first.id, 1, note(\"Правка скрытой\"))).toBe(\"not_found\");\n expect(await storage.deleteMemoryNote(\"anna\", first.id, 1)).toBe(\"not_found\");\n expect((await storage.listMemoryNotes(\"anna\")).some((item) => item.id === first.id)).toBe(false);\n expect((await storage.listMergedMemoryNotes(\"anna\")).some((item) => item.id === first.id && item.content === \"Пишет на TypeScript\")).toBe(true);\n });\n\n it(\"удаление результата удаляет и скрытые оригиналы; устаревшая версия ничего не удаляет\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { third, merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n const result = (await storage.listMemoryNotes(\"anna\")).find((item) => item.content.endsWith(\"на работе\"))!;\n expect(await storage.deleteMemoryNote(\"anna\", result.id, 7)).toBe(\"stale_version\");\n expect(await storage.listMergedMemoryNotes(\"anna\")).toHaveLength(2);\n expect(await storage.deleteMemoryNote(\"anna\", result.id, 1)).toBe(\"ok\");\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n expect((await storage.listMemoryNotes(\"anna\")).map((item) => item.id)).toEqual([third.id]);\n });\n\n it(\"стирание памяти убирает скрытые оригиналы и запуски, считает только видимые, чужое не трогает\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n await storage.insertMemoryNotes(\"boris\", [note(\"Борисова\")]);\n const boris = await claimed(storage, \"boris\", 0);\n // Видны: результат и «Любит чай»; скрытых двое — они не считаются.\n expect(await storage.clearMemoryNotes(\"anna\")).toBe(2);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n expect(await storage.listMemoryOptimizationRuns(\"anna\")).toEqual([]);\n expect(await storage.listMemoryNotes(\"boris\")).toHaveLength(1);\n expect(await storage.listMemoryOptimizationRuns(\"boris\")).toEqual([expect.objectContaining({ id: boris.id })]);\n });\n });\n\n describe(\"возврат слияния\", () => {\n it(\"возвращает оригиналы как были, убирает результат, запуск становится отменённым\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run, merge } = await withRun(storage);\n const before = await storage.listMemoryNotes(\"anna\");\n const applied = (await storage.applyMemoryMerge(\"anna\", merge())) as { groups: unknown };\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"ok\");\n expect(await storage.listMemoryNotes(\"anna\")).toEqual(before);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual([]);\n const [reverted] = await storage.listMemoryOptimizationRuns(\"anna\");\n expect(reverted).toMatchObject({ id: run.id, status: \"reverted\", groups: applied.groups });\n expect(reverted?.finishedAt).toBe(at(5));\n });\n\n it(\"результат менялся — conflict, ничего не меняется\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run, merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n const result = (await storage.listMemoryNotes(\"anna\")).find((item) => item.content.endsWith(\"на работе\"))!;\n await storage.updateMemoryNote(\"anna\", result.id, 1, note(\"Пишет на TypeScript в компании\", \"О себе\", \"Работа\"));\n const visible = await storage.listMemoryNotes(\"anna\");\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"conflict\");\n expect(await storage.listMemoryNotes(\"anna\")).toEqual(visible);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toHaveLength(2);\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.status).toBe(\"applied\");\n });\n\n it(\"результат удалён (вместе с оригиналами) — conflict\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run, merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n const result = (await storage.listMemoryNotes(\"anna\")).find((item) => item.content.endsWith(\"на работе\"))!;\n await storage.deleteMemoryNote(\"anna\", result.id, 1);\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"conflict\");\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.status).toBe(\"applied\");\n });\n\n it(\"запуск, которого нет, чужой, идущий, без слияния или уже отменённый, — not_found\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run, merge } = await withRun(storage);\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"not_found\");\n expect(await storage.revertMemoryMerge(\"anna\", \"missing\")).toBe(\"not_found\");\n await storage.applyMemoryMerge(\"anna\", merge());\n expect(await storage.revertMemoryMerge(\"boris\", run.id)).toBe(\"not_found\");\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"ok\");\n expect(await storage.revertMemoryMerge(\"anna\", run.id)).toBe(\"not_found\");\n const quiet = await storageWithOptimizer(context);\n const idle = await claimed(quiet);\n await quiet.finishMemoryOptimizationRun(\"anna\", idle.id, { status: \"no_changes\", finishedAt: at(1) });\n expect(await quiet.revertMemoryMerge(\"anna\", idle.id)).toBe(\"not_found\");\n });\n\n describe(\"проверка пределов при возврате\", () => {\n /** Слияние применено; результат — «… на работе». Гарды пишут, что видели. */\n async function applied(storage: OptimizerStorage) {\n const setup = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", setup.merge());\n return setup;\n }\n\n it(\"проверка видит записи без результатов слияния и оригиналы, что вернутся; пропустила — возврат выполнен\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run, first, second } = await applied(storage);\n const seen: { remaining: string[]; restored: string[] }[] = [];\n const result = await storage.revertMemoryMerge(\"anna\", run.id, (remaining, restored) => {\n seen.push({ remaining: remaining.map((item) => item.content), restored: restored.map((item) => item.id).sort() });\n return null;\n });\n expect(result).toBe(\"ok\");\n expect(seen).toEqual([{ remaining: [\"Любит чай\"], restored: [first.id, second.id].sort() }]);\n expect(await storage.listMemoryNotes(\"anna\")).toHaveLength(3);\n });\n\n for (const kind of [\"limit_reached\", \"duplicate\"] as const) {\n it(`ошибка проверки ${kind} — тот же результат, ничего не изменено, запуск остаётся слитым`, async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run } = await applied(storage);\n const visible = await storage.listMemoryNotes(\"anna\");\n const hidden = await storage.listMergedMemoryNotes(\"anna\");\n expect(await storage.revertMemoryMerge(\"anna\", run.id, () => ({ kind, message: \"Нельзя\" }))).toBe(kind);\n expect(await storage.listMemoryNotes(\"anna\")).toEqual(visible);\n expect(await storage.listMergedMemoryNotes(\"anna\")).toEqual(hidden);\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.status).toBe(\"applied\");\n // Место освободили — тот же возврат теперь проходит.\n expect(await storage.revertMemoryMerge(\"anna\", run.id, () => null)).toBe(\"ok\");\n });\n }\n\n it(\"проверка не зовётся, если возврат невозможен: конфликт, чужой или несуществующий запуск\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { run } = await applied(storage);\n const result = (await storage.listMemoryNotes(\"anna\")).find((item) => item.content.endsWith(\"на работе\"))!;\n await storage.updateMemoryNote(\"anna\", result.id, 1, note(\"Пишет на TypeScript в компании\", \"О себе\", \"Работа\"));\n let calls = 0;\n const guard = () => {\n calls += 1;\n return null;\n };\n expect(await storage.revertMemoryMerge(\"anna\", run.id, guard)).toBe(\"conflict\");\n expect(await storage.revertMemoryMerge(\"boris\", run.id, guard)).toBe(\"not_found\");\n expect(await storage.revertMemoryMerge(\"anna\", \"missing\", guard)).toBe(\"not_found\");\n expect(calls).toBe(0);\n });\n });\n });\n\n describe(\"список запусков\", () => {\n it(\"новейшие первыми, с отбором по состоянию и числу; чужих нет\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const day = 24 * 60;\n const oldest = await claimed(storage, \"anna\", 0);\n await storage.finishMemoryOptimizationRun(\"anna\", oldest.id, { status: \"no_changes\", finishedAt: at(1) });\n const middle = await claimed(storage, \"anna\", 2 * day);\n await storage.finishMemoryOptimizationRun(\"anna\", middle.id, { status: \"failed\", finishedAt: at(2 * day + 1), error: \"x\" });\n const newest = await claimed(storage, \"anna\", 4 * day);\n await claimed(storage, \"boris\", 0);\n expect((await storage.listMemoryOptimizationRuns(\"anna\")).map((run) => run.id)).toEqual([newest.id, middle.id, oldest.id]);\n expect((await storage.listMemoryOptimizationRuns(\"anna\", { limit: 2 })).map((run) => run.id)).toEqual([newest.id, middle.id]);\n expect((await storage.listMemoryOptimizationRuns(\"anna\", { status: [\"failed\", \"no_changes\"] })).map((run) => run.id)).toEqual([middle.id, oldest.id]);\n expect(await storage.listMemoryOptimizationRuns(\"anna\", { status: [\"reverted\"] })).toEqual([]);\n expect(await storage.listMemoryOptimizationRuns(\"clara\")).toEqual([]);\n });\n\n it(\"отданные запуски и скрытые записи — копии\", async (context) => {\n const storage = await storageWithOptimizer(context);\n const { merge } = await withRun(storage);\n await storage.applyMemoryMerge(\"anna\", merge());\n const [run] = await storage.listMemoryOptimizationRuns(\"anna\");\n run!.groups[0]!.originalIds.push(\"лишний\");\n run!.groups.push({ resultId: \"x\", originalIds: [], resultVersion: 1 });\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.groups).toHaveLength(1);\n expect((await storage.listMemoryOptimizationRuns(\"anna\"))[0]?.groups[0]?.originalIds).toHaveLength(2);\n const [hidden] = await storage.listMergedMemoryNotes(\"anna\");\n hidden!.categories.push(\"Лишний\");\n expect((await storage.listMergedMemoryNotes(\"anna\"))[0]?.categories).toEqual([\"О себе\", \"Работа\"]);\n });\n });\n });\n });\n}\n\n/** Модель для проверок виджета: первый запрос в каждом чате — вызов ask_choice, дальше — короткий текст. */\nfunction widgetModel() {\n const usage = { inputTokens: { total: 10, noCache: 10, cacheRead: 0, cacheWrite: 0 }, outputTokens: { total: 2, text: 2, reasoning: 0 } };\n const finish = (reason: \"stop\" | \"tool-calls\") => ({ type: \"finish\", finishReason: { unified: reason, raw: reason }, usage });\n const asked = (prompt: unknown) => JSON.stringify(prompt).includes('\"tool-result\"');\n return {\n specificationVersion: \"v4\",\n provider: \"contract\",\n modelId: \"contract-v1\",\n supportedUrls: {},\n doGenerate: async () => {\n throw new Error(\"Проверкам виджета doGenerate не нужен\");\n },\n doStream: async ({ prompt }: { prompt: unknown }) => {\n const parts = asked(prompt)\n ? [{ type: \"text-start\", id: \"t\" }, { type: \"text-delta\", id: \"t\", delta: \"Готово\" }, { type: \"text-end\", id: \"t\" }, finish(\"stop\")]\n : [{ type: \"tool-call\", toolCallId: \"w1\", toolName: \"ask_choice\", input: JSON.stringify({ question: \"Какой тариф?\", options: [\"Базовый\", \"Про\"] }) }, finish(\"tool-calls\")];\n return {\n stream: new ReadableStream({\n start(controller) {\n for (const part of [{ type: \"stream-start\", warnings: [] }, ...parts]) controller.enqueue(part);\n controller.close();\n },\n }),\n };\n },\n };\n}\n\nconst widgetQuestion = (id = \"u1\") => ({ id, role: \"user\" as const, parts: [{ type: \"text\" as const, text: \"помоги выбрать тариф\" }] });\n\n/** Служба чата с базовыми виджетами на этом хранилище: как отдельная копия сервера. */\nfunction widgetService(storage: ChatStorage): ChatService {\n const model = widgetModel();\n const catalog = extendCatalog(standardCatalog, {\n addProviders: [\n {\n id: \"contract\",\n displayName: \"contract\",\n apiKeyEnv: \"CONTRACT_API_KEY\",\n createLanguageModel: () => model as never,\n requestOptions: () => ({}),\n },\n ],\n addModels: [\n {\n id: \"contract-model\",\n displayName: \"Contract Model\",\n contextWindowTokens: 100_000,\n acceptsImages: false,\n reasoning: { replayPastTurns: true },\n providerModelIds: { contract: \"contract-v1\" },\n },\n ],\n });\n return createChatService({\n storage,\n catalog,\n defaultChoice: { modelId: \"contract-model\", providerId: \"contract\" },\n agent: { instructions: \"Ты помощник.\", widgets: { basic: true } },\n env: { CONTRACT_API_KEY: \"не-настоящий-ключ\" },\n logError: () => {},\n });\n}\n\n/** Служба с инструментом поиска: первый шаг ответа вызывает `find`, второй — пишет текст. Запросы к модели копятся в `prompts`. */\nfunction editAnswerService(storage: ChatStorage, lockedToolOutputs?: readonly string[]): { service: ChatService; prompts: unknown[] } {\n const prompts: unknown[] = [];\n const usage = { inputTokens: { total: 10, noCache: 10, cacheRead: 0, cacheWrite: 0 }, outputTokens: { total: 5, text: 5, reasoning: 0 } };\n const finish = (reason: \"stop\" | \"tool-calls\") => ({ type: \"finish\", finishReason: { unified: reason, raw: reason }, usage });\n const text = (id: string, delta: string) => [{ type: \"text-start\", id }, { type: \"text-delta\", id, delta }, { type: \"text-end\", id }];\n const model = {\n specificationVersion: \"v4\",\n provider: \"contract\",\n modelId: \"contract-v1\",\n supportedUrls: {},\n doGenerate: async () => {\n throw new Error(\"Проверкам правки ответа doGenerate не нужен\");\n },\n doStream: async ({ prompt }: { prompt: readonly { role: string }[] }) => {\n prompts.push(prompt);\n const parts =\n prompt.at(-1)?.role === \"tool\"\n ? [...text(\"t2\", \"Нашёл отчёт.\"), finish(\"stop\")]\n : [...text(\"t1\", \"Ищу отчёт.\"), { type: \"tool-call\", toolCallId: prompts.length === 1 ? \"f1\" : `f${prompts.length}`, toolName: \"find\", input: JSON.stringify({ name: \"отчёт\" }) }, finish(\"tool-calls\")];\n return {\n stream: new ReadableStream({\n start(controller) {\n for (const part of [{ type: \"stream-start\", warnings: [] }, ...parts]) controller.enqueue(part);\n controller.close();\n },\n }),\n };\n },\n };\n const catalog = extendCatalog(standardCatalog, {\n addProviders: [\n {\n id: \"contract\",\n displayName: \"contract\",\n apiKeyEnv: \"CONTRACT_API_KEY\",\n createLanguageModel: () => model as never,\n requestOptions: () => ({}),\n },\n ],\n addModels: [\n {\n id: \"contract-model\",\n displayName: \"Contract Model\",\n contextWindowTokens: 100_000,\n acceptsImages: false,\n reasoning: { replayPastTurns: true },\n providerModelIds: { contract: \"contract-v1\" },\n },\n ],\n });\n const find = {\n description: \"Найти файл\",\n inputSchema: jsonSchema<{ name: string }>({ type: \"object\", properties: { name: { type: \"string\" } }, required: [\"name\"] }),\n execute: async () => \"нашёл: отчёт.pdf\",\n };\n const service = createChatService({\n storage,\n catalog,\n defaultChoice: { modelId: \"contract-model\", providerId: \"contract\" },\n agent: { instructions: \"Ты помощник.\", tools: { find } },\n env: { CONTRACT_API_KEY: \"не-настоящий-ключ\" },\n logError: () => {},\n ...(lockedToolOutputs && { lockedToolOutputs }),\n });\n return { service, prompts };\n}\n\nasync function drain(stream: ReadableStream<unknown>): Promise<void> {\n const reader = stream.getReader();\n while (!(await reader.read()).done);\n}\n"],"mappings":"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","names":[]}
|