refine long-running task notices

This commit is contained in:
zenord
2026-08-17 16:35:23 +08:00
parent 680a449cd8
commit 947f19e3cd
4 changed files with 44 additions and 56 deletions
+19 -35
View File
@@ -104,11 +104,11 @@ export class Gateway {
stream: new ReplyStream(message, adapter)
};
this.asyncInbounds.add(inbound);
this.armTimer(inbound, inbound.receivedAt + 15_000, message);
this.armTimer(inbound, inbound.receivedAt + 15_000);
const locked = await this.withChatLock(chatKey, async () => {
inbound.phase = "running";
if (inbound.queuedNoticeSent) void inbound.stream.enqueue("轮到这条了,我开始处理。");
if (inbound.queuedNoticeSent) void inbound.stream.enqueue("轮到这件事了,我现在开始处理。");
try {
const reply = (await this.runtime.prompt({
platform: message.platform,
@@ -200,7 +200,7 @@ export class Gateway {
return await this.runtime.cancel(message.platform, message.chatId) ? "Cancellation requested." : "No active turn to cancel.";
}
private armTimer(inbound: AsyncInbound, deadline: number, message: IncomingMessage): void {
private armTimer(inbound: AsyncInbound, deadline: number): void {
if (this.closed || inbound.phase === "finished") return;
inbound.timer?.cancel();
inbound.timer = this.schedule(() => {
@@ -208,41 +208,19 @@ export class Gateway {
if (this.closed || inbound.phase === "finished") return;
const now = this.now();
if (now < deadline) {
this.armTimer(inbound, deadline, message);
this.armTimer(inbound, deadline);
return;
}
const elapsed = now - inbound.receivedAt;
if (!inbound.initialNoticeSent) {
inbound.initialNoticeSent = true;
inbound.queuedNoticeSent = inbound.phase === "queued";
void inbound.stream.enqueue(inbound.phase === "queued"
? "前面还有任务,这条还在排队,轮到后我马上处理。"
: "这条还在处理,完成后我会直接回复。");
} else {
void inbound.stream.enqueue(this.reminderText(inbound, message));
}
this.armTimer(inbound, nextReminderDeadline(inbound.receivedAt, now), message);
void inbound.stream.enqueue(reminderText(inbound.phase, elapsed));
this.armTimer(inbound, nextReminderDeadline(inbound.receivedAt, now));
}, Math.max(0, deadline - this.now()));
}
private reminderText(inbound: AsyncInbound, message: IncomingMessage): string {
let idleSeconds: number | undefined;
try {
const value = this.runtime.status(message.platform, message.chatId).idleSeconds;
if (typeof value === "number" && Number.isFinite(value) && value >= 0) idleSeconds = Math.floor(value);
} catch {
// A status sampling failure must not affect the active turn.
}
const activity = activityText(idleSeconds);
if (inbound.phase === "queued") {
return activity
? `前面的任务还在处理,${activity};这条仍在排队,轮到后我马上处理。`
: "前面的任务还在处理,这条仍在排队,轮到后我马上处理。";
}
return activity
? `这条还在处理中,${activity};完成后我会直接回复。`
: "这条还在处理中,完成后我会直接回复。";
}
private finishInbound(inbound: AsyncInbound): void {
if (inbound.phase === "finished") return;
inbound.phase = "finished";
@@ -295,12 +273,18 @@ function nextReminderDeadline(receivedAt: number, now: number): number {
const elapsed = now - receivedAt;
if (elapsed < 60_000) return receivedAt + 60_000;
if (elapsed < 180_000) return receivedAt + 180_000;
return receivedAt + 180_000 + (Math.floor((elapsed - 180_000) / 300_000) + 1) * 300_000;
if (elapsed < 480_000) return receivedAt + 480_000;
return receivedAt + 480_000 + (Math.floor((elapsed - 480_000) / 600_000) + 1) * 600_000;
}
function activityText(idleSeconds: number | undefined): string | undefined {
if (idleSeconds === undefined) return undefined;
if (idleSeconds < 30) return "刚刚还有进展";
if (idleSeconds < 120) return `最近 ${idleSeconds} 秒没新进展`;
return `最近 ${Math.floor(idleSeconds / 60)} 分钟没新进展`;
function reminderText(phase: AsyncInbound["phase"], elapsed: number): string {
if (phase === "queued") {
return elapsed < 60_000
? "前面还有一件事没处理完,这条我记着,轮到后马上处理。"
: "前面的事情还没处理完,这条还在等。我没有漏掉,轮到后会接着做。";
}
if (elapsed < 60_000) return "收到,我还在处理,稍等我一下。";
if (elapsed < 180_000) return "还在弄,暂时还没出结果,弄好我马上回你。";
if (elapsed < 480_000) return "这件事比预想中多花了一点时间,我还在继续处理。你不用一直盯着,弄好我会直接回你。";
return "我还在处理这件事,确实花了些时间。想看看现在的状态可以发 /status,不想继续等也可以发 /cancel。";
}