fix(feishu): Remove incorrect oc_ prefix assumption in resolveFeishuSession (#10407)

* fix(feishu): remove incorrect oc_ prefix assumption in resolveFeishuSession

- Feishu oc_ is a generic chat_id that can represent both groups and DMs
- Must use chat_mode field from API to distinguish, not ID prefix
- Only ou_/on_ prefixes reliably indicate user IDs (always DM)
- Fixes session misrouting for DMs with oc_ chat IDs

This bug caused DM messages with oc_ chat_ids to be incorrectly
created as group sessions, breaking session isolation and routing.

* docs: update Feishu ID format comment to reflect oc_ ambiguity

The previous comment incorrectly stated oc_ is always a group chat.
This update clarifies that oc_ chat_ids can be either groups or DMs,
and explicit prefixes (dm:/group:) should be used to distinguish.

* feishu: add regression coverage for oc session routing

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
neverland
2026-02-28 12:16:20 +08:00
committed by GitHub
parent 079bc24613
commit 6a8d83b6dd
3 changed files with 49 additions and 5 deletions

View File

@@ -973,6 +973,42 @@ describe("resolveOutboundSessionRoute", () => {
from: "slack:group:G123",
},
},
{
name: "Feishu explicit group prefix keeps group routing",
cfg: baseConfig,
channel: "feishu",
target: "group:oc_group_chat",
expected: {
sessionKey: "agent:main:feishu:group:oc_group_chat",
from: "feishu:group:oc_group_chat",
to: "oc_group_chat",
chatType: "group",
},
},
{
name: "Feishu explicit dm prefix keeps direct routing",
cfg: perChannelPeerCfg,
channel: "feishu",
target: "dm:oc_dm_chat",
expected: {
sessionKey: "agent:main:feishu:direct:oc_dm_chat",
from: "feishu:oc_dm_chat",
to: "oc_dm_chat",
chatType: "direct",
},
},
{
name: "Feishu bare oc_ target defaults to direct routing",
cfg: perChannelPeerCfg,
channel: "feishu",
target: "oc_ambiguous_chat",
expected: {
sessionKey: "agent:main:feishu:direct:oc_ambiguous_chat",
from: "feishu:oc_ambiguous_chat",
to: "oc_ambiguous_chat",
chatType: "direct",
},
},
];
for (const testCase of cases) {