Commit Graph

10 Commits

Author SHA1 Message Date
matevip
54a2c3c0a3 fix(wecom): drop pre-tool rehearsal narrations from permanent bubbles 2026-08-04 06:14:55 -04:00
matevip
ad6b0728e9 fix(channel): stop streaming replies from showing the same text twice 2026-07-29 21:29:48 -04:00
matevip
e294b32542 feat(channel): scope conversation ids by channel to stop cross-workspace bleed 2026-07-23 18:50:10 +08:00
matevip
8749c915cd feat(wecom): roll progress bubble per stage narration 2026-07-22 13:40:22 +08:00
mateaix
be836b6f0a fix(wecom): harden streaming reply management 2026-07-21 21:48:30 +08:00
matevip
bf6bed5511 feat(wecom): event-driven progress bubble with live tool trace 2026-07-21 10:29:00 +08:00
倪程伟
b478eef78c
feat(im): resolve workflow approvals via feishu/wecom card clicks (ISSUE #413 P2-B3) (#416)
Before this, a workflow await_approval step whose approverChannels
pointed at feishu/wecom was effectively dead for IM interaction. Even
after PR #414 (B1) pushed the notice to the IM group, clicking the
card's Approve/Deny buttons did nothing useful:

- Identity check (requester==clicker) failed-closed: wf- approvals
  have userId=null (system-initiated), so every click was rejected.
- Even if it passed, the synthetic /approve injection was a dead end:
  the router routes by conversationId, but wf- ids use a synthetic
  workflow:run:{runId} key that no IM conversation matches, so
  findPendingByConversation returned null and the /approve was fed
  to the LLM as plain text.

B3 fix: both ToolGuardCardHandlers now detect the wf- prefix and
resolve inline (approvalService.resolve), bypassing the synthetic
injection entirely. The WorkflowApprovalResolvedEvent published
inside resolve is picked up by ApprovalResumeBridge (activated in
PR #414 B2), which resumes the paused run. This mirrors the Web /
WebChat resolve path (PR #415).

Identity policy: any audience member may resolve a wf- approval.
The card only reaches channels declared in await_approval's
approverChannels, so whoever sees it is a designated approver.
Regular tool approvals keep the strict requester==clicker guard.

Tests:
- wecom ToolGuardCardHandlerTest: +2 wf- cases (inline resolve, no
  synthetic injection; already-resolved renders expired). Existing 6
  cases updated for the new 3-arg constructor.
- feishu FeishuCardDispatcherTest: updated for the new factory
  constructor signature.

Regression: ApprovalWorkflowServiceResolveTest (13), GcTest (7),
RecoveryTest (7), feishu dispatcher (4), button value (7),
renderer (3+3) — all green.
2026-06-25 09:56:36 +08:00
matevip
f699746d65 test(memory,wecom): align two stale tests with current production behavior
Both failed on dev independently of the recent merges (confirmed against a
pre-merge baseline):

- MemorySummarizationStructuredRoutingTest reflected applyStructuredEntries by
  its old (Long, JsonNode) signature; owner-isolation added a trailing ownerKey
  param. Update the reflective lookup to (Long, JsonNode, String) and the
  remember() verifications to the 6-arg overload.

- ToolGuardCardHandlerTest still asserted the old 'system-owned pending accepts
  any clicker' behavior, but the handler now rejects a group click on a
  system/cron-owned approval fail-closed (no human requester to match), routing
  it to the admin console. Assert no synthetic injection + the unauthorized card
  render instead.
2026-06-09 10:15:36 +08:00
matevip
a9fa8e7fb1 sync: interactive approval card on Feishu via Schema-2.0 button + card.action callback 2026-05-20 12:05:47 +08:00
matevip
0ffc224623 chore(test): backfill mateclaw-server/src/test/ that earlier PRIVATE_ITEMS pattern accidentally excluded
The PRIVATE_ITEMS list contained the bare 'test' entry, which rsync
interprets as 'any directory named test at any depth' — so it caught
the root-level /test/ scratch directory (intended) AND every src/test/
under each module (not intended).

Pattern is already anchored to /test (root-only). This commit rsyncs
the accumulated src/test/ tree forward so opensource has the unit tests
that have been written / updated against existing src/main/ code since
the pattern regression. Going forward each per-commit sync will carry
src/test/ files along with the main change.
2026-05-12 17:38:08 +08:00