mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-07 16:31:23 +00:00
fix(discord): defer component interactions to prevent timeout (#16287)
* fix(discord): defer component interactions to prevent timeout Discord requires interaction responses within 3 seconds. Button clicks were routed through the LLM pipeline before responding, exceeding this window and showing 'This interaction failed' to users. Now immediately defers the interaction, then processes the agent response asynchronously. Fixes #16262 * fix: harden deferred interaction replies and silent chat finals (#16287) (thanks @robbyczgw-cla) --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -56,6 +56,16 @@ export class ChatLog extends Container {
|
||||
this.addChild(new AssistantMessageComponent(text));
|
||||
}
|
||||
|
||||
dropAssistant(runId?: string) {
|
||||
const effectiveRunId = this.resolveRunId(runId);
|
||||
const existing = this.streamingRuns.get(effectiveRunId);
|
||||
if (!existing) {
|
||||
return;
|
||||
}
|
||||
this.removeChild(existing);
|
||||
this.streamingRuns.delete(effectiveRunId);
|
||||
}
|
||||
|
||||
startTool(toolCallId: string, toolName: string, args: unknown) {
|
||||
const existing = this.toolById.get(toolCallId);
|
||||
if (existing) {
|
||||
|
||||
@@ -6,7 +6,12 @@ import { createEventHandlers } from "./tui-event-handlers.js";
|
||||
|
||||
type MockChatLog = Pick<
|
||||
ChatLog,
|
||||
"startTool" | "updateToolResult" | "addSystem" | "updateAssistant" | "finalizeAssistant"
|
||||
| "startTool"
|
||||
| "updateToolResult"
|
||||
| "addSystem"
|
||||
| "updateAssistant"
|
||||
| "finalizeAssistant"
|
||||
| "dropAssistant"
|
||||
>;
|
||||
type MockTui = Pick<TUI, "requestRender">;
|
||||
|
||||
@@ -41,6 +46,7 @@ describe("tui-event-handlers: handleAgentEvent", () => {
|
||||
addSystem: vi.fn(),
|
||||
updateAssistant: vi.fn(),
|
||||
finalizeAssistant: vi.fn(),
|
||||
dropAssistant: vi.fn(),
|
||||
};
|
||||
const tui: MockTui = { requestRender: vi.fn() };
|
||||
const setActivityStatus = vi.fn();
|
||||
@@ -357,4 +363,33 @@ describe("tui-event-handlers: handleAgentEvent", () => {
|
||||
|
||||
expect(loadHistory).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("drops streaming assistant when chat final has no message", () => {
|
||||
const state = makeState({ activeChatRunId: null });
|
||||
const { chatLog, tui, setActivityStatus } = makeContext(state);
|
||||
const { handleChatEvent } = createEventHandlers({
|
||||
chatLog,
|
||||
tui,
|
||||
state,
|
||||
setActivityStatus,
|
||||
});
|
||||
|
||||
handleChatEvent({
|
||||
runId: "run-silent",
|
||||
sessionKey: state.currentSessionKey,
|
||||
state: "delta",
|
||||
message: { content: "hello" },
|
||||
});
|
||||
chatLog.dropAssistant.mockClear();
|
||||
chatLog.finalizeAssistant.mockClear();
|
||||
|
||||
handleChatEvent({
|
||||
runId: "run-silent",
|
||||
sessionKey: state.currentSessionKey,
|
||||
state: "final",
|
||||
});
|
||||
|
||||
expect(chatLog.dropAssistant).toHaveBeenCalledWith("run-silent");
|
||||
expect(chatLog.finalizeAssistant).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -109,6 +109,20 @@ export function createEventHandlers(context: EventHandlerContext) {
|
||||
setActivityStatus("streaming");
|
||||
}
|
||||
if (evt.state === "final") {
|
||||
if (!evt.message) {
|
||||
if (isLocalRunId?.(evt.runId)) {
|
||||
forgetLocalRunId?.(evt.runId);
|
||||
} else {
|
||||
void loadHistory?.();
|
||||
}
|
||||
chatLog.dropAssistant(evt.runId);
|
||||
noteFinalizedRun(evt.runId);
|
||||
state.activeChatRunId = null;
|
||||
setActivityStatus("idle");
|
||||
void refreshSessionInfo?.();
|
||||
tui.requestRender();
|
||||
return;
|
||||
}
|
||||
if (isCommandMessage(evt.message)) {
|
||||
if (isLocalRunId?.(evt.runId)) {
|
||||
forgetLocalRunId?.(evt.runId);
|
||||
|
||||
Reference in New Issue
Block a user