mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:00:42 +00:00
fix(matrix): bind approval reactions before option emoji
This commit is contained in:
@@ -67,6 +67,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Slack/Matrix: avoid creating blank progress-draft messages when `streaming.progress.label=false` and progress tool lines are disabled. Thanks @vincentkoc.
|
||||
- Slack/Discord: suppress standalone tool-progress chatter when partial preview streaming has `streaming.preview.toolProgress: false`, matching the documented quiet-preview behavior. Thanks @vincentkoc.
|
||||
- QA/Matrix: keep the mock OpenAI tool-progress provider aligned with exact-marker Matrix prompts so the hardened live preview scenario still forces a deterministic read before final delivery. Thanks @vincentkoc.
|
||||
- Matrix: bind native approval reaction targets before publishing option reactions, so fast approver reactions on threaded prompts are not dropped while the approval handler finishes setup. Thanks @vincentkoc.
|
||||
- Google Meet: make realtime talk-back agent-driven by default with `realtime.strategy: "agent"`, keep the previous direct bidirectional model behavior available as `realtime.strategy: "bidi"`, route the Meet tab speaker output to `BlackHole 2ch` automatically for local Chrome realtime joins, coalesce nearby speech transcript fragments before consulting the agent, and avoid cutting off agent speech from server VAD or stale playback pipe errors.
|
||||
- Google Meet: suppress queued assistant playback and assistant-like transcript echoes from the realtime input path, so the meeting does not hear the agent's own speech as a new user turn and loop or cut itself off.
|
||||
- OpenAI/Google Meet: wait for realtime voice `session.updated` before treating the bridge as connected, so Meet joins do not return with audio queued behind an unconfigured realtime session. Thanks @vincentkoc.
|
||||
|
||||
@@ -266,6 +266,52 @@ describe("matrixApprovalNativeRuntime", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("binds Matrix approval reactions before publishing option reactions", async () => {
|
||||
const sendSingleTextMessage = vi.fn().mockResolvedValue({
|
||||
messageId: "$approval",
|
||||
primaryMessageId: "$approval",
|
||||
messageIds: ["$approval"],
|
||||
roomId: "!room:example.org",
|
||||
});
|
||||
const reactMessage = vi.fn().mockImplementation(async () => {
|
||||
expect(
|
||||
resolveMatrixApprovalReactionTarget({
|
||||
roomId: "!room:example.org",
|
||||
eventId: "$approval",
|
||||
reactionKey: "✅",
|
||||
}),
|
||||
).toEqual({
|
||||
approvalId: "req-1",
|
||||
decision: "allow-once",
|
||||
});
|
||||
});
|
||||
const view = buildExecApprovalView();
|
||||
const pendingPayload = await buildPendingPayload(view);
|
||||
|
||||
await matrixApprovalNativeRuntime.transport.deliverPending({
|
||||
cfg: {} as never,
|
||||
accountId: "default",
|
||||
context: {
|
||||
client: {} as never,
|
||||
deps: {
|
||||
sendSingleTextMessage,
|
||||
reactMessage,
|
||||
},
|
||||
},
|
||||
request: {} as never,
|
||||
approvalKind: "exec",
|
||||
plannedTarget: buildMatrixApprovalRoomTarget("!room:example.org"),
|
||||
preparedTarget: {
|
||||
to: "room:!room:example.org",
|
||||
roomId: "!room:example.org",
|
||||
},
|
||||
view,
|
||||
pendingPayload,
|
||||
});
|
||||
|
||||
expect(reactMessage).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("falls back to chunked Matrix delivery when approval content exceeds one event", async () => {
|
||||
const sendSingleTextMessage = vi
|
||||
.fn()
|
||||
|
||||
@@ -408,7 +408,7 @@ export const matrixApprovalNativeRuntime = createChannelApprovalNativeRuntimeAda
|
||||
: null,
|
||||
);
|
||||
},
|
||||
deliverPending: async ({ cfg, accountId, context, preparedTarget, pendingPayload }) => {
|
||||
deliverPending: async ({ cfg, accountId, context, preparedTarget, pendingPayload, view }) => {
|
||||
const resolved = resolveHandlerContext({ cfg, accountId, context });
|
||||
if (!resolved) {
|
||||
return null;
|
||||
@@ -447,6 +447,13 @@ export const matrixApprovalNativeRuntime = createChannelApprovalNativeRuntimeAda
|
||||
);
|
||||
const reactionEventId =
|
||||
result.primaryMessageId?.trim() || messageIds[0] || result.messageId.trim();
|
||||
registerMatrixApprovalReactionTarget({
|
||||
roomId: result.roomId,
|
||||
eventId: reactionEventId,
|
||||
approvalId: pendingPayload.approvalId,
|
||||
allowedDecisions: pendingPayload.allowedDecisions,
|
||||
ttlMs: view.expiresAtMs - Date.now(),
|
||||
});
|
||||
await Promise.allSettled(
|
||||
listMatrixApprovalReactionBindings(pendingPayload.allowedDecisions).map(
|
||||
async ({ emoji }) => {
|
||||
|
||||
Reference in New Issue
Block a user