@ykurilov/agent-chat-flows 0.63.2 → 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.
@@ -5,3 +5,4 @@ export { migrateFlow } from "./migrate-flow.js";
5
5
  export { catalogEventLabel, catalogEventNames } from "./catalog-events.js";
6
6
  export { compactFlow } from "./compact-flow.js";
7
7
  export { flowJsonSchema } from "./flow-json-schema.js";
8
+ export { parseDuration } from "./parse-duration.js";
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Длительность словами в мс: «15 мин» → 900 000, «1 ч 30 мин», «2 дня», «1h 30m», «2 days». Каждое число — со своей
3
+ * единицей; непонятное, пустое или ноль — `undefined`.
4
+ */
5
+ export declare function parseDuration(text: string): number | undefined;
@@ -19,6 +19,14 @@ export interface FlowTestChatLabels {
19
19
  failed: string;
20
20
  /** Перемотка к началу следующего дня сценария. */
21
21
  nextDay: string;
22
+ /** Перемотка к моменту, когда сценарий сам напишет первым. */
23
+ nextFirstMessage: string;
24
+ /** Впереди сценарий сам ничего не напишет: перематывать к напоминанию не к чему. */
25
+ nothingScheduled: string;
26
+ /** Поле «своё время»: подпись, пример и подсказка на непонятное. */
27
+ customTime: string;
28
+ customTimePlaceholder: string;
29
+ customTimeInvalid: string;
22
30
  /** «День 2 из 3», «День 2». */
23
31
  day: (day: number, totalDays?: number) => string;
24
32
  /** Вечер позднего старта: первый день ещё не начался. */
@@ -390,6 +390,12 @@ export interface FlowTestChatFrameProps {
390
390
  day: string | null;
391
391
  /** К началу следующего дня сценария; нет — кнопки нет (нет «Дней и времени» или приложение не дало перемотку). */
392
392
  onNextDay?(): void;
393
+ /** К моменту, когда сценарий сам напишет первым; нет — кнопки нет (приложение не дало перемотку). */
394
+ onNextFirstMessage?(): void;
395
+ /** Последняя перемотка к напоминанию не нашла, к чему перематывать: впереди сценарий сам ничего не напишет. */
396
+ nothingScheduled?: boolean;
397
+ /** Поле «своё время»: текст вроде «1 ч 30 мин»; `false` — не понял, перемотки не было. Нет — поля нет. */
398
+ onAdvanceText?(text: string): boolean;
393
399
  /** Идёт запуск чата или перемотка: кнопки перемотки ждут. */
394
400
  busy: boolean;
395
401
  /** Чат не открылся или часы не перемотались. */
@@ -19,6 +19,14 @@ export interface FlowTestChatConnection {
19
19
  advanceToNextDay?(chatId: string): Promise<{
20
20
  timeOffset: number;
21
21
  }>;
22
+ /**
23
+ * Промотать часы ровно к моменту, когда сценарий сам напишет первым: на сервере
24
+ * `flow.advanceTestClock({ chatId, to: "next_first_message" })`. Впереди ничего — ошибка с `code: "nothing_scheduled"`
25
+ * (у `FlowTestClockError`; через сеть передайте код). Нет — кнопки «К следующему напоминанию» нет.
26
+ */
27
+ advanceToNextFirstMessage?(chatId: string): Promise<{
28
+ timeOffset: number;
29
+ }>;
22
30
  /** Место чата: на сервере `flow.readRun`. В браузер посетителя место не уходит, доска читает его отдельно. */
23
31
  readRun(chatId: string): Promise<(Pick<FlowRun, "state" | "path"> & {
24
32
  day?: FlowDayInfo;
@@ -45,6 +53,10 @@ export interface FlowTestChatController {
45
53
  advance(ms: number): void;
46
54
  /** К началу следующего дня сценария; `null` — приложение не дало `advanceToNextDay`. */
47
55
  nextDay: (() => void) | null;
56
+ /** К следующему сообщению сценария; `null` — приложение не дало `advanceToNextFirstMessage`. */
57
+ nextFirstMessage: (() => void) | null;
58
+ /** Последняя перемотка к напоминанию: впереди сценарий сам ничего не напишет. */
59
+ nothingScheduled: boolean;
48
60
  }
49
61
  /** Логика тестового чата редактора: открыть, перемотать, начать заново, подсветка состояния. */
50
62
  export declare function useFlowTestChat(connection: FlowTestChatConnection, flow: AgentFlow): FlowTestChatController;
@@ -202,6 +202,8 @@ export interface FlowTimers {
202
202
  branchHead: string | null;
203
203
  failedAt?: number;
204
204
  }): Promise<void>;
205
+ /** Слушать, что сработало по таймеру чата (ход «пишет первым», «срок вышел», «не завершил»); возврат — отписка. */
206
+ watch?(chatId: string, onFired: (fired: FlowTestClockReason) => void): () => void;
205
207
  }
206
208
  export interface FirstMessageRules {
207
209
  /** Можно ли написать первым сейчас; нет — когда повторить (мс) или `null`. */
@@ -372,7 +374,10 @@ export type FlowAdmitDecision = {
372
374
  | {
373
375
  kind: "paused";
374
376
  };
375
- /** Перемотка тестового чата: на `ms` или до начала следующего дня сценария. */
377
+ /**
378
+ * Перемотка тестового чата: на `ms`, до начала следующего дня сценария или ровно к моменту, когда сценарий напишет первым
379
+ * (`next_first_message`, с 0.64).
380
+ */
376
381
  export type FlowTestClockInput = {
377
382
  ownerId: string;
378
383
  chatId: string;
@@ -380,9 +385,25 @@ export type FlowTestClockInput = {
380
385
  ms: number;
381
386
  to?: undefined;
382
387
  } | {
383
- to: "next_day_start";
388
+ to: "next_day_start" | "next_first_message";
384
389
  ms?: undefined;
385
390
  });
391
+ /**
392
+ * Что случилось в момент, куда перемотал `next_first_message`: вид — первая причина хода «пишет первым» (`transition`,
393
+ * `morning`, `silence`…), `deadline` — «срок вышел», `give_up` — «не завершил». `stateId` — нода после срабатывания,
394
+ * `exitId` — выход ноды по таймеру, `reasons` — все причины хода.
395
+ */
396
+ export interface FlowTestClockReason {
397
+ kind: FlowFirstReason["kind"] | "deadline" | "give_up";
398
+ stateId: string;
399
+ exitId?: string;
400
+ reasons?: FlowFirstReason[];
401
+ }
402
+ /** Итог перемотки тестового чата: новый сдвиг часов, мс; у `next_first_message` — что сработало. */
403
+ export interface FlowTestClockResult {
404
+ timeOffset: number;
405
+ reason?: FlowTestClockReason;
406
+ }
386
407
  export interface FlowAdmitInput {
387
408
  ownerId: string;
388
409
  chatId: string;
@@ -600,11 +621,11 @@ export interface AgentFlowHandle {
600
621
  /**
601
622
  * Тестовый чат редактора (создан с `flowTestChatData()`): промотать его часы вперёд на `ms` или до начала следующего
602
623
  * дня сценария (`to: "next_day_start"`, по часам человека). Наступивший таймер срабатывает сразу; ответ ждёт конца
603
- * его хода. Рабочий чат — ошибка.
624
+ * его хода. Рабочий чат — ошибка. `to: "next_first_message"` — ровно к моменту, когда сценарий сам напишет первым
625
+ * (касание, утреннее, выход ноды по сроку, «срок вышел», «не завершил»), с учётом ночи и потолков; впереди ничего —
626
+ * `FlowTestClockError` с кодом `nothing_scheduled`, часы не тронуты.
604
627
  */
605
- advanceTestClock(input: FlowTestClockInput): Promise<{
606
- timeOffset: number;
607
- }>;
628
+ advanceTestClock(input: FlowTestClockInput): Promise<FlowTestClockResult>;
608
629
  start(): void;
609
630
  stop(): Promise<void>;
610
631
  /**
@@ -3,7 +3,7 @@ export { FLOW_SERVICE_BLOCKS } from "./flow-service-blocks.js";
3
3
  export type * from "./flow-types.js";
4
4
  export { DEFAULT_JUDGE_MODEL, DEFAULT_JUDGE_THRESHOLD, DEFAULT_JUDGE_TIMEOUT_MS } from "./judge.js";
5
5
  export { DEFAULT_TIMER_LEASE_MS, DEFAULT_TIMER_TICK_MS } from "./flow-timers.js";
6
- export { flowTestChatData, testChatOffset } from "./test-clock.js";
6
+ export { FlowTestClockError, flowTestChatData, testChatOffset } from "./test-clock.js";
7
7
  export { DEFAULT_PAUSE_STAFF_SILENCE_HOURS } from "./pause.js";
8
8
  export { FLOW_EXIT_TOOL, FLOW_EXTRA_TOOLS } from "./flow-tools.js";
9
9
  export { FLOW_TIME_ZONE_TOOL } from "./time-zone-tool.js";
@@ -1,6 +1,6 @@
1
1
  import { type FlowRun } from "../engine/flow-run.js";
2
2
  import { type FlowRuntime } from "./flow-events.js";
3
- import type { FlowPort, FlowTestClockInput, FlowTimers } from "./flow-types.js";
3
+ import type { FlowPort, FlowTestClockInput, FlowTestClockResult, FlowTimers } from "./flow-types.js";
4
4
  /** Ключ данных чата (`Chat.data`) с пометкой тестового чата и сдвигом его часов. */
5
5
  export declare const FLOW_TEST_CHAT_KEY = "flowTestChat";
6
6
  /** Данные нового тестового чата: `service.createChat(userId, { data: flowTestChatData() })`. */
@@ -9,6 +9,11 @@ export declare function flowTestChatData(): Record<string, unknown>;
9
9
  export declare function testChatOffset(data: Record<string, unknown> | undefined): number | null;
10
10
  /** Часы чата, мс: часы сервера плюс сдвиг тестового чата. */
11
11
  export declare const chatTime: (run: Pick<FlowRun, "timeOffset"> | null | undefined, serverNow: number) => number;
12
+ /** Перемотка не удалась по понятной причине: `nothing_scheduled` — впереди сценарий сам ничего не напишет. */
13
+ export declare class FlowTestClockError extends Error {
14
+ readonly code: "nothing_scheduled" | "not_reached";
15
+ constructor(code: "nothing_scheduled" | "not_reached", message: string);
16
+ }
12
17
  /**
13
18
  * Промотать часы тестового чата вперёд: на `ms` или до начала следующего дня сценария (`to: "next_day_start"`). Сдвиг
14
19
  * в данные чата, ближайший таймер пересчитан по новым часам и, если наступил, срабатывает сразу (агент пишет первым по
@@ -21,6 +26,4 @@ export declare function advanceTestClock(input: {
21
26
  ownerId: string;
22
27
  chatId: string;
23
28
  clock: FlowTestClockInput;
24
- }): Promise<{
25
- timeOffset: number;
26
- }>;
29
+ }): Promise<FlowTestClockResult>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ykurilov/agent-chat-flows",
3
- "version": "0.63.2",
3
+ "version": "0.64.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -56,13 +56,13 @@
56
56
  "ai": "7.0.122",
57
57
  "drizzle-orm": "^0.45.3",
58
58
  "zod": "^4.6.5",
59
- "@ykurilov/agent-chat-core": "0.63.2"
59
+ "@ykurilov/agent-chat-core": "0.64.0"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "better-sqlite3": "^13.0.3",
63
63
  "pg": "^8.23.0",
64
64
  "react": "^19.3.0",
65
- "@ykurilov/agent-chat-react": "^0.63.2"
65
+ "@ykurilov/agent-chat-react": "^0.64.0"
66
66
  },
67
67
  "peerDependenciesMeta": {
68
68
  "@ykurilov/agent-chat-react": {
@@ -90,7 +90,7 @@
90
90
  "pg": "^8.23.0",
91
91
  "react": "^19.3.0",
92
92
  "tsx": "4.23.15",
93
- "@ykurilov/agent-chat-react": "0.63.2"
93
+ "@ykurilov/agent-chat-react": "0.64.0"
94
94
  },
95
95
  "scripts": {
96
96
  "build": "node ../../scripts/build-package.mjs",