@ykurilov/agent-chat-flows 0.0.0-stage → 0.55.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.
Files changed (151) hide show
  1. package/CHANGELOG.md +252 -0
  2. package/LICENSE +21 -0
  3. package/README.md +124 -2
  4. package/agent-flow.schema.json +1020 -0
  5. package/dist/chunk-3PTJI2XY.js +100 -0
  6. package/dist/chunk-3PTJI2XY.js.map +1 -0
  7. package/dist/chunk-BNMQUNSI.js +9 -0
  8. package/dist/chunk-BNMQUNSI.js.map +1 -0
  9. package/dist/chunk-BOV6FJGU.js +1288 -0
  10. package/dist/chunk-BOV6FJGU.js.map +1 -0
  11. package/dist/chunk-CKY5KG7N.js +165 -0
  12. package/dist/chunk-CKY5KG7N.js.map +1 -0
  13. package/dist/chunk-DCTRMCGV.js +34 -0
  14. package/dist/chunk-DCTRMCGV.js.map +1 -0
  15. package/dist/format.js +147 -0
  16. package/dist/format.js.map +1 -0
  17. package/dist/index.js +3197 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/postgres.js +387 -0
  20. package/dist/postgres.js.map +1 -0
  21. package/dist/react.js +2650 -0
  22. package/dist/react.js.map +1 -0
  23. package/dist/sqlite.js +319 -0
  24. package/dist/sqlite.js.map +1 -0
  25. package/dist/types/check/app-checks.d.ts +16 -0
  26. package/dist/types/check/check-flow.d.ts +8 -0
  27. package/dist/types/check/index.d.ts +2 -0
  28. package/dist/types/engine/data-conditions.d.ts +10 -0
  29. package/dist/types/engine/day-frame.d.ts +17 -0
  30. package/dist/types/engine/first-messages.d.ts +21 -0
  31. package/dist/types/engine/flow-days.d.ts +39 -0
  32. package/dist/types/engine/flow-graph.d.ts +26 -0
  33. package/dist/types/engine/flow-run.d.ts +130 -0
  34. package/dist/types/engine/index.d.ts +14 -0
  35. package/dist/types/engine/migrate-run.d.ts +11 -0
  36. package/dist/types/engine/next-transition.d.ts +40 -0
  37. package/dist/types/engine/nudges.d.ts +78 -0
  38. package/dist/types/engine/run-updates.d.ts +37 -0
  39. package/dist/types/engine/side-questions.d.ts +26 -0
  40. package/dist/types/engine/side-tasks.d.ts +44 -0
  41. package/dist/types/engine/targets.d.ts +9 -0
  42. package/dist/types/engine/timers.d.ts +61 -0
  43. package/dist/types/engine/zoned-time.d.ts +27 -0
  44. package/dist/types/format/catalog-events.d.ts +5 -0
  45. package/dist/types/format/compact-flow.d.ts +8 -0
  46. package/dist/types/format/flow-format.d.ts +286 -0
  47. package/dist/types/format/flow-json-schema.d.ts +2 -0
  48. package/dist/types/format/flow-schema.d.ts +605 -0
  49. package/dist/types/format/index.d.ts +7 -0
  50. package/dist/types/format/migrate-flow.d.ts +4 -0
  51. package/dist/types/format/parse-flow.d.ts +6 -0
  52. package/dist/types/format.d.ts +3 -0
  53. package/dist/types/index.d.ts +4 -0
  54. package/dist/types/labels/client-card.d.ts +20 -0
  55. package/dist/types/labels/editor.d.ts +261 -0
  56. package/dist/types/labels/index.d.ts +14 -0
  57. package/dist/types/labels/migrate.d.ts +19 -0
  58. package/dist/types/labels/test-chat.d.ts +28 -0
  59. package/dist/types/not-yet.d.ts +2 -0
  60. package/dist/types/postgres.d.ts +10 -0
  61. package/dist/types/prompt/client-card-block.d.ts +16 -0
  62. package/dist/types/prompt/flow-rules.d.ts +9 -0
  63. package/dist/types/prompt/rules/after-end.d.ts +3 -0
  64. package/dist/types/prompt/rules/client-facts.d.ts +2 -0
  65. package/dist/types/prompt/rules/day-frame.d.ts +2 -0
  66. package/dist/types/prompt/rules/link-views.d.ts +4 -0
  67. package/dist/types/prompt/rules/rule-part.d.ts +3 -0
  68. package/dist/types/prompt/rules/side-tasks.d.ts +2 -0
  69. package/dist/types/prompt/rules/time-zone.d.ts +2 -0
  70. package/dist/types/prompt/state-card.d.ts +14 -0
  71. package/dist/types/react/client-card/client-card-panel.d.ts +8 -0
  72. package/dist/types/react/client-card/index.d.ts +2 -0
  73. package/dist/types/react/client-card/use-client-card.d.ts +19 -0
  74. package/dist/types/react/client-card-skin.d.ts +27 -0
  75. package/dist/types/react/editor/board-space.d.ts +51 -0
  76. package/dist/types/react/editor/board-styles.d.ts +1 -0
  77. package/dist/types/react/editor/editor-model.d.ts +60 -0
  78. package/dist/types/react/editor/exit-text.d.ts +11 -0
  79. package/dist/types/react/editor/flow-board.d.ts +11 -0
  80. package/dist/types/react/editor/flow-editor.d.ts +13 -0
  81. package/dist/types/react/editor/flow-simulation.d.ts +44 -0
  82. package/dist/types/react/editor/index.d.ts +6 -0
  83. package/dist/types/react/editor/schedule-model.d.ts +47 -0
  84. package/dist/types/react/editor/side-task-model.d.ts +18 -0
  85. package/dist/types/react/editor/use-flow-editor.d.ts +120 -0
  86. package/dist/types/react/flow-editor-skin.d.ts +453 -0
  87. package/dist/types/react/flow-labels.d.ts +8 -0
  88. package/dist/types/react/index.d.ts +6 -0
  89. package/dist/types/react/test-chat/flow-test-chat.d.ts +22 -0
  90. package/dist/types/react/test-chat/index.d.ts +2 -0
  91. package/dist/types/react/test-chat/use-flow-test-chat.d.ts +50 -0
  92. package/dist/types/react.d.ts +3 -0
  93. package/dist/types/runtime/admit.d.ts +15 -0
  94. package/dist/types/runtime/agent-flow.d.ts +20 -0
  95. package/dist/types/runtime/client-card.d.ts +9 -0
  96. package/dist/types/runtime/client-facts.d.ts +22 -0
  97. package/dist/types/runtime/close-day-tool.d.ts +3 -0
  98. package/dist/types/runtime/decisions-client.d.ts +33 -0
  99. package/dist/types/runtime/extra-tool.d.ts +16 -0
  100. package/dist/types/runtime/first-message-retry.d.ts +4 -0
  101. package/dist/types/runtime/first-message-rules.d.ts +55 -0
  102. package/dist/types/runtime/first-reasons-notice.d.ts +9 -0
  103. package/dist/types/runtime/flow-delivery.d.ts +53 -0
  104. package/dist/types/runtime/flow-events.d.ts +126 -0
  105. package/dist/types/runtime/flow-finish.d.ts +68 -0
  106. package/dist/types/runtime/flow-known-texts.d.ts +11 -0
  107. package/dist/types/runtime/flow-signals.d.ts +12 -0
  108. package/dist/types/runtime/flow-timers.d.ts +55 -0
  109. package/dist/types/runtime/flow-tools.d.ts +23 -0
  110. package/dist/types/runtime/flow-types.d.ts +547 -0
  111. package/dist/types/runtime/held-messages.d.ts +25 -0
  112. package/dist/types/runtime/index.d.ts +11 -0
  113. package/dist/types/runtime/judge-context.d.ts +36 -0
  114. package/dist/types/runtime/judge.d.ts +21 -0
  115. package/dist/types/runtime/migrate-chats.d.ts +20 -0
  116. package/dist/types/runtime/note-tools.d.ts +15 -0
  117. package/dist/types/runtime/pause.d.ts +21 -0
  118. package/dist/types/runtime/prepare-turn.d.ts +12 -0
  119. package/dist/types/runtime/side-task-tool.d.ts +5 -0
  120. package/dist/types/runtime/step-tail.d.ts +11 -0
  121. package/dist/types/runtime/tail/day-line.d.ts +2 -0
  122. package/dist/types/runtime/tail/frame-line.d.ts +2 -0
  123. package/dist/types/runtime/tail/side-tasks-line.d.ts +2 -0
  124. package/dist/types/runtime/tail/tail-part.d.ts +21 -0
  125. package/dist/types/runtime/test-clock.d.ts +26 -0
  126. package/dist/types/runtime/time-zone-tool.d.ts +3 -0
  127. package/dist/types/runtime/turn-gate.d.ts +8 -0
  128. package/dist/types/sqlite.d.ts +9 -0
  129. package/dist/types/store/flow-store-shared.d.ts +20 -0
  130. package/dist/types/store/flow-store.d.ts +240 -0
  131. package/dist/types/store/memory.d.ts +3 -0
  132. package/dist/types/store/migration-settings.d.ts +7 -0
  133. package/dist/types/store/postgres-schema.d.ts +775 -0
  134. package/dist/types/store/postgres.d.ts +15 -0
  135. package/dist/types/store/sqlite-schema.d.ts +824 -0
  136. package/dist/types/store/sqlite.d.ts +9 -0
  137. package/drizzle/postgres/0000_init.sql +45 -0
  138. package/drizzle/postgres/0001_days_pause_side_tasks.sql +21 -0
  139. package/drizzle/postgres/0002_chat_placement.sql +1 -0
  140. package/drizzle/postgres/meta/0000_snapshot.json +317 -0
  141. package/drizzle/postgres/meta/0001_snapshot.json +439 -0
  142. package/drizzle/postgres/meta/0002_snapshot.json +445 -0
  143. package/drizzle/postgres/meta/_journal.json +27 -0
  144. package/drizzle/sqlite/0000_init.sql +44 -0
  145. package/drizzle/sqlite/0001_days_pause_side_tasks.sql +21 -0
  146. package/drizzle/sqlite/0002_chat_placement.sql +1 -0
  147. package/drizzle/sqlite/meta/0000_snapshot.json +297 -0
  148. package/drizzle/sqlite/meta/0001_snapshot.json +427 -0
  149. package/drizzle/sqlite/meta/0002_snapshot.json +434 -0
  150. package/drizzle/sqlite/meta/_journal.json +27 -0
  151. package/package.json +98 -3
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/format/flow-json-schema.ts","../src/engine/first-messages.ts","../src/engine/migrate-run.ts","../src/engine/day-frame.ts","../src/engine/side-tasks.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { agentFlowSchema } from \"./flow-schema\";\n\n/** JSON Schema сценария (то, что пишет автор: значения по умолчанию необязательны). Лежит в пакете: `agent-flow.schema.json`. */\nexport function flowJsonSchema(): Record<string, unknown> {\n return {\n ...z.toJSONSchema(agentFlowSchema, { io: \"input\", unrepresentable: \"any\" }),\n $id: \"https://github.com/ykurilov/agent-chat-sdk/packages/flows/agent-flow.schema.json\",\n title: \"Сценарий поведения агента (agent-flow)\",\n };\n}\n","import { DEFAULT_FIRST_MESSAGES, type FirstMessagesRules, type FirstMessagesSetting } from \"./flow-run\";\nimport { clockMinutes, nextClockTime, parseClock, startOfNextDay } from \"./zoned-time\";\n\nexport { localDay } from \"./zoned-time\";\n\nexport interface FirstMessageInput {\n /** Когда агент хочет написать, мс. */\n at: number;\n timeZone: string;\n /** Сколько уже написал первым за эти сутки человека (`localDay`). */\n sentToday: number;\n}\n\n/** Настройка приложения поверх значений SDK (→ В10). `false` — правила выключены: `null`, агент пишет первым без ограничений. */\nexport function resolveFirstMessages(setting: FirstMessagesSetting | undefined): FirstMessagesRules | null {\n if (setting === false) return null;\n const rules: FirstMessagesRules = {\n quietHours: { ...DEFAULT_FIRST_MESSAGES.quietHours, ...setting?.quietHours },\n maxPerDay: setting?.maxPerDay ?? DEFAULT_FIRST_MESSAGES.maxPerDay,\n ...(setting?.canWriteNow ? { canWriteNow: setting.canWriteNow } : {}),\n };\n for (const clock of [rules.quietHours.from, rules.quietHours.to]) {\n if (parseClock(clock) === null) throw new Error(`Тихие часы пишутся как «ЧЧ:ММ», например «21:00», а не «${clock}».`);\n }\n return rules;\n}\n\ntype QuietHours = FirstMessagesRules[\"quietHours\"];\n\n/** Тихо ли сейчас на часах человека. Тихие часы могут идти через полночь; `from` = `to` — тихих часов нет. */\nfunction isQuiet(quietHours: QuietHours, at: number, timeZone: string): boolean {\n const from = parseClock(quietHours.from)!;\n const to = parseClock(quietHours.to)!;\n const now = clockMinutes(at, timeZone);\n if (from === to) return false;\n return from < to ? now >= from && now < to : now >= from || now < to;\n}\n\n/** Первый момент от `at`, когда не тихо. */\nfunction firstAwake(quietHours: QuietHours, at: number, timeZone: string): number {\n return isQuiet(quietHours, at, timeZone) ? nextClockTime(at, parseClock(quietHours.to)!, timeZone) : at;\n}\n\n/**\n * Можно ли написать первым сейчас; нет — на когда перенести. Тихие часы → их конец. Потолок за сутки исчерпан →\n * следующие сутки человека, после тихих часов.\n */\nexport function firstMessageSlot(\n rules: Omit<FirstMessagesRules, \"canWriteNow\">,\n input: FirstMessageInput,\n): { allowed: true } | { allowed: false; retryAt: number } {\n const { at, timeZone } = input;\n if (input.sentToday >= rules.maxPerDay) {\n return { allowed: false, retryAt: firstAwake(rules.quietHours, startOfNextDay(at, timeZone), timeZone) };\n }\n const awake = firstAwake(rules.quietHours, at, timeZone);\n return awake === at ? { allowed: true } : { allowed: false, retryAt: awake };\n}\n","import type { AgentFlow } from \"../format/flow-format\";\nimport type { FlowRun } from \"./flow-run\";\nimport { stateById } from \"./flow-graph\";\nimport { appendPath } from \"./run-updates\";\n\n/** Куда перевести чаты из состояний, которых нет в новой версии: id старого → id нового. */\nexport type StateMap = Record<string, string>;\n\n/**\n * Переводит чат на новую версию сценария (→ В11). Состояние есть в новой версии — часы и путь целы. Удалено — вход в\n * состояние из `map`; без цели — ошибка (её ловит перевод чатов раньше). Заметки чата — по совпадающим `id`.\n * Удалённые состояния в пути и в остановленных часах переименовываются по `map`: так «назад» ведёт туда, куда автор\n * отправил удалённое состояние.\n */\nexport function migrateRun(run: FlowRun, next: AgentFlow, map: StateMap, now: number): FlowRun {\n const exists = (id: string) => stateById(next, id) !== undefined;\n const renamed = (id: string) => (!exists(id) && map[id] !== undefined && exists(map[id]) ? map[id] : id);\n const noteIds = new Set(next.chatNotes.map((field) => field.id));\n const notes = Object.fromEntries(Object.entries(run.notes).filter(([id]) => noteIds.has(id)));\n const path = run.path.map((entry) => ({ ...entry, state: renamed(entry.state), from: entry.from === null ? null : renamed(entry.from) }));\n const pausedClocks = Object.fromEntries(\n Object.entries(run.pausedClocks)\n .map(([id, ms]) => [renamed(id), ms] as const)\n .filter(([id]) => exists(id)),\n );\n if (exists(run.state)) return { ...run, path, pausedClocks, notes };\n\n const targetId = map[run.state];\n if (targetId === undefined) {\n throw new Error(`Состояния «${run.state}» нет в новой версии сценария «${next.id}», а куда перевести чат — не выбрано.`);\n }\n const target = stateById(next, targetId);\n if (!target) throw new Error(`Состояния «${targetId}» нет в новой версии сценария «${next.id}»: туда не перевести чат из «${run.state}».`);\n return {\n ...run,\n state: target.id,\n enteredAt: now,\n pausedClocks: {},\n notes,\n path: appendPath(path, { state: target.id, at: now, tags: target.tags, from: run.state, exitId: null, decidedBy: \"migrate\" }),\n lastRejected: null,\n };\n}\n","import type { FlowSchedule } from \"../format/flow-format\";\nimport type { FlowRun } from \"./flow-run\";\nimport { dayInProgress } from \"./flow-days\";\n\n// Рамки дня по числу сообщений человека за день сценария, по plan.md, «Рамки дня и решение о входящем». Чистые функции.\n\n/** `normal` — как обычно; `soft` — сворачиваться (строка хвоста); `last` — готовая фраза `hardText`; `closed` — молчать до утра. */\nexport type FrameState = \"normal\" | \"soft\" | \"last\" | \"closed\";\n\n/** Готовая фраза жёсткой рамки, если автор свою не задал. */\nexport const DEFAULT_HARD_FRAME_TEXT = \"На сегодня всё — утром обязательно отвечу!\";\n\n/**\n * Состояние рамки дня для `humanMessagesToday`-го сообщения человека за день сценария: на `hardAt`-м — готовая фраза,\n * после — молчание; с `softFrom`-го — сворачиваться. Рамок нет — `normal`.\n */\nexport function frameState(humanMessagesToday: number, frame: FlowSchedule[\"dayFrame\"]): FrameState {\n if (!frame) return \"normal\";\n const { softFrom, hardAt } = frame;\n if (hardAt !== undefined && humanMessagesToday > hardAt) return \"closed\";\n if (hardAt !== undefined && humanMessagesToday === hardAt) return \"last\";\n if (softFrom !== undefined && humanMessagesToday >= softFrom) return \"soft\";\n return \"normal\";\n}\n\n/** Готовая фраза жёсткой рамки: автора, иначе по умолчанию. */\nexport function hardFrameText(frame: FlowSchedule[\"dayFrame\"]): string {\n return frame?.hardText?.trim() || DEFAULT_HARD_FRAME_TEXT;\n}\n\n/** Сколько сообщений человека уже посчитано за день сценария, который идёт в `at` (`run.dayCounts`). */\nexport function humanMessagesToday(run: FlowRun, at: number, timeZone: string, schedule: FlowSchedule): number {\n return run.dayCounts?.[dayInProgress(at, timeZone, schedule)] ?? 0;\n}\n\n/** Человек закрыл день (`flow_close_day`, запись `dayClosedOn`), и этот день ещё идёт: сегодня первым не пишем. */\nexport function dayClosedToday(dayClosedOn: string | null, at: number, timeZone: string, schedule: FlowSchedule): boolean {\n return dayClosedOn !== null && dayClosedOn === dayInProgress(at, timeZone, schedule);\n}\n","import { DEFAULT_SIDE_TASK_MAX_ATTEMPTS, type AgentFlow, type FlowSideTask } from \"../format/flow-format\";\nimport type { FlowRun } from \"./flow-run\";\nimport { fieldValueFits } from \"./data-conditions\";\nimport { fieldById, isFinal, stateById } from \"./flow-graph\";\n\n// Попутные задачи: дела между делом («предложить подписаться на канал»). Темп общий с вопросами о человеке\n// (`pace.sideQuestionEveryMessages`), попыток у задачи не больше `maxAttempts`, решённая не всплывает.\n\n/** Попытки задачи, как их отдаёт хранилище: на человека (`chatId: null`) или на разговор. */\nexport interface SideTaskAttempts {\n taskId: string;\n chatId: string | null;\n asks: number;\n doneAt: string | null;\n}\n\n/** Встроенная задача: пока пояс человека неизвестен, в первый день до ночи узнать город (В1). Первая по важности. */\nexport const TIME_ZONE_TASK_ID = \"ask_time_zone\";\nexport const TIME_ZONE_TASK: FlowSideTask = {\n id: TIME_ZONE_TASK_ID,\n text: \"Узнай, из какого человек города, чтобы писать ему в удобное время. Узнал город — запиши его пояс через «flow_time_zone» и отметь задачу решённой.\",\n when: \"в первый день, до ночи; например: «Кстати, вы откуда? Хочу писать вам в удобное время»\",\n maxAttempts: DEFAULT_SIDE_TASK_MAX_ATTEMPTS,\n perConversation: false,\n};\n\n/** Задача по id: встроенная «узнать город» — только у сценария с «Днями и временем», иначе задача сценария. */\nexport function sideTaskById(flow: AgentFlow, id: string): FlowSideTask | undefined {\n if (id === TIME_ZONE_TASK_ID && flow.schedule) return TIME_ZONE_TASK;\n return flow.sideTasks?.find((task) => task.id === id);\n}\n\n/** Есть ли у сценария попутные задачи: свои или встроенная. Нет — ни инструмента, ни правила, ни строки (как в 0.48). */\nexport const hasSideTasks = (flow: AgentFlow) => flow.schedule !== undefined || (flow.sideTasks?.length ?? 0) > 0;\n\nexport interface SideTaskContext {\n flow: AgentFlow;\n run: FlowRun;\n /** Разговор, в котором идёт ход: по нему считаются попытки задач «заново в каждом разговоре». */\n chatId: string;\n attempts: readonly SideTaskAttempts[];\n /** Значения карточки клиента по `id` поля. Заметки чата берутся из `run.notes`. */\n card: Readonly<Record<string, unknown>>;\n /** Пояс человека неизвестен, а сегодня его первый день до первой ночи: тогда открыта встроенная задача «узнать город». Отдаёт этап 4. */\n askTimeZone?: boolean;\n}\n\nexport type OpenSideTasksInput = SideTaskContext;\n\n/** Решена ли задача: отмечена или её поле уже известно. Потрачена ли: попытки кончились. Иначе — открыта. */\nexport type SideTaskStanding = \"open\" | \"done\" | \"spent\";\n\n/** Попытки задачи: на человека — запись без разговора, у «заново в каждом разговоре» — запись этого разговора. */\nexport function sideTaskRecord(task: FlowSideTask, chatId: string, attempts: readonly SideTaskAttempts[]): SideTaskAttempts | undefined {\n const owner = task.perConversation ? chatId : null;\n return attempts.find((record) => record.taskId === task.id && record.chatId === owner);\n}\n\n/** Известно ли поле задачи: значение подходит типу поля. Поля нет в сценарии — не известно. */\nexport function sideTaskFieldKnown(task: FlowSideTask, context: Pick<SideTaskContext, \"flow\" | \"run\" | \"card\">): boolean {\n if (task.field === undefined) return false;\n const found = fieldById(context.flow, task.field);\n if (!found) return false;\n return fieldValueFits(found.field, found.place === \"notes\" ? context.run.notes[task.field] : context.card[task.field]);\n}\n\n/** Где задача сейчас — без учёта темпа и места в сценарии. */\nexport function sideTaskStanding(task: FlowSideTask, context: SideTaskContext): SideTaskStanding {\n const record = sideTaskRecord(task, context.chatId, context.attempts);\n if (record?.doneAt || sideTaskFieldKnown(task, context)) return \"done\";\n return (record?.asks ?? 0) >= task.maxAttempts ? \"spent\" : \"open\";\n}\n\n/** Прошло ли с прошлого вопроса или задачи между делом столько сообщений человека, сколько велит `pace`. */\nexport function sideTaskPaceReached(flow: AgentFlow, run: FlowRun): boolean {\n return run.sideQuestionAt === null || run.humanMessages - run.sideQuestionAt >= flow.pace.sideQuestionEveryMessages;\n}\n\n/**\n * Задачи, которые агент может предложить сейчас: открытые, и только если темп позволяет, состояние не «без вопросов» и\n * сценарий не кончился. Порядок — как в сценарии. Встроенная «узнать город» — первой и вне общего темпа: у неё только\n * первый день до ночи. Задач нет — пусто, как в 0.48.\n */\nexport function openSideTasks(input: OpenSideTasksInput): FlowSideTask[] {\n const { flow, run } = input;\n const state = stateById(flow, run.state);\n if (!state || isFinal(state) || state.noSideQuestions) return [];\n const askCity = input.askTimeZone === true && flow.schedule !== undefined && sideTaskStanding(TIME_ZONE_TASK, input) === \"open\";\n const own = sideTaskPaceReached(flow, run) ? (flow.sideTasks ?? []).filter((task) => sideTaskStanding(task, input) === \"open\") : [];\n return askCity ? [TIME_ZONE_TASK, ...own] : own;\n}\n"],"mappings":"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","names":["humanMessagesToday"]}
@@ -0,0 +1,34 @@
1
+ // src/store/flow-store-shared.ts
2
+ function migratePending(input) {
3
+ return { kind: "migrate", key: `migrate:${input.toVersionId}:${input.at}`, versionId: input.toVersionId, map: input.map, at: input.at };
4
+ }
5
+ var appliedInTime = (change) => change.kind === "transition" && change.appliedAt !== void 0;
6
+ function pendingAdded(pending, change) {
7
+ const index = pending.findIndex((item) => item.key === change.key);
8
+ if (index === -1) return [...pending, change];
9
+ const existing = pending[index];
10
+ if (existing.kind !== "transition" || change.kind !== "transition" || change.appliedAt === void 0 || existing.appliedAt !== void 0) return null;
11
+ return pending.map((item, at) => at === index ? { ...existing, appliedAt: change.appliedAt } : item);
12
+ }
13
+ var mappedState = (stateId, map) => Object.hasOwn(map, stateId) ? map[stateId] : stateId;
14
+ var byVersionAndState = (left, right) => compareText(left.versionId, right.versionId) || compareText(left.stateId, right.stateId);
15
+ var compareText = (left, right) => left < right ? -1 : left > right ? 1 : 0;
16
+ var normalizeTime = (iso) => new Date(iso).toISOString();
17
+ function withoutNul(value) {
18
+ if (value === null || value === void 0) return value;
19
+ if (typeof value === "string") return value.replaceAll("\0", "");
20
+ if (typeof value !== "object") return value;
21
+ return JSON.parse(JSON.stringify(value, (_key, item) => typeof item === "string" ? item.replaceAll("\0", "") : item));
22
+ }
23
+
24
+ export {
25
+ migratePending,
26
+ appliedInTime,
27
+ pendingAdded,
28
+ mappedState,
29
+ byVersionAndState,
30
+ compareText,
31
+ normalizeTime,
32
+ withoutNul
33
+ };
34
+ //# sourceMappingURL=chunk-DCTRMCGV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/store/flow-store-shared.ts"],"sourcesContent":["import type { StateMap } from \"../engine/migrate-run\";\nimport type { ChatsInState, MigrateBatchInput, PendingFlowChange } from \"./flow-store\";\n\n// Общее у трёх хранилищ сценариев: одинаковые ключи, порядок и правила, чтобы договор держался везде.\n\n/** Ожидающий перевод версии. Ключ с временем: перевод v1 → v2 → v1 → v2 не схлопывается в один. */\nexport function migratePending(input: MigrateBatchInput): PendingFlowChange {\n return { kind: \"migrate\", key: `migrate:${input.toVersionId}:${input.at}`, versionId: input.toVersionId, map: input.map, at: input.at };\n}\n\n/** Переход, применённый в срок без хода: «забрать» его не снимает — «Переделать» на той же ветке применит его снова. */\nexport const appliedInTime = (change: PendingFlowChange): boolean => change.kind === \"transition\" && change.appliedAt !== undefined;\n\n/**\n * Ожидающее после `addPending`: новый ключ — в конец; тот же ключ — прежний остаётся, но `appliedAt` нового дописывается,\n * если его не было (переход отложили ночью, а утром применили в срок). Ничего не изменилось — `null`.\n */\nexport function pendingAdded(pending: readonly PendingFlowChange[], change: PendingFlowChange): PendingFlowChange[] | null {\n const index = pending.findIndex((item) => item.key === change.key);\n if (index === -1) return [...pending, change];\n const existing = pending[index]!;\n if (existing.kind !== \"transition\" || change.kind !== \"transition\" || change.appliedAt === undefined || existing.appliedAt !== undefined) return null;\n return pending.map((item, at) => (at === index ? { ...existing, appliedAt: change.appliedAt } : item));\n}\n\n/** Состояние после перевода: удалённое — по карте, остальное как было. Зеркало для подсчёта до следующего хода. */\nexport const mappedState = (stateId: string, map: StateMap): string => (Object.hasOwn(map, stateId) ? map[stateId]! : stateId);\n\nexport const byVersionAndState = (left: ChatsInState, right: ChatsInState) =>\n compareText(left.versionId, right.versionId) || compareText(left.stateId, right.stateId);\n\n/** Порядок строк как у базы (`COLLATE \"C\"` и `BINARY`): по кодам символов, без учёта языка. */\nexport const compareText = (left: string, right: string) => (left < right ? -1 : left > right ? 1 : 0);\n\n/** Время к одному виду: `toISOString` с миллисекундами, как его вернёт база. */\nexport const normalizeTime = (iso: string) => new Date(iso).toISOString();\n\n/** PostgreSQL не хранит символ NUL ни в тексте, ни в JSON: вырезаем его до записи. */\nexport function withoutNul<T>(value: T): T {\n if (value === null || value === undefined) return value;\n if (typeof value === \"string\") return value.replaceAll(\"\\u0000\", \"\") as T;\n if (typeof value !== \"object\") return value;\n return JSON.parse(JSON.stringify(value, (_key, item: unknown) => (typeof item === \"string\" ? item.replaceAll(\"\\u0000\", \"\") : item))) as T;\n}\n"],"mappings":";AAMO,SAAS,eAAe,OAA6C;AAC1E,SAAO,EAAE,MAAM,WAAW,KAAK,WAAW,MAAM,WAAW,IAAI,MAAM,EAAE,IAAI,WAAW,MAAM,aAAa,KAAK,MAAM,KAAK,IAAI,MAAM,GAAG;AACxI;AAGO,IAAM,gBAAgB,CAAC,WAAuC,OAAO,SAAS,gBAAgB,OAAO,cAAc;AAMnH,SAAS,aAAa,SAAuC,QAAuD;AACzH,QAAM,QAAQ,QAAQ,UAAU,CAAC,SAAS,KAAK,QAAQ,OAAO,GAAG;AACjE,MAAI,UAAU,GAAI,QAAO,CAAC,GAAG,SAAS,MAAM;AAC5C,QAAM,WAAW,QAAQ,KAAK;AAC9B,MAAI,SAAS,SAAS,gBAAgB,OAAO,SAAS,gBAAgB,OAAO,cAAc,UAAa,SAAS,cAAc,OAAW,QAAO;AACjJ,SAAO,QAAQ,IAAI,CAAC,MAAM,OAAQ,OAAO,QAAQ,EAAE,GAAG,UAAU,WAAW,OAAO,UAAU,IAAI,IAAK;AACvG;AAGO,IAAM,cAAc,CAAC,SAAiB,QAA2B,OAAO,OAAO,KAAK,OAAO,IAAI,IAAI,OAAO,IAAK;AAE/G,IAAM,oBAAoB,CAAC,MAAoB,UACpD,YAAY,KAAK,WAAW,MAAM,SAAS,KAAK,YAAY,KAAK,SAAS,MAAM,OAAO;AAGlF,IAAM,cAAc,CAAC,MAAc,UAAmB,OAAO,QAAQ,KAAK,OAAO,QAAQ,IAAI;AAG7F,IAAM,gBAAgB,CAAC,QAAgB,IAAI,KAAK,GAAG,EAAE,YAAY;AAGjE,SAAS,WAAc,OAAa;AACzC,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,MAAI,OAAO,UAAU,SAAU,QAAO,MAAM,WAAW,MAAU,EAAE;AACnE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO,KAAK,MAAM,KAAK,UAAU,OAAO,CAAC,MAAM,SAAmB,OAAO,SAAS,WAAW,KAAK,WAAW,MAAU,EAAE,IAAI,IAAK,CAAC;AACrI;","names":[]}
package/dist/format.js ADDED
@@ -0,0 +1,147 @@
1
+ import {
2
+ firstMessageSlot,
3
+ flowJsonSchema,
4
+ frameState,
5
+ migrateRun,
6
+ openSideTasks,
7
+ resolveFirstMessages
8
+ } from "./chunk-CKY5KG7N.js";
9
+ import {
10
+ AGENT_FLOW_FORMAT,
11
+ AGENT_FLOW_FORMAT_VERSION,
12
+ ANY_STATE_LAYOUT_KEY,
13
+ DEFAULT_FIRST_MESSAGES,
14
+ DEFAULT_LATE_START_HOURS,
15
+ DEFAULT_SIDE_QUESTION_EVERY_MESSAGES,
16
+ DEFAULT_SIDE_TASK_MAX_ATTEMPTS,
17
+ FLOW_AFTER_END_MODES,
18
+ FLOW_CHAIN_LIMIT,
19
+ FLOW_DATA_OPS,
20
+ FLOW_DEADLINE_EXIT,
21
+ FLOW_EVENT_TYPES,
22
+ FLOW_FIELD_TYPES,
23
+ FLOW_FIRST_EXIT,
24
+ FLOW_GIVE_UP_EXIT,
25
+ FLOW_OPS_BY_FIELD_TYPE,
26
+ FLOW_PATH_LIMIT,
27
+ FLOW_STATE_KEY,
28
+ FLOW_TIMER_SPANS,
29
+ FLOW_TIMER_UNITS,
30
+ RETURN_TARGET,
31
+ activeExits,
32
+ agentFlowSchema,
33
+ appIssues,
34
+ applyTransition,
35
+ beforeFirstNight,
36
+ catalogEventLabel,
37
+ catalogEventNames,
38
+ checkFlow,
39
+ claimAllowed,
40
+ commonApplies,
41
+ compactFlow,
42
+ dataConditionHolds,
43
+ dayAnchor,
44
+ dayInProgress,
45
+ dayOf,
46
+ dayStartAt,
47
+ deadlineAt,
48
+ dueReasons,
49
+ fieldById,
50
+ fieldValueFits,
51
+ flowDay,
52
+ isFieldStale,
53
+ isFinal,
54
+ isTouch,
55
+ localDay,
56
+ migrateFlow,
57
+ nextDue,
58
+ nextNudge,
59
+ nextTransition,
60
+ nextWake,
61
+ noteAgentAnswer,
62
+ noteHumanMessage,
63
+ noteRejectedClaim,
64
+ noteSideQuestion,
65
+ parseFlow,
66
+ placeOfPath,
67
+ returnTarget,
68
+ sideQuestion,
69
+ startRun,
70
+ stateDaysDue,
71
+ stateNudges,
72
+ timerDueAt,
73
+ withDayAnchor
74
+ } from "./chunk-BOV6FJGU.js";
75
+ export {
76
+ AGENT_FLOW_FORMAT,
77
+ AGENT_FLOW_FORMAT_VERSION,
78
+ ANY_STATE_LAYOUT_KEY,
79
+ DEFAULT_FIRST_MESSAGES,
80
+ DEFAULT_LATE_START_HOURS,
81
+ DEFAULT_SIDE_QUESTION_EVERY_MESSAGES,
82
+ DEFAULT_SIDE_TASK_MAX_ATTEMPTS,
83
+ FLOW_AFTER_END_MODES,
84
+ FLOW_CHAIN_LIMIT,
85
+ FLOW_DATA_OPS,
86
+ FLOW_DEADLINE_EXIT,
87
+ FLOW_EVENT_TYPES,
88
+ FLOW_FIELD_TYPES,
89
+ FLOW_FIRST_EXIT,
90
+ FLOW_GIVE_UP_EXIT,
91
+ FLOW_OPS_BY_FIELD_TYPE,
92
+ FLOW_PATH_LIMIT,
93
+ FLOW_STATE_KEY,
94
+ FLOW_TIMER_SPANS,
95
+ FLOW_TIMER_UNITS,
96
+ RETURN_TARGET,
97
+ activeExits,
98
+ agentFlowSchema,
99
+ appIssues,
100
+ applyTransition,
101
+ beforeFirstNight,
102
+ catalogEventLabel,
103
+ catalogEventNames,
104
+ checkFlow,
105
+ claimAllowed,
106
+ commonApplies,
107
+ compactFlow,
108
+ dataConditionHolds,
109
+ dayAnchor,
110
+ dayInProgress,
111
+ dayOf,
112
+ dayStartAt,
113
+ deadlineAt,
114
+ dueReasons,
115
+ fieldById,
116
+ fieldValueFits,
117
+ firstMessageSlot,
118
+ flowDay,
119
+ flowJsonSchema,
120
+ frameState,
121
+ isFieldStale,
122
+ isFinal,
123
+ isTouch,
124
+ localDay,
125
+ migrateFlow,
126
+ migrateRun,
127
+ nextDue,
128
+ nextNudge,
129
+ nextTransition,
130
+ nextWake,
131
+ noteAgentAnswer,
132
+ noteHumanMessage,
133
+ noteRejectedClaim,
134
+ noteSideQuestion,
135
+ openSideTasks,
136
+ parseFlow,
137
+ placeOfPath,
138
+ resolveFirstMessages,
139
+ returnTarget,
140
+ sideQuestion,
141
+ startRun,
142
+ stateDaysDue,
143
+ stateNudges,
144
+ timerDueAt,
145
+ withDayAnchor
146
+ };
147
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}