@ykurilov/agent-chat-flows 0.0.0-stage → 0.56.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 +261 -0
- package/LICENSE +21 -0
- package/README.md +124 -2
- package/agent-flow.schema.json +1020 -0
- package/dist/chunk-3PTJI2XY.js +100 -0
- package/dist/chunk-3PTJI2XY.js.map +1 -0
- package/dist/chunk-BNMQUNSI.js +9 -0
- package/dist/chunk-BNMQUNSI.js.map +1 -0
- package/dist/chunk-BOV6FJGU.js +1288 -0
- package/dist/chunk-BOV6FJGU.js.map +1 -0
- package/dist/chunk-CKY5KG7N.js +165 -0
- package/dist/chunk-CKY5KG7N.js.map +1 -0
- package/dist/chunk-DCTRMCGV.js +34 -0
- package/dist/chunk-DCTRMCGV.js.map +1 -0
- package/dist/format.js +147 -0
- package/dist/format.js.map +1 -0
- package/dist/index.js +3197 -0
- package/dist/index.js.map +1 -0
- package/dist/postgres.js +387 -0
- package/dist/postgres.js.map +1 -0
- package/dist/react.js +2650 -0
- package/dist/react.js.map +1 -0
- package/dist/sqlite.js +319 -0
- package/dist/sqlite.js.map +1 -0
- package/dist/types/check/app-checks.d.ts +16 -0
- package/dist/types/check/check-flow.d.ts +8 -0
- package/dist/types/check/index.d.ts +2 -0
- package/dist/types/engine/data-conditions.d.ts +10 -0
- package/dist/types/engine/day-frame.d.ts +17 -0
- package/dist/types/engine/first-messages.d.ts +21 -0
- package/dist/types/engine/flow-days.d.ts +39 -0
- package/dist/types/engine/flow-graph.d.ts +26 -0
- package/dist/types/engine/flow-run.d.ts +130 -0
- package/dist/types/engine/index.d.ts +14 -0
- package/dist/types/engine/migrate-run.d.ts +11 -0
- package/dist/types/engine/next-transition.d.ts +40 -0
- package/dist/types/engine/nudges.d.ts +78 -0
- package/dist/types/engine/run-updates.d.ts +37 -0
- package/dist/types/engine/side-questions.d.ts +26 -0
- package/dist/types/engine/side-tasks.d.ts +44 -0
- package/dist/types/engine/targets.d.ts +9 -0
- package/dist/types/engine/timers.d.ts +61 -0
- package/dist/types/engine/zoned-time.d.ts +27 -0
- package/dist/types/format/catalog-events.d.ts +5 -0
- package/dist/types/format/compact-flow.d.ts +8 -0
- package/dist/types/format/flow-format.d.ts +286 -0
- package/dist/types/format/flow-json-schema.d.ts +2 -0
- package/dist/types/format/flow-schema.d.ts +605 -0
- package/dist/types/format/index.d.ts +7 -0
- package/dist/types/format/migrate-flow.d.ts +4 -0
- package/dist/types/format/parse-flow.d.ts +6 -0
- package/dist/types/format.d.ts +3 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/labels/client-card.d.ts +20 -0
- package/dist/types/labels/editor.d.ts +261 -0
- package/dist/types/labels/index.d.ts +14 -0
- package/dist/types/labels/migrate.d.ts +19 -0
- package/dist/types/labels/test-chat.d.ts +28 -0
- package/dist/types/not-yet.d.ts +2 -0
- package/dist/types/postgres.d.ts +10 -0
- package/dist/types/prompt/client-card-block.d.ts +16 -0
- package/dist/types/prompt/flow-rules.d.ts +9 -0
- package/dist/types/prompt/rules/after-end.d.ts +3 -0
- package/dist/types/prompt/rules/client-facts.d.ts +2 -0
- package/dist/types/prompt/rules/day-frame.d.ts +2 -0
- package/dist/types/prompt/rules/link-views.d.ts +4 -0
- package/dist/types/prompt/rules/rule-part.d.ts +3 -0
- package/dist/types/prompt/rules/side-tasks.d.ts +2 -0
- package/dist/types/prompt/rules/time-zone.d.ts +2 -0
- package/dist/types/prompt/state-card.d.ts +14 -0
- package/dist/types/react/client-card/client-card-panel.d.ts +8 -0
- package/dist/types/react/client-card/index.d.ts +2 -0
- package/dist/types/react/client-card/use-client-card.d.ts +19 -0
- package/dist/types/react/client-card-skin.d.ts +27 -0
- package/dist/types/react/editor/board-space.d.ts +51 -0
- package/dist/types/react/editor/board-styles.d.ts +1 -0
- package/dist/types/react/editor/editor-model.d.ts +60 -0
- package/dist/types/react/editor/exit-text.d.ts +11 -0
- package/dist/types/react/editor/flow-board.d.ts +11 -0
- package/dist/types/react/editor/flow-editor.d.ts +13 -0
- package/dist/types/react/editor/flow-simulation.d.ts +44 -0
- package/dist/types/react/editor/index.d.ts +6 -0
- package/dist/types/react/editor/schedule-model.d.ts +47 -0
- package/dist/types/react/editor/side-task-model.d.ts +18 -0
- package/dist/types/react/editor/use-flow-editor.d.ts +120 -0
- package/dist/types/react/flow-editor-skin.d.ts +453 -0
- package/dist/types/react/flow-labels.d.ts +8 -0
- package/dist/types/react/index.d.ts +6 -0
- package/dist/types/react/test-chat/flow-test-chat.d.ts +22 -0
- package/dist/types/react/test-chat/index.d.ts +2 -0
- package/dist/types/react/test-chat/use-flow-test-chat.d.ts +50 -0
- package/dist/types/react.d.ts +3 -0
- package/dist/types/runtime/admit.d.ts +15 -0
- package/dist/types/runtime/agent-flow.d.ts +20 -0
- package/dist/types/runtime/client-card.d.ts +9 -0
- package/dist/types/runtime/client-facts.d.ts +22 -0
- package/dist/types/runtime/close-day-tool.d.ts +3 -0
- package/dist/types/runtime/decisions-client.d.ts +33 -0
- package/dist/types/runtime/extra-tool.d.ts +16 -0
- package/dist/types/runtime/first-message-retry.d.ts +4 -0
- package/dist/types/runtime/first-message-rules.d.ts +55 -0
- package/dist/types/runtime/first-reasons-notice.d.ts +9 -0
- package/dist/types/runtime/flow-delivery.d.ts +53 -0
- package/dist/types/runtime/flow-events.d.ts +126 -0
- package/dist/types/runtime/flow-finish.d.ts +68 -0
- package/dist/types/runtime/flow-known-texts.d.ts +11 -0
- package/dist/types/runtime/flow-signals.d.ts +12 -0
- package/dist/types/runtime/flow-timers.d.ts +55 -0
- package/dist/types/runtime/flow-tools.d.ts +23 -0
- package/dist/types/runtime/flow-types.d.ts +547 -0
- package/dist/types/runtime/held-messages.d.ts +25 -0
- package/dist/types/runtime/index.d.ts +11 -0
- package/dist/types/runtime/judge-context.d.ts +36 -0
- package/dist/types/runtime/judge.d.ts +21 -0
- package/dist/types/runtime/migrate-chats.d.ts +20 -0
- package/dist/types/runtime/note-tools.d.ts +15 -0
- package/dist/types/runtime/pause.d.ts +21 -0
- package/dist/types/runtime/prepare-turn.d.ts +12 -0
- package/dist/types/runtime/side-task-tool.d.ts +5 -0
- package/dist/types/runtime/step-tail.d.ts +11 -0
- package/dist/types/runtime/tail/day-line.d.ts +2 -0
- package/dist/types/runtime/tail/frame-line.d.ts +2 -0
- package/dist/types/runtime/tail/side-tasks-line.d.ts +2 -0
- package/dist/types/runtime/tail/tail-part.d.ts +21 -0
- package/dist/types/runtime/test-clock.d.ts +26 -0
- package/dist/types/runtime/time-zone-tool.d.ts +3 -0
- package/dist/types/runtime/turn-gate.d.ts +8 -0
- package/dist/types/sqlite.d.ts +9 -0
- package/dist/types/store/flow-store-shared.d.ts +20 -0
- package/dist/types/store/flow-store.d.ts +240 -0
- package/dist/types/store/memory.d.ts +3 -0
- package/dist/types/store/migration-settings.d.ts +7 -0
- package/dist/types/store/postgres-schema.d.ts +775 -0
- package/dist/types/store/postgres.d.ts +15 -0
- package/dist/types/store/sqlite-schema.d.ts +824 -0
- package/dist/types/store/sqlite.d.ts +9 -0
- package/drizzle/postgres/0000_init.sql +45 -0
- package/drizzle/postgres/0001_days_pause_side_tasks.sql +21 -0
- package/drizzle/postgres/0002_chat_placement.sql +1 -0
- package/drizzle/postgres/meta/0000_snapshot.json +317 -0
- package/drizzle/postgres/meta/0001_snapshot.json +439 -0
- package/drizzle/postgres/meta/0002_snapshot.json +445 -0
- package/drizzle/postgres/meta/_journal.json +27 -0
- package/drizzle/sqlite/0000_init.sql +44 -0
- package/drizzle/sqlite/0001_days_pause_side_tasks.sql +21 -0
- package/drizzle/sqlite/0002_chat_placement.sql +1 -0
- package/drizzle/sqlite/meta/0000_snapshot.json +297 -0
- package/drizzle/sqlite/meta/0001_snapshot.json +427 -0
- package/drizzle/sqlite/meta/0002_snapshot.json +434 -0
- package/drizzle/sqlite/meta/_journal.json +27 -0
- package/package.json +98 -3
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AgentToolsModel } from "@ykurilov/agent-chat-core";
|
|
2
|
+
import type { Tool } from "ai";
|
|
3
|
+
import type { AgentFlow } from "../format/flow-format.js";
|
|
4
|
+
import type { FlowRuntime } from "./flow-events.js";
|
|
5
|
+
/**
|
|
6
|
+
* Служебный инструмент сценария из своего файла. Набор зависит только от версии сценария, а не от состояния: кэш цел.
|
|
7
|
+
* Сценарий без нужных полей — инструмента нет, набор как в 0.48.
|
|
8
|
+
*/
|
|
9
|
+
export interface FlowExtraTool {
|
|
10
|
+
name: string;
|
|
11
|
+
wanted(flow: AgentFlow): boolean;
|
|
12
|
+
make(input: {
|
|
13
|
+
runtime: FlowRuntime;
|
|
14
|
+
model: AgentToolsModel;
|
|
15
|
+
}): Tool;
|
|
16
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Ход «пишет первым» не начался или приложение сказало «не сейчас» (`canWriteNow` → `false`): касание — через час. */
|
|
2
|
+
export declare const FIRST_MESSAGE_RETRY_MS = 3600000;
|
|
3
|
+
/** `canWriteNow` → `{ retryAt }` в прошлом: повтор не чаще, чем раз в минуту. */
|
|
4
|
+
export declare const FIRST_MESSAGE_MIN_RETRY_MS = 60000;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { FlowSchedule } from "../format/flow-format.js";
|
|
2
|
+
import type { FirstMessagesSetting } from "../engine/flow-run.js";
|
|
3
|
+
import type { FlowChatRecord, FlowStore } from "../store/flow-store.js";
|
|
4
|
+
import type { FirstMessageRules, FlowPeople } from "./flow-types.js";
|
|
5
|
+
/** Что в записи чата запрещает писать первым. */
|
|
6
|
+
export type FlowChatWriteState = Pick<FlowChatRecord, "dayClosedOn" | "pausedUntil" | "windowClosed">;
|
|
7
|
+
/**
|
|
8
|
+
* Запрет из записи чата, до правил приложения: окно канала закрыто — молчать до сообщения человека (`retryAt: null`);
|
|
9
|
+
* пауза сотрудника — до её конца; агент закрыл день — до начала следующего. Нет запрета — `null`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function chatWriteBlock(chat: FlowChatWriteState, at: number, timeZone: string, schedule: FlowSchedule | undefined): {
|
|
12
|
+
retryAt: number | null;
|
|
13
|
+
} | null;
|
|
14
|
+
/** Правила «писать первым» на хранилище счётчиков; `false` в настройках — `null`, агент пишет первым без ограничений. */
|
|
15
|
+
export declare function createFirstMessageRules(setting: FirstMessagesSetting | undefined, store: FlowStore): FirstMessageRules | null;
|
|
16
|
+
/** Пояс чата ещё не известен: страница его не присылала. */
|
|
17
|
+
export declare const UNKNOWN_TIME_ZONE = "";
|
|
18
|
+
export declare const serverTimeZone: () => string;
|
|
19
|
+
/**
|
|
20
|
+
* Пояс страницы из пояса хода. Ядро с 0.53 говорит его прямо (`pageTimeZone`). Без этого поля: ядро без пояса страницы
|
|
21
|
+
* подставляет запасной (приложения или сервера), поэтому совпадение с запасным — «страница пояс не прислала»: такой пояс
|
|
22
|
+
* не затирает известный пояс чата.
|
|
23
|
+
*/
|
|
24
|
+
export declare function pageTimeZone(turnZone: string, appZone: string | undefined, sent?: string | null): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* Пояс чата для таймеров: известный (человека или со страницы), иначе `defaultTimeZone`, иначе приложения, иначе
|
|
27
|
+
* сервера — с предупреждением один раз на чат.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createChatTimeZones(input: {
|
|
30
|
+
appTimeZone: () => string | undefined;
|
|
31
|
+
defaultTimeZone?: string;
|
|
32
|
+
warn: (message: string) => void;
|
|
33
|
+
}): {
|
|
34
|
+
of(chatId: string, stored: string): string;
|
|
35
|
+
};
|
|
36
|
+
/** Пояс IANA в каноническом виде («asia/novosibirsk» → «Asia/Novosibirsk»); не пояс — `null`. */
|
|
37
|
+
export declare function ianaTimeZone(value: string): string | null;
|
|
38
|
+
/** Пояс человека: один на все его разговоры. Копия в записи чата — для таймеров, которые читают её без ожидания. */
|
|
39
|
+
export interface FlowTimeZones {
|
|
40
|
+
/** Известный пояс: записанный человеку, иначе узнанный в этом чате. Не знаем — `null`. */
|
|
41
|
+
known(ownerId: string, chatId: string): Promise<string | null>;
|
|
42
|
+
/** Пояс для счёта: известный, иначе приложения или сервера. */
|
|
43
|
+
of(ownerId: string, chatId: string): Promise<string>;
|
|
44
|
+
/** Запасной пояс чата, пока пояс человека неизвестен: приложения или сервера. */
|
|
45
|
+
fallback(chatId: string): string;
|
|
46
|
+
/** Пояс узнан (страница, слова человека): человеку и копия в запись чата. */
|
|
47
|
+
write(ownerId: string, chatId: string, timeZone: string): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
/** Пояса людей: адаптер приложения `people` или таблица модуля; запасной — `fallback` (приложения или сервера). */
|
|
50
|
+
export declare function createFlowTimeZones(input: {
|
|
51
|
+
store: FlowStore;
|
|
52
|
+
people?: FlowPeople;
|
|
53
|
+
fallback: (chatId: string) => string;
|
|
54
|
+
now: () => number;
|
|
55
|
+
}): FlowTimeZones;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AgentFlow } from "../format/flow-format.js";
|
|
2
|
+
import type { FlowFirstReason } from "../engine/nudges.js";
|
|
3
|
+
import type { FlowNotice } from "./flow-types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Служебное сообщение хода «пишет первым». Только переход ноды — прежнее «Сработало: …» (как в 0.48); есть другие
|
|
6
|
+
* причины — их список и задача «новое и полезное». `data.exitId` — переход, который применит ход; `data.nudgeStep` —
|
|
7
|
+
* шаг ряда касаний после хода (после перехода и утреннего — 0, ряд заново); `data.nudgeStepOwn` — его насчитал свой ряд ноды на N дней (`ownNudge`).
|
|
8
|
+
*/
|
|
9
|
+
export declare function firstReasonsNotice(flow: AgentFlow, reasons: readonly FlowFirstReason[], exitId: string | null, ownNudge?: boolean): FlowNotice;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type StoredMessage } from "@ykurilov/agent-chat-core";
|
|
2
|
+
import type { FlowFirstReason } from "../engine/nudges.js";
|
|
3
|
+
import type { FlowChatRecord } from "../store/flow-store.js";
|
|
4
|
+
import type { FirstMessageRules, FlowAttachment, FlowDeliveryOutcome, FlowDeliveryReport, FlowOutgoing, FlowPort } from "./flow-types.js";
|
|
5
|
+
import { type FlowRuntime } from "./flow-events.js";
|
|
6
|
+
import type { FlowFinisher } from "./flow-finish.js";
|
|
7
|
+
/** Срок записи о повторе доставки в таблице сроков. */
|
|
8
|
+
export declare const FLOW_DELIVERY_EXIT = "@delivery";
|
|
9
|
+
/** Ход «пишет первым» закончен: что ушло и когда. */
|
|
10
|
+
export interface FirstTurnAnswer {
|
|
11
|
+
ownerId: string;
|
|
12
|
+
chatId: string;
|
|
13
|
+
/** Готовый ответ хода (`awaitAnswer`); нет — каналы SDK. */
|
|
14
|
+
answer: {
|
|
15
|
+
messageId: string;
|
|
16
|
+
text: string;
|
|
17
|
+
status: string;
|
|
18
|
+
parts: StoredMessage["parts"];
|
|
19
|
+
} | undefined;
|
|
20
|
+
reasons: FlowFirstReason[];
|
|
21
|
+
/** Момент хода по часам чата и пояс человека: счётчик дня. */
|
|
22
|
+
at: number;
|
|
23
|
+
timeZone: string;
|
|
24
|
+
}
|
|
25
|
+
export interface FlowDelivery {
|
|
26
|
+
/** У приложения своя доставка (`attach({ deliver })`). Нет — доставляют каналы SDK, как в 0.48. */
|
|
27
|
+
own(): boolean;
|
|
28
|
+
/** Отдать ответ в `deliver` и разобрать исход. */
|
|
29
|
+
send(message: FlowOutgoing): Promise<FlowDeliveryOutcome>;
|
|
30
|
+
/** Исход из каналов SDK (`reportDelivery`). */
|
|
31
|
+
report(input: FlowDeliveryReport): Promise<void>;
|
|
32
|
+
/** Ход «пишет первым» закончен: своя доставка — первая попытка; каналы SDK — в счётчик дня сразу (как в 0.48). Итог попытки; нечего отдавать — `null`. */
|
|
33
|
+
afterFirstTurn(turn: FirstTurnAnswer): Promise<FlowDeliveryOutcome["status"] | null>;
|
|
34
|
+
/** Наступил срок повтора (`record.delivery`): тот же текст, тот же `messageId`, без нового хода. Итог попытки; повторять нечего — `null`. */
|
|
35
|
+
retry(record: FlowChatRecord, serverAt: number): Promise<FlowDeliveryOutcome["status"] | null>;
|
|
36
|
+
}
|
|
37
|
+
export declare function createFlowDelivery(input: {
|
|
38
|
+
runtime: FlowRuntime;
|
|
39
|
+
deliver: () => FlowAttachment["deliver"];
|
|
40
|
+
port?: (chat: {
|
|
41
|
+
ownerId: string;
|
|
42
|
+
chatId: string;
|
|
43
|
+
}) => Promise<FlowPort>;
|
|
44
|
+
finish?: () => FlowFinisher;
|
|
45
|
+
firstMessages?: () => FirstMessageRules | null;
|
|
46
|
+
timeZoneOf?: (ownerId: string, chatId: string) => Promise<string>;
|
|
47
|
+
/** Канал SDK сообщил «не доставлено» (`failed`, `window_closed`): касание не засчитано — сроки чата пересчитать. */
|
|
48
|
+
onUndelivered?: (chat: {
|
|
49
|
+
ownerId: string;
|
|
50
|
+
chatId: string;
|
|
51
|
+
at: number;
|
|
52
|
+
}) => Promise<void>;
|
|
53
|
+
}): FlowDelivery;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { Chat } from "@ykurilov/agent-chat-core";
|
|
2
|
+
import type { AgentFlow, FlowExit } from "../format/flow-format.js";
|
|
3
|
+
import { type FlowRun, type Transition } from "../engine/flow-run.js";
|
|
4
|
+
import { describeCondition, type FlowEvent } from "../engine/next-transition.js";
|
|
5
|
+
import type { FlowChatRecord, FlowStore, PendingFlowChange } from "../store/flow-store.js";
|
|
6
|
+
import type { FlowNotice, FlowTransitionEvent } from "./flow-types.js";
|
|
7
|
+
import type { FlowFirstReason } from "../engine/nudges.js";
|
|
8
|
+
import type { FlowTimeZones } from "./first-message-rules.js";
|
|
9
|
+
/**
|
|
10
|
+
* `FlowRun` в состоянии чата: плюс ответ агента, в начале которого он записан. По нему ожидающий переход судьи узнаёт
|
|
11
|
+
* свою ветку: правка или «Переделать» начинают ветку с другим ответом — переход снимается.
|
|
12
|
+
*/
|
|
13
|
+
export type ChatFlowRun = FlowRun & {
|
|
14
|
+
answerId?: string;
|
|
15
|
+
/** Почему агент пишет первым в ответе `answerId`; ход на сообщение человека — нет. Для хвоста приложения. */
|
|
16
|
+
firstReasons?: FlowFirstReason[];
|
|
17
|
+
};
|
|
18
|
+
/** Чат закреплён за версией сценария. */
|
|
19
|
+
export interface PinnedFlow {
|
|
20
|
+
flowId: string;
|
|
21
|
+
versionId: string;
|
|
22
|
+
flow: AgentFlow;
|
|
23
|
+
/** Разговор закончен (`endChat`): инструкция «после конца» вместо правил сценария. */
|
|
24
|
+
ended?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Что общего у частей сценария в службе чата: хранилище, часы, сценарий чата и отчёт о переходах. */
|
|
27
|
+
export interface FlowRuntime {
|
|
28
|
+
store: FlowStore;
|
|
29
|
+
now(): number;
|
|
30
|
+
logError(message: string): void;
|
|
31
|
+
/** Сценарий чата; с `chat` закрепляет незакреплённый чат за версией (`loadFlow`). `null` — чат без сценария. */
|
|
32
|
+
chatFlow(ownerId: string, chatId: string, chat?: Chat): Promise<PinnedFlow | null>;
|
|
33
|
+
/** Фоновая работа, которую ждёт `settled`; нет — не отслеживается (подделки в тестах). */
|
|
34
|
+
track?(work: Promise<unknown>): void;
|
|
35
|
+
/** Значения карточки клиента по `id` полей: для условий по данным. */
|
|
36
|
+
cardValues(ownerId: string): Promise<Record<string, unknown>>;
|
|
37
|
+
/** Пояс человека; нет — пояс хода (подделки в тестах). */
|
|
38
|
+
timeZones?: FlowTimeZones;
|
|
39
|
+
/** `AgentFlowOptions.defaultTimeZone`: пояс хода без страницы и без известного пояса человека — он, а не пояс службы. */
|
|
40
|
+
defaultTimeZone?: string;
|
|
41
|
+
/** Переходы случились: копия состояния в хранилище, `onTransition`. Не бросает. */
|
|
42
|
+
afterTransitions(input: {
|
|
43
|
+
ownerId: string;
|
|
44
|
+
chatId: string;
|
|
45
|
+
pinned: PinnedFlow;
|
|
46
|
+
run: FlowRun;
|
|
47
|
+
transitions: Transition[];
|
|
48
|
+
}): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
/** Сообщить приложению о переходе (`onTransition`); ошибка приложения не ломает ход. */
|
|
51
|
+
export declare function reportTransition(handler: ((event: FlowTransitionEvent) => void | Promise<void>) | undefined, event: FlowTransitionEvent, logError: (message: string) => void): Promise<void>;
|
|
52
|
+
/** `FlowRun` из состояния чата; нет или не то — `null`. */
|
|
53
|
+
export declare function storedRun(value: unknown): ChatFlowRun | null;
|
|
54
|
+
/** Где чат сейчас: из состояния ветки, а на пустой ветке — старт сценария. */
|
|
55
|
+
export declare function currentRun(flow: AgentFlow, values: Record<string, unknown> | undefined, now: number): ChatFlowRun;
|
|
56
|
+
/**
|
|
57
|
+
* Куда перенесли чат при закреплении (`loadFlow`, `adopt`): состояние и моменты, от которых считаются сроки, а у идущего
|
|
58
|
+
* чата — последние слова обеих сторон, шаг касаний и счёт сообщений человека за день. Нет поля — как у нового чата.
|
|
59
|
+
*/
|
|
60
|
+
export interface ChatPlacement {
|
|
61
|
+
stateId?: string;
|
|
62
|
+
startedAt?: number;
|
|
63
|
+
enteredAt?: number;
|
|
64
|
+
lastHumanAt?: number;
|
|
65
|
+
lastAgentAt?: number;
|
|
66
|
+
nudgeStep?: number;
|
|
67
|
+
/** Сообщения человека за день сценария к моменту `at`. */
|
|
68
|
+
humanToday?: {
|
|
69
|
+
at: number;
|
|
70
|
+
count: number;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Место чата, перенесённого в заданное состояние: путь начинается с него, сроки таймеров — от `enteredAt` (нет — от
|
|
75
|
+
* `startedAt`). Счёт дня ложится в день сценария по поясу `timeZone`; пояса нет — счёт не переносится.
|
|
76
|
+
*/
|
|
77
|
+
export declare function placedRun(flow: AgentFlow, placement: ChatPlacement, now: number, timeZone?: string): ChatFlowRun;
|
|
78
|
+
/** Перенос из записи чата; первый ход его уже записал в состояние (или переноса не было) — `null`. */
|
|
79
|
+
export declare function recordPlacement(record: Pick<FlowChatRecord, "stateId" | "placement">): ChatPlacement | null;
|
|
80
|
+
/**
|
|
81
|
+
* Где чат сейчас вне хода: из состояния ветки; до первого хода перенесённого чата — из записи переноса; иначе старт.
|
|
82
|
+
* Так таймеры, `admit` и `readRun` видят перенесённое место, не дожидаясь хода человека.
|
|
83
|
+
*/
|
|
84
|
+
export declare function chatRun(flow: AgentFlow, values: Record<string, unknown> | undefined, record: Pick<FlowChatRecord, "stateId" | "placement"> | null | undefined, now: number, timeZone?: string): ChatFlowRun;
|
|
85
|
+
/**
|
|
86
|
+
* Пояс человека для шага движка вне подготовки хода, как в `runOutsideTurn`: пояса модуля, без них — из записи чата;
|
|
87
|
+
* неизвестен — `defaultTimeZone`, иначе сервера.
|
|
88
|
+
*/
|
|
89
|
+
export declare function personTimeZone(runtime: Pick<FlowRuntime, "store" | "timeZones" | "defaultTimeZone">, chat: {
|
|
90
|
+
ownerId: string;
|
|
91
|
+
chatId: string;
|
|
92
|
+
}): Promise<string>;
|
|
93
|
+
/** `chatRun` для частей сценария вне хода: запись чата (если не передана) и пояс человека читаются тут. */
|
|
94
|
+
export declare function runOutsideTurn(runtime: Pick<FlowRuntime, "store" | "timeZones">, chat: {
|
|
95
|
+
ownerId: string;
|
|
96
|
+
chatId: string;
|
|
97
|
+
}, flow: AgentFlow, values: Record<string, unknown> | undefined, now: number, record?: FlowChatRecord | null): Promise<ChatFlowRun>;
|
|
98
|
+
/**
|
|
99
|
+
* Шаг движка с проверкой нового состояния: условия по данным и наступившие таймеры, чей срок не зависит от входа
|
|
100
|
+
* (`overdueOnEntry`). Переходы складываются в `out`. `timeZone` — пояс человека: по нему считаются дни программы.
|
|
101
|
+
*/
|
|
102
|
+
export declare function advance(flow: AgentFlow, run: ChatFlowRun, event: FlowEvent, input: {
|
|
103
|
+
now: number;
|
|
104
|
+
card: Record<string, unknown>;
|
|
105
|
+
out: Transition[];
|
|
106
|
+
onChainLimit: (run: FlowRun) => void;
|
|
107
|
+
timeZone: string;
|
|
108
|
+
}): ChatFlowRun;
|
|
109
|
+
/** Событие движка для ожидающего перехода: таймер проверяется заново по своему сроку, судья — как вердикт. */
|
|
110
|
+
export declare function pendingEvent(transition: Transition, timeZone: string): FlowEvent;
|
|
111
|
+
/**
|
|
112
|
+
* Ожидающее вне хода поверх места ветки — каким место станет к ходу: переходы своей ветки из того же состояния и
|
|
113
|
+
* события приложения. Само ожидание не трогается.
|
|
114
|
+
*/
|
|
115
|
+
export declare function withPending(flow: AgentFlow, run: ChatFlowRun, pending: readonly PendingFlowChange[], input: Parameters<typeof advance>[3]): ChatFlowRun;
|
|
116
|
+
/** Строка журнала про зацикливание. */
|
|
117
|
+
export declare const chainLimitMessage: (chatId: string, run: FlowRun) => string;
|
|
118
|
+
/** Условие выхода по `id`: своё у состояния или общее. */
|
|
119
|
+
export declare function exitById(flow: AgentFlow, exitId: string): FlowExit | undefined;
|
|
120
|
+
export { describeCondition };
|
|
121
|
+
/** Точный первый текст состояния: агент пишет его слово в слово, без модели, когда это возможно. */
|
|
122
|
+
export declare function exactFirstText(flow: AgentFlow, stateId: string): string | null;
|
|
123
|
+
/** Служебное сообщение модели о переходах вне её ответа: «Сработало: тишина 3 ч → «Напоминание»». */
|
|
124
|
+
export declare function transitionNotice(flow: AgentFlow, transitions: Transition[]): FlowNotice;
|
|
125
|
+
/** Результат инструмента, после которого сменилось состояние: карточка нового состояния и точный первый текст. */
|
|
126
|
+
export declare function transitionReport(flow: AgentFlow, run: FlowRun, transitions: Transition[]): string;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { AgentFlow, FlowAfterEnd } from "../format/flow-format.js";
|
|
2
|
+
import type { FlowEndReason, FlowRun, Transition } from "../engine/flow-run.js";
|
|
3
|
+
import type { FirstMessageRules, FlowFinish, FlowPort } from "./flow-types.js";
|
|
4
|
+
import type { ChatFlowRun, FlowRuntime, PinnedFlow } from "./flow-events.js";
|
|
5
|
+
import type { FlowDelivery } from "./flow-delivery.js";
|
|
6
|
+
/** Имя служебного сообщения `app` прощального хода при «срок вышел». */
|
|
7
|
+
export declare const FLOW_DEADLINE_NOTICE = "flow_deadline";
|
|
8
|
+
/**
|
|
9
|
+
* Что делать с сообщением человека после конца (→ В6). Единственная точка решения: позже здесь встанет передача
|
|
10
|
+
* следующему сценарию и признак «кто ведёт сейчас» (сценарий, рассылка, сотрудник).
|
|
11
|
+
*/
|
|
12
|
+
export declare function afterEndOf(flow: AgentFlow): FlowAfterEnd;
|
|
13
|
+
/**
|
|
14
|
+
* Закрывает ли конечная нода разговор. Сценарий с «Днями и временем» или с заданным `afterEnd` — да; иначе, как в 0.48,
|
|
15
|
+
* агент и дальше отвечает по карточке конечной ноды, а приложение узнаёт о ней только событием.
|
|
16
|
+
*/
|
|
17
|
+
export declare const finalEndsChat: (flow: AgentFlow) => boolean;
|
|
18
|
+
/** Место чата, закрытого вне хода (таймер, перенос): переход в `deadlineState` и отметка конца. О переходе уже сообщено. */
|
|
19
|
+
export declare function endedRun<T extends FlowRun>(flow: AgentFlow, run: T, ended: {
|
|
20
|
+
endedAt: number;
|
|
21
|
+
endReason: FlowEndReason;
|
|
22
|
+
}): T;
|
|
23
|
+
export interface FlowDeadlineInput {
|
|
24
|
+
ownerId: string;
|
|
25
|
+
chatId: string;
|
|
26
|
+
pinned: PinnedFlow;
|
|
27
|
+
run: ChatFlowRun;
|
|
28
|
+
/** Когда срок вышел, по часам чата. */
|
|
29
|
+
at: number;
|
|
30
|
+
timeZone: string;
|
|
31
|
+
}
|
|
32
|
+
export interface FlowFinisher {
|
|
33
|
+
/** Переходы хода: вход в конечную ноду — конец `final` (или только событие у сценария 0.48). */
|
|
34
|
+
afterTransitions(input: {
|
|
35
|
+
ownerId: string;
|
|
36
|
+
chatId: string;
|
|
37
|
+
pinned: PinnedFlow;
|
|
38
|
+
run: FlowRun;
|
|
39
|
+
transitions: readonly Transition[];
|
|
40
|
+
}): Promise<void>;
|
|
41
|
+
/** «Срок вышел»: конец `deadline`, переход в `deadlineState`, событие. Возвращает место после конца. */
|
|
42
|
+
deadline(input: FlowDeadlineInput): Promise<{
|
|
43
|
+
run: ChatFlowRun;
|
|
44
|
+
ended: boolean;
|
|
45
|
+
}>;
|
|
46
|
+
/** Прощальный ход при «срок вышел» (→ В5): по правилам «писать первым»; готовый текст — без модели. */
|
|
47
|
+
farewell(input: FlowDeadlineInput & {
|
|
48
|
+
port: FlowPort;
|
|
49
|
+
firstMessages: FirstMessageRules | null;
|
|
50
|
+
delivery?: FlowDelivery;
|
|
51
|
+
}): Promise<void>;
|
|
52
|
+
/** Конец вне хода: «не завершил» (3 дня тишины), «заблокировал» (исход доставки), причина приложения (`flow.end`). Один раз. */
|
|
53
|
+
end(input: {
|
|
54
|
+
ownerId: string;
|
|
55
|
+
chatId: string;
|
|
56
|
+
pinned: PinnedFlow;
|
|
57
|
+
run: FlowRun;
|
|
58
|
+
reason: FlowEndReason;
|
|
59
|
+
outcome?: string;
|
|
60
|
+
at: number;
|
|
61
|
+
}): Promise<{
|
|
62
|
+
ended: boolean;
|
|
63
|
+
}>;
|
|
64
|
+
}
|
|
65
|
+
export declare function createFlowFinish(input: {
|
|
66
|
+
runtime: FlowRuntime;
|
|
67
|
+
onFinish?: (event: FlowFinish) => void | Promise<void>;
|
|
68
|
+
}): FlowFinisher;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReplyChecksSetting } from "@ykurilov/agent-chat-core";
|
|
2
|
+
import type { AgentFlow } from "../format/flow-format.js";
|
|
3
|
+
/** Тексты сценария: общая часть, ноды, первые сообщения, прощание, рамки дня, попутные задачи. */
|
|
4
|
+
export declare function flowKnownTexts(flow: AgentFlow): string[];
|
|
5
|
+
/**
|
|
6
|
+
* `replyChecks` службы с текстами сценария чата в `knownTexts` (после своих текстов приложения). Чат без сценария и сбой
|
|
7
|
+
* чтения сценария — только свои тексты; сбой — строка в журнал.
|
|
8
|
+
*/
|
|
9
|
+
export declare function withFlowKnownTexts(setting: ReplyChecksSetting, flowOf: (ownerId: string, chatId: string) => Promise<{
|
|
10
|
+
flow: AgentFlow;
|
|
11
|
+
} | null>, logError: (message: string) => void): ReplyChecksSetting;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FlowPort, FlowSignalInput } from "./flow-types.js";
|
|
2
|
+
import { type FlowRuntime } from "./flow-events.js";
|
|
3
|
+
/**
|
|
4
|
+
* Событие приложения с «будить»: служебное сообщение `app` (`flow_event`), агент отвечает сразу. Переход применит
|
|
5
|
+
* `prepareTurn` этого хода; у нового состояния точный первый текст — готовый ответ без модели. Срочный сигнал проходит
|
|
6
|
+
* мимо правил «писать первым» и в счётчик не идёт. Чат занят — событие ждёт начала следующего хода.
|
|
7
|
+
*/
|
|
8
|
+
export declare function sendFlowSignal(input: {
|
|
9
|
+
runtime: FlowRuntime;
|
|
10
|
+
port: FlowPort;
|
|
11
|
+
signal: FlowSignalInput;
|
|
12
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { AgentFlow } from "../format/flow-format.js";
|
|
2
|
+
import type { Transition } from "../engine/flow-run.js";
|
|
3
|
+
import type { FlowChatRecord, FlowStore } from "../store/flow-store.js";
|
|
4
|
+
import type { FirstMessageRules, FlowPort, FlowTimers, FlowTimerSettings } from "./flow-types.js";
|
|
5
|
+
import { type ChatFlowRun } from "./flow-events.js";
|
|
6
|
+
import { type FlowDelivery } from "./flow-delivery.js";
|
|
7
|
+
export declare const DEFAULT_TIMER_TICK_MS = 15000;
|
|
8
|
+
export declare const DEFAULT_TIMER_LEASE_MS = 60000;
|
|
9
|
+
/** Мягкий потолок ходов сервера подряд без сообщения человека у сценария (страховка от петли переходов по таймерам). */
|
|
10
|
+
export declare const DEFAULT_FLOW_SERVER_TURNS_IN_ROW = 50;
|
|
11
|
+
/**
|
|
12
|
+
* Тик по наступившим срокам: аренда, затем один ход «пишет первым» на все причины срока (переход ноды по таймеру,
|
|
13
|
+
* утреннее, накопленное, касание) через `deliverNotices` (вид `app`) или готовый текст. По plan.md, «Пишет первым».
|
|
14
|
+
*/
|
|
15
|
+
export declare function createFlowTimers(input: {
|
|
16
|
+
store: FlowStore;
|
|
17
|
+
settings: FlowTimerSettings;
|
|
18
|
+
firstMessages: FirstMessageRules | null;
|
|
19
|
+
/** Служба чата этого разговора. */
|
|
20
|
+
port: (chat: {
|
|
21
|
+
ownerId: string;
|
|
22
|
+
chatId: string;
|
|
23
|
+
}) => FlowPort | Promise<FlowPort>;
|
|
24
|
+
logError: (message: string) => void;
|
|
25
|
+
now: () => Date;
|
|
26
|
+
/** Сценарий версии, за которой закреплён чат. */
|
|
27
|
+
flowOf: (record: FlowChatRecord) => Promise<AgentFlow | null>;
|
|
28
|
+
/** Пояс человека: известный пояс чата, иначе приложения, иначе сервера (→ В10). */
|
|
29
|
+
timeZoneOf: (chatId: string, stored: string) => string;
|
|
30
|
+
cardValues: (ownerId: string) => Promise<Record<string, unknown>>;
|
|
31
|
+
/** Наступил «срок вышел» (этап 4): конец разговора и прощание. Нет — срок снимается. */
|
|
32
|
+
onDeadline?: (input: {
|
|
33
|
+
record: FlowChatRecord;
|
|
34
|
+
flow: AgentFlow;
|
|
35
|
+
run: ChatFlowRun;
|
|
36
|
+
at: number;
|
|
37
|
+
timeZone: string;
|
|
38
|
+
}) => Promise<void>;
|
|
39
|
+
/** «Не завершил»: тишина человека дольше `giveUpAfter` — конец без сообщения. */
|
|
40
|
+
onGiveUp?: (input: {
|
|
41
|
+
record: FlowChatRecord;
|
|
42
|
+
flow: AgentFlow;
|
|
43
|
+
run: ChatFlowRun;
|
|
44
|
+
at: number;
|
|
45
|
+
}) => Promise<void>;
|
|
46
|
+
/** Переход по таймеру применён в срок без хода: запись чата, `onTransition`, конечная нода. */
|
|
47
|
+
onAppliedTransitions?: (input: {
|
|
48
|
+
record: FlowChatRecord;
|
|
49
|
+
flow: AgentFlow;
|
|
50
|
+
run: ChatFlowRun;
|
|
51
|
+
transitions: Transition[];
|
|
52
|
+
}) => Promise<void>;
|
|
53
|
+
/** Доставка ответа в каналы приложения и счётчик дня. Нет — каналы SDK, счётчик сразу. */
|
|
54
|
+
delivery?: () => FlowDelivery;
|
|
55
|
+
}): FlowTimers;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AgentToolsSource } from "@ykurilov/agent-chat-core";
|
|
2
|
+
import { type FlowRuntime, type PinnedFlow } from "./flow-events.js";
|
|
3
|
+
import type { ClientCardTools, FlowJudge, JudgeMessage } from "./flow-types.js";
|
|
4
|
+
import type { FlowExtraTool } from "./extra-tool.js";
|
|
5
|
+
export declare const FLOW_EXIT_TOOL = "flow_exit";
|
|
6
|
+
/** Служебные инструменты возможностей сценария, каждый из своего файла. */
|
|
7
|
+
export declare const FLOW_EXTRA_TOOLS: readonly FlowExtraTool[];
|
|
8
|
+
export interface FlowToolsInput {
|
|
9
|
+
runtime: FlowRuntime;
|
|
10
|
+
judge: () => FlowJudge;
|
|
11
|
+
/** Последние реплики чата для судьи. */
|
|
12
|
+
history: (ownerId: string, chatId: string) => Promise<JudgeMessage[]>;
|
|
13
|
+
/** `flow_note` и `client_card`; модуля ещё нет — пусто. */
|
|
14
|
+
cardTools: () => ClientCardTools["tools"];
|
|
15
|
+
/**
|
|
16
|
+
* Сценарий чата, уже прочитанный в этом ходе (`prepareTurn`, инструкция); набор инструментов собирается без ожидания.
|
|
17
|
+
* Нет — только инструменты 0.48.
|
|
18
|
+
*/
|
|
19
|
+
knownFlow: (chatId: string) => PinnedFlow | undefined;
|
|
20
|
+
extraTools?: readonly FlowExtraTool[];
|
|
21
|
+
}
|
|
22
|
+
/** Служебный `flow_exit` и обёртки инструментов приложения: охрана по состоянию, события «вызван инструмент». */
|
|
23
|
+
export declare function withFlowTools(tools: AgentToolsSource | undefined, input: FlowToolsInput): AgentToolsSource;
|