|
| 1 | +import { |
| 2 | +finiteSecondsToTimerSafeMilliseconds, |
| 3 | +resolveTimerTimeoutMs, |
| 4 | +} from "@openclaw/normalization-core/number-coercion"; |
1 | 5 | import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; |
2 | 6 | import { createTypingKeepaliveLoop } from "../../channels/typing-lifecycle.js"; |
3 | 7 | import { createTypingStartGuard } from "../../channels/typing-start-guard.js"; |
4 | 8 | import { isSilentReplyPrefixText, isSilentReplyText, SILENT_REPLY_TOKEN } from "../tokens.js"; |
5 | 9 | |
| 10 | +const DEFAULT_TYPING_INTERVAL_SECONDS = 6; |
| 11 | +const DEFAULT_TYPING_TTL_MS = 2 * 60_000; |
| 12 | + |
| 13 | +function resolveTypingIntervalMs(seconds: number | undefined): number { |
| 14 | +if (Number.isFinite(seconds) && (seconds ?? 0) <= 0) { |
| 15 | +return 0; |
| 16 | +} |
| 17 | +return ( |
| 18 | +finiteSecondsToTimerSafeMilliseconds(seconds ?? DEFAULT_TYPING_INTERVAL_SECONDS) ?? |
| 19 | +DEFAULT_TYPING_INTERVAL_SECONDS * 1000 |
| 20 | +); |
| 21 | +} |
| 22 | + |
6 | 23 | export type TypingController = { |
7 | 24 | onReplyStart: () => Promise<void>; |
8 | 25 | startTypingLoop: () => Promise<void>; |
@@ -22,14 +39,7 @@ export function createTypingController(params: {
|
22 | 39 | silentToken?: string; |
23 | 40 | log?: (message: string) => void; |
24 | 41 | }): TypingController { |
25 | | -const { |
26 | | - onReplyStart, |
27 | | - onCleanup, |
28 | | - typingIntervalSeconds = 6, |
29 | | - typingTtlMs = 2 * 60_000, |
30 | | - silentToken = SILENT_REPLY_TOKEN, |
31 | | - log, |
32 | | -} = params; |
| 42 | +const { onReplyStart, onCleanup, silentToken = SILENT_REPLY_TOKEN, log } = params; |
33 | 43 | if (!onReplyStart && !onCleanup) { |
34 | 44 | return { |
35 | 45 | onReplyStart: async () => {}, |
@@ -52,7 +62,8 @@ export function createTypingController(params: {
|
52 | 62 | // Once we stop typing, we "seal" the controller so late events can't restart typing forever. |
53 | 63 | let sealed = false; |
54 | 64 | let typingTtlTimer: NodeJS.Timeout | undefined; |
55 | | -const typingIntervalMs = typingIntervalSeconds * 1000; |
| 65 | +const typingIntervalMs = resolveTypingIntervalMs(params.typingIntervalSeconds); |
| 66 | +const typingTtlMs = resolveTimerTimeoutMs(params.typingTtlMs, DEFAULT_TYPING_TTL_MS, 0); |
56 | 67 | |
57 | 68 | const formatTypingTtl = (ms: number) => { |
58 | 69 | if (ms % 60_000 === 0) { |
|