@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.
- package/CHANGELOG.md +12 -0
- package/dist/{chunk-KGWXTWBZ.js → chunk-22FWN7NU.js} +2 -2
- package/dist/{chunk-H3AN5YUN.js → chunk-3K72EVAT.js} +2 -2
- package/dist/{chunk-LT4QELAZ.js → chunk-5RDY7QBA.js} +34 -9
- package/dist/chunk-5RDY7QBA.js.map +1 -0
- package/dist/format.js +4 -2
- package/dist/index.js +65 -5
- package/dist/index.js.map +1 -1
- package/dist/react.js +28 -3
- package/dist/react.js.map +1 -1
- package/dist/types/format/index.d.ts +1 -0
- package/dist/types/format/parse-duration.d.ts +5 -0
- package/dist/types/labels/test-chat.d.ts +8 -0
- package/dist/types/react/flow-editor-skin.d.ts +6 -0
- package/dist/types/react/test-chat/use-flow-test-chat.d.ts +12 -0
- package/dist/types/runtime/flow-types.d.ts +27 -6
- package/dist/types/runtime/index.d.ts +1 -1
- package/dist/types/runtime/test-clock.d.ts +7 -4
- package/package.json +4 -4
- package/dist/chunk-LT4QELAZ.js.map +0 -1
- /package/dist/{chunk-KGWXTWBZ.js.map → chunk-22FWN7NU.js.map} +0 -0
- /package/dist/{chunk-H3AN5YUN.js.map → chunk-3K72EVAT.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
sideTaskFieldKnown,
|
|
15
15
|
sideTaskRecord,
|
|
16
16
|
sideTaskStanding
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-3K72EVAT.js";
|
|
18
18
|
import {
|
|
19
19
|
FACT_PREFIX,
|
|
20
20
|
MAX_FACTS,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
fieldValueText,
|
|
27
27
|
isFactEntry,
|
|
28
28
|
sameFact
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-22FWN7NU.js";
|
|
30
30
|
import {
|
|
31
31
|
AGENT_FLOW_FORMAT,
|
|
32
32
|
AGENT_FLOW_FORMAT_VERSION,
|
|
@@ -92,6 +92,7 @@ import {
|
|
|
92
92
|
noteSideQuestion,
|
|
93
93
|
overdueOnEntry,
|
|
94
94
|
parseBooleanAnswer,
|
|
95
|
+
parseDuration,
|
|
95
96
|
parseFlow,
|
|
96
97
|
placeOfPath,
|
|
97
98
|
returnTarget,
|
|
@@ -105,7 +106,7 @@ import {
|
|
|
105
106
|
withDayAnchor,
|
|
106
107
|
withNudgeStep,
|
|
107
108
|
withoutUndeliveredTouch
|
|
108
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-5RDY7QBA.js";
|
|
109
110
|
import {
|
|
110
111
|
appliedInTime,
|
|
111
112
|
byVersionAndState,
|
|
@@ -1020,6 +1021,15 @@ function testChatOffset(data) {
|
|
|
1020
1021
|
return typeof offset === "number" && Number.isFinite(offset) ? offset : 0;
|
|
1021
1022
|
}
|
|
1022
1023
|
var chatTime = (run, serverNow) => serverNow + (run?.timeOffset ?? 0);
|
|
1024
|
+
var FlowTestClockError = class extends Error {
|
|
1025
|
+
constructor(code, message) {
|
|
1026
|
+
super(message);
|
|
1027
|
+
this.code = code;
|
|
1028
|
+
this.name = "FlowTestClockError";
|
|
1029
|
+
}
|
|
1030
|
+
code;
|
|
1031
|
+
};
|
|
1032
|
+
var NEXT_FIRST_MESSAGE_STEPS = 50;
|
|
1023
1033
|
var TURN_WAIT_LIMIT = 5;
|
|
1024
1034
|
async function placeRun(runtime, port, chat, flow, now) {
|
|
1025
1035
|
const { values } = await port.getChatState(chat.ownerId, chat.chatId);
|
|
@@ -1049,7 +1059,8 @@ async function advanceTestClock(input) {
|
|
|
1049
1059
|
const { runtime, port, timers, ownerId, chatId, clock } = input;
|
|
1050
1060
|
const offset = testChatOffset(await port.getChatData(ownerId, chatId));
|
|
1051
1061
|
if (offset === null) throw new Error(`\u0427\u0430\u0442 ${chatId} \u043D\u0435 \u0442\u0435\u0441\u0442\u043E\u0432\u044B\u0439: \u0447\u0430\u0441\u044B \u043F\u0435\u0440\u0435\u043C\u0430\u0442\u044B\u0432\u0430\u044E\u0442\u0441\u044F \u0442\u043E\u043B\u044C\u043A\u043E \u0443 \u0442\u0435\u0441\u0442\u043E\u0432\u044B\u0445 \u0447\u0430\u0442\u043E\u0432`);
|
|
1052
|
-
|
|
1062
|
+
if (clock.to === "next_first_message") return advanceToNextFirstMessage({ runtime, port, timers, ownerId, chatId, offset });
|
|
1063
|
+
const ms = clock.to === "next_day_start" ? await msToNextDay(runtime, port, ownerId, chatId, offset) : clock.ms ?? Number.NaN;
|
|
1053
1064
|
if (!Number.isFinite(ms) || ms <= 0) throw new Error("\u041F\u0435\u0440\u0435\u043C\u043E\u0442\u043A\u0430 \u0447\u0430\u0441\u043E\u0432: \u043D\u0443\u0436\u0435\u043D \u0441\u0434\u0432\u0438\u0433 \u0432\u043F\u0435\u0440\u0451\u0434, \u043C\u0441 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0443\u043B\u044F");
|
|
1054
1065
|
const timeOffset = offset + ms;
|
|
1055
1066
|
await port.updateChatData(ownerId, chatId, { [FLOW_TEST_CHAT_KEY]: { timeOffset } });
|
|
@@ -1062,6 +1073,37 @@ async function advanceTestClock(input) {
|
|
|
1062
1073
|
await turnFinished(port, ownerId, chatId);
|
|
1063
1074
|
return { timeOffset };
|
|
1064
1075
|
}
|
|
1076
|
+
var nothingScheduled = (chatId) => new FlowTestClockError("nothing_scheduled", `\u0427\u0430\u0442 ${chatId}: \u0432\u043F\u0435\u0440\u0435\u0434\u0438 \u0441\u0446\u0435\u043D\u0430\u0440\u0438\u0439 \u0441\u0430\u043C \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u043F\u0438\u0448\u0435\u0442 \u2014 \u043F\u0435\u0440\u0435\u043C\u0430\u0442\u044B\u0432\u0430\u0442\u044C \u043D\u0435 \u043A \u0447\u0435\u043C\u0443`);
|
|
1077
|
+
async function advanceToNextFirstMessage(input) {
|
|
1078
|
+
const { runtime, port, timers, ownerId, chatId } = input;
|
|
1079
|
+
const pinned = timers && await runtime.chatFlow(ownerId, chatId);
|
|
1080
|
+
if (!timers?.watch || !pinned) throw nothingScheduled(chatId);
|
|
1081
|
+
let timeOffset = input.offset;
|
|
1082
|
+
for (let step = 0; step < NEXT_FIRST_MESSAGE_STEPS; step += 1) {
|
|
1083
|
+
const run = await placeRun(runtime, port, { ownerId, chatId }, pinned.flow, runtime.now() + timeOffset);
|
|
1084
|
+
if (!run) throw nothingScheduled(chatId);
|
|
1085
|
+
if (step === 0) await timers.reschedule({ ownerId, chatId, run: { ...run, timeOffset }, branchHead: run.answerId ?? null });
|
|
1086
|
+
const record = await runtime.store.getChat(chatId);
|
|
1087
|
+
if (!record || record.endedAt !== null || record.dueAt === null) throw nothingScheduled(chatId);
|
|
1088
|
+
const serverNow = runtime.now();
|
|
1089
|
+
const shift = Math.max(0, Date.parse(record.dueAt) - serverNow);
|
|
1090
|
+
if (shift > 0) {
|
|
1091
|
+
timeOffset += shift;
|
|
1092
|
+
await port.updateChatData(ownerId, chatId, { [FLOW_TEST_CHAT_KEY]: { timeOffset } });
|
|
1093
|
+
await runtime.store.setDue(chatId, { at: new Date(serverNow).toISOString(), exitId: record.dueExitId ?? FLOW_FIRST_EXIT, branchHead: record.dueBranchHead });
|
|
1094
|
+
}
|
|
1095
|
+
let reason = null;
|
|
1096
|
+
const unwatch = timers.watch(chatId, (fired) => reason ??= fired);
|
|
1097
|
+
try {
|
|
1098
|
+
await timers.tick();
|
|
1099
|
+
await turnFinished(port, ownerId, chatId);
|
|
1100
|
+
} finally {
|
|
1101
|
+
unwatch();
|
|
1102
|
+
}
|
|
1103
|
+
if (reason) return { timeOffset, reason };
|
|
1104
|
+
}
|
|
1105
|
+
throw new FlowTestClockError("not_reached", `\u0427\u0430\u0442 ${chatId}: \u0441\u0440\u043E\u043A \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u043E\u0442\u043A\u043B\u0430\u0434\u044B\u0432\u0430\u043B\u0441\u044F ${NEXT_FIRST_MESSAGE_STEPS} \u0440\u0430\u0437 \u043F\u043E\u0434\u0440\u044F\u0434 \u2014 \u043F\u0435\u0440\u0435\u043C\u043E\u0442\u043A\u0430 \u043E\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0430`);
|
|
1106
|
+
}
|
|
1065
1107
|
|
|
1066
1108
|
// src/runtime/flow-finish.ts
|
|
1067
1109
|
var FLOW_DEADLINE_NOTICE = "flow_deadline";
|
|
@@ -1501,6 +1543,10 @@ function createFlowTimers(input) {
|
|
|
1501
1543
|
const owner = `flow-timers:${randomUUID()}`;
|
|
1502
1544
|
let interval;
|
|
1503
1545
|
let running = null;
|
|
1546
|
+
const watchers = /* @__PURE__ */ new Map();
|
|
1547
|
+
const fired = (chatId, reason) => {
|
|
1548
|
+
for (const onFired of watchers.get(chatId) ?? []) onFired(reason);
|
|
1549
|
+
};
|
|
1504
1550
|
const dueInput = (due, branchHead, offset) => ({ at: isoOf2(due.at - offset), exitId: due.exitId, branchHead });
|
|
1505
1551
|
async function placeOf2(record, chatPort, run, failedAt) {
|
|
1506
1552
|
const pausedUntil = record.pausedUntil === null ? null : Date.parse(record.pausedUntil);
|
|
@@ -1625,11 +1671,14 @@ function createFlowTimers(input) {
|
|
|
1625
1671
|
await store.setDue(chatId, null);
|
|
1626
1672
|
const endAt = flow.schedule ? deadlineAt(run, timeZone, flow.schedule) ?? wake.at : wake.at;
|
|
1627
1673
|
await input.onDeadline?.({ record, flow, run, at: endAt, timeZone });
|
|
1674
|
+
const deadlineState = flow.schedule?.deadlineState;
|
|
1675
|
+
fired(chatId, { kind: "deadline", stateId: deadlineState && stateById(flow, deadlineState) ? deadlineState : run.state });
|
|
1628
1676
|
return;
|
|
1629
1677
|
}
|
|
1630
1678
|
if (due.giveUp) {
|
|
1631
1679
|
await store.setDue(chatId, null);
|
|
1632
1680
|
await input.onGiveUp?.({ record, flow, run, at });
|
|
1681
|
+
fired(chatId, { kind: "give_up", stateId: run.state });
|
|
1633
1682
|
return;
|
|
1634
1683
|
}
|
|
1635
1684
|
const transitions = [];
|
|
@@ -1710,6 +1759,7 @@ function createFlowTimers(input) {
|
|
|
1710
1759
|
const answered = nudgeStep === void 0 ? noteAgentAnswer(next, at) : withNudgeStep(noteAgentAnswer(next, at), nudgeStep, nudgeStepOwn === true);
|
|
1711
1760
|
const following = nextWake(flow, answered, at, timeZone, { pausedUntil: context.pausedUntil ?? null });
|
|
1712
1761
|
await store.setDue(chatId, following ? dueInput(following, result.messageId ?? null, offset) : null, { unlessDelivery: true });
|
|
1762
|
+
fired(chatId, { kind: reasons[0].kind, stateId: next.state, ...moved && { exitId: due.exitId }, reasons });
|
|
1713
1763
|
if (!delivery) {
|
|
1714
1764
|
await firstMessages?.record({ ownerId, at, timeZone });
|
|
1715
1765
|
return;
|
|
@@ -1764,7 +1814,15 @@ function createFlowTimers(input) {
|
|
|
1764
1814
|
});
|
|
1765
1815
|
},
|
|
1766
1816
|
tick,
|
|
1767
|
-
reschedule
|
|
1817
|
+
reschedule,
|
|
1818
|
+
watch(chatId, onFired) {
|
|
1819
|
+
const listeners = watchers.get(chatId) ?? /* @__PURE__ */ new Set();
|
|
1820
|
+
watchers.set(chatId, listeners.add(onFired));
|
|
1821
|
+
return () => {
|
|
1822
|
+
listeners.delete(onFired);
|
|
1823
|
+
if (listeners.size === 0) watchers.delete(chatId);
|
|
1824
|
+
};
|
|
1825
|
+
}
|
|
1768
1826
|
};
|
|
1769
1827
|
}
|
|
1770
1828
|
|
|
@@ -3289,6 +3347,7 @@ export {
|
|
|
3289
3347
|
FLOW_TIMER_SPANS,
|
|
3290
3348
|
FLOW_TIMER_UNITS,
|
|
3291
3349
|
FLOW_TIME_ZONE_TOOL,
|
|
3350
|
+
FlowTestClockError,
|
|
3292
3351
|
RETURN_TARGET,
|
|
3293
3352
|
activeExits,
|
|
3294
3353
|
agentFlowSchema,
|
|
@@ -3333,6 +3392,7 @@ export {
|
|
|
3333
3392
|
noteRejectedClaim,
|
|
3334
3393
|
noteSideQuestion,
|
|
3335
3394
|
openSideTasks,
|
|
3395
|
+
parseDuration,
|
|
3336
3396
|
parseFlow,
|
|
3337
3397
|
placeOfPath,
|
|
3338
3398
|
resolveFirstMessages,
|