40 lines
1.1 KiB
TypeScript
40 lines
1.1 KiB
TypeScript
// 收件箱:会话外面发生的事要让模型知道,都先放到这里。
|
||
// 用户消息、后台命令的完成通知、问题的答复,三种来源走同一个入口。
|
||
// Loop 只在两个时刻取走:一轮开始时,以及每一步的工具都返回之后。
|
||
import type { InboxItem } from '../shared/types.ts';
|
||
|
||
export class Inbox {
|
||
private items: InboxItem[] = [];
|
||
private wake: (() => void) | null = null;
|
||
private seq = 0;
|
||
onPush: (item: InboxItem) => void = () => {};
|
||
|
||
push(item: Omit<InboxItem, 'id'>): InboxItem {
|
||
const stored = { id: `in_${++this.seq}`, ...item };
|
||
this.items.push(stored);
|
||
this.onPush(stored);
|
||
this.wake?.();
|
||
this.wake = null;
|
||
return stored;
|
||
}
|
||
|
||
// 取走当前所有内容。
|
||
drain(): InboxItem[] {
|
||
return this.items.splice(0);
|
||
}
|
||
|
||
// 停止时叫醒空闲中的 Loop,让它退出。
|
||
interrupt(): void {
|
||
this.wake?.();
|
||
this.wake = null;
|
||
}
|
||
|
||
// 空闲时等在这里,有东西进来才继续。
|
||
waitForItem(): Promise<void> {
|
||
if (this.items.length) return Promise.resolve();
|
||
return new Promise((resolve) => {
|
||
this.wake = resolve;
|
||
});
|
||
}
|
||
}
|