mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 16:50:43 +00:00
fix: limit status reaction restore cleanup
This commit is contained in:
@@ -18,6 +18,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Discord/Slack: defer status-reaction cleanup until run finalization so queued, thinking, tool, and terminal reactions no longer flicker during normal progress updates. (#75582)
|
||||
- Discord/voice: run voice-channel turns under a voice-output policy that hides the agent `tts` tool and asks for spoken reply text, so `/vc join` sessions synthesize and play agent replies instead of ending with `NO_REPLY`. Fixes #61536. Thanks @aounakram.
|
||||
- Plugins/runtime-deps: prune legacy version-scoped plugin runtime-deps roots during bundled dependency repair and cover the path in Package Acceptance's upgrade-survivor matrix, so upgrades from 2026.4.x no longer leave stale per-plugin runtime trees after doctor runs. Thanks @vincentkoc.
|
||||
- Plugins/runtime-deps: keep Gateway startup plugin imports and runtime plugin fallback loads verify-only after startup/config repair planning, so packaged installs no longer spawn package-manager repair from hot paths after readiness. Refs #75283 and #75069. Thanks @brokemac79 and @xiaohuaxi.
|
||||
|
||||
@@ -139,6 +139,28 @@ describe("Slack status reaction lifecycle", () => {
|
||||
expect(active.has(DEFAULT_EMOJIS.thinking)).toBe(false);
|
||||
});
|
||||
|
||||
it("restoreInitial removes only tracked active reactions", async () => {
|
||||
const { adapter, active } = createSlackMockAdapter();
|
||||
const ctrl = createStatusReactionController({
|
||||
enabled: true,
|
||||
adapter,
|
||||
initialEmoji: "eyes",
|
||||
timing: { debounceMs: 0, stallSoftMs: 99999, stallHardMs: 99999 },
|
||||
});
|
||||
|
||||
void ctrl.setQueued();
|
||||
await vi.advanceTimersByTimeAsync(10);
|
||||
await ctrl.setDone();
|
||||
|
||||
await ctrl.restoreInitial();
|
||||
|
||||
expect(active.has("eyes")).toBe(true);
|
||||
expect(active.has(DEFAULT_EMOJIS.done)).toBe(false);
|
||||
expect(adapter.removeReaction).toHaveBeenCalledTimes(1);
|
||||
expect(adapter.removeReaction).toHaveBeenCalledWith(DEFAULT_EMOJIS.done);
|
||||
expect(adapter.removeReaction).not.toHaveBeenCalledWith(DEFAULT_EMOJIS.thinking);
|
||||
});
|
||||
|
||||
it("restoreInitial still applies initial emoji when it is only debounced", async () => {
|
||||
const { adapter, active } = createSlackMockAdapter();
|
||||
const ctrl = createStatusReactionController({
|
||||
|
||||
@@ -160,21 +160,6 @@ export function createStatusReactionController(params: {
|
||||
let chainPromise = Promise.resolve();
|
||||
const activeEmojis = new Set<string>();
|
||||
|
||||
// Known emojis for clear operation
|
||||
const knownEmojis = new Set<string>([
|
||||
initialEmoji,
|
||||
emojis.queued,
|
||||
emojis.thinking,
|
||||
emojis.tool,
|
||||
emojis.coding,
|
||||
emojis.web,
|
||||
emojis.done,
|
||||
emojis.error,
|
||||
emojis.stallSoft,
|
||||
emojis.stallHard,
|
||||
emojis.compacting,
|
||||
]);
|
||||
|
||||
/**
|
||||
* Serialize async operations to prevent race conditions.
|
||||
*/
|
||||
@@ -231,12 +216,12 @@ export function createStatusReactionController(params: {
|
||||
}, timing.stallHardMs);
|
||||
}
|
||||
|
||||
async function removeKnownEmojis(options: { keepEmoji?: string } = {}): Promise<void> {
|
||||
async function removeActiveEmojis(options: { keepEmoji?: string } = {}): Promise<void> {
|
||||
if (!adapter.removeReaction) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const emoji of knownEmojis) {
|
||||
for (const emoji of Array.from(activeEmojis)) {
|
||||
if (emoji === options.keepEmoji) {
|
||||
continue;
|
||||
}
|
||||
@@ -378,7 +363,7 @@ export function createStatusReactionController(params: {
|
||||
|
||||
await enqueue(async () => {
|
||||
if (adapter.removeReaction) {
|
||||
await removeKnownEmojis();
|
||||
await removeActiveEmojis();
|
||||
} else {
|
||||
// For platforms without removeReaction, set empty or just skip
|
||||
// (Telegram handles this atomically on the next setReaction)
|
||||
@@ -409,7 +394,7 @@ export function createStatusReactionController(params: {
|
||||
|
||||
await enqueue(async () => {
|
||||
await applyEmoji(initialEmoji);
|
||||
await removeKnownEmojis({ keepEmoji: initialEmoji });
|
||||
await removeActiveEmojis({ keepEmoji: initialEmoji });
|
||||
pendingEmoji = "";
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user