mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-18 14:17:27 +00:00
60 lines
1.4 KiB
TypeScript
60 lines
1.4 KiB
TypeScript
import { createTypingKeepaliveLoop } from "./typing-lifecycle.js";
|
|
|
|
export type TypingCallbacks = {
|
|
onReplyStart: () => Promise<void>;
|
|
onIdle?: () => void;
|
|
/** Called when the typing controller is cleaned up (e.g., on NO_REPLY). */
|
|
onCleanup?: () => void;
|
|
};
|
|
|
|
export function createTypingCallbacks(params: {
|
|
start: () => Promise<void>;
|
|
stop?: () => Promise<void>;
|
|
onStartError: (err: unknown) => void;
|
|
onStopError?: (err: unknown) => void;
|
|
keepaliveIntervalMs?: number;
|
|
}): TypingCallbacks {
|
|
const stop = params.stop;
|
|
const keepaliveIntervalMs = params.keepaliveIntervalMs ?? 3_000;
|
|
let stopSent = false;
|
|
let closed = false;
|
|
|
|
const fireStart = async () => {
|
|
if (closed) {
|
|
return;
|
|
}
|
|
try {
|
|
await params.start();
|
|
} catch (err) {
|
|
params.onStartError(err);
|
|
}
|
|
};
|
|
|
|
const keepaliveLoop = createTypingKeepaliveLoop({
|
|
intervalMs: keepaliveIntervalMs,
|
|
onTick: fireStart,
|
|
});
|
|
|
|
const onReplyStart = async () => {
|
|
if (closed) {
|
|
return;
|
|
}
|
|
stopSent = false;
|
|
keepaliveLoop.stop();
|
|
await fireStart();
|
|
keepaliveLoop.start();
|
|
};
|
|
|
|
const fireStop = () => {
|
|
closed = true;
|
|
keepaliveLoop.stop();
|
|
if (!stop || stopSent) {
|
|
return;
|
|
}
|
|
stopSent = true;
|
|
void stop().catch((err) => (params.onStopError ?? params.onStartError)(err));
|
|
};
|
|
|
|
return { onReplyStart, onIdle: fireStop, onCleanup: fireStop };
|
|
}
|