mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
fix(feishu): mirror router conversationId fallback for recent-file cache
This commit is contained in:
parent
f8088088b5
commit
96ed3e8aa7
@ -1412,8 +1412,13 @@ public class FeishuChannelAdapter extends AbstractChannelAdapter implements Stre
|
||||
* {@code senderId} is the full open id. Mirror that exactly:
|
||||
* {@code groups → feishu:{shortSuffix}}, {@code DMs → feishu:{senderOpenId}}.
|
||||
*/
|
||||
private String buildConversationId(String shortSuffix, String senderOpenId, boolean isGroup) {
|
||||
String identifier = isGroup ? shortSuffix : senderOpenId;
|
||||
static String buildConversationId(String shortSuffix, String senderOpenId, boolean isGroup) {
|
||||
// The routed ChannelMessage carries chatId = (isGroup ? shortSuffix : null);
|
||||
// the router then falls back to senderId when that chatId is null. Mirror both
|
||||
// steps so the storage id matches the runtime id in every case (including the
|
||||
// degenerate group-with-no-suffix path).
|
||||
String routedChatId = isGroup ? shortSuffix : null;
|
||||
String identifier = routedChatId != null ? routedChatId : senderOpenId;
|
||||
return identifier != null ? CHANNEL_TYPE + ":" + identifier : null;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
package vip.mate.channel.feishu;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Locks the invariant that {@link FeishuChannelAdapter#buildConversationId} produces
|
||||
* exactly the id {@code ChannelMessageRouter} derives for the same chat.
|
||||
*
|
||||
* <p>The recent-file cache saves inbound attachments under
|
||||
* {@code data/chat-uploads/{conversationId}/}; the prompt only exposes a file's
|
||||
* name (not its path) to the model, so {@code ReadFileTool}/{@code DocumentExtractTool}
|
||||
* resolve it through {@code ChatUploadResolver} under the runtime conversationId.
|
||||
* If the storage id and the runtime id diverge, those tools cannot find the file
|
||||
* and document reads silently fail — which is precisely the regression these tests
|
||||
* guard against.
|
||||
*
|
||||
* <p>The router derives its id from the routed {@code ChannelMessage}, whose
|
||||
* {@code chatId} is {@code (isGroup ? shortSuffix : null)} and whose {@code senderId}
|
||||
* is the full open id, via {@code feishu:{chatId != null ? chatId : senderId}}.
|
||||
*/
|
||||
class FeishuConversationIdAlignmentTest {
|
||||
|
||||
private static final String CHANNEL = FeishuChannelAdapter.CHANNEL_TYPE; // "feishu"
|
||||
private static final String SHORT_SUFFIX = "cli2_abcd1234";
|
||||
private static final String SENDER = "ou_user0123456789";
|
||||
|
||||
/** Mirror of ChannelMessageRouter#buildConversationId against the routed message. */
|
||||
private static String routerConversationId(String shortSuffix, String senderId, boolean isGroup) {
|
||||
String routedChatId = isGroup ? shortSuffix : null;
|
||||
String identifier = routedChatId != null ? routedChatId : senderId;
|
||||
return identifier != null ? CHANNEL + ":" + identifier : null;
|
||||
}
|
||||
|
||||
@Test
|
||||
void group_usesShortSuffix() {
|
||||
assertEquals(CHANNEL + ":" + SHORT_SUFFIX,
|
||||
FeishuChannelAdapter.buildConversationId(SHORT_SUFFIX, SENDER, true));
|
||||
}
|
||||
|
||||
@Test
|
||||
void dm_usesSenderOpenIdAndIgnoresShortSuffix() {
|
||||
assertEquals(CHANNEL + ":" + SENDER,
|
||||
FeishuChannelAdapter.buildConversationId(SHORT_SUFFIX, SENDER, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void group_nullShortSuffix_fallsBackToSender() {
|
||||
// Degenerate group path: routed chatId is null, so the router (and this helper)
|
||||
// fall back to the sender open id — never null when a sender is present.
|
||||
assertEquals(CHANNEL + ":" + SENDER,
|
||||
FeishuChannelAdapter.buildConversationId(null, SENDER, true));
|
||||
}
|
||||
|
||||
@Test
|
||||
void dm_nullSender_returnsNull() {
|
||||
assertNull(FeishuChannelAdapter.buildConversationId(SHORT_SUFFIX, null, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesRouterFormula_acrossCases() {
|
||||
// Group and DM, with and without a short suffix — the storage id must equal
|
||||
// the id the router computes for the routed ChannelMessage in every case.
|
||||
assertEquals(routerConversationId(SHORT_SUFFIX, SENDER, true),
|
||||
FeishuChannelAdapter.buildConversationId(SHORT_SUFFIX, SENDER, true));
|
||||
assertEquals(routerConversationId(SHORT_SUFFIX, SENDER, false),
|
||||
FeishuChannelAdapter.buildConversationId(SHORT_SUFFIX, SENDER, false));
|
||||
assertEquals(routerConversationId(null, SENDER, true),
|
||||
FeishuChannelAdapter.buildConversationId(null, SENDER, true));
|
||||
assertEquals(routerConversationId(SHORT_SUFFIX, null, false),
|
||||
FeishuChannelAdapter.buildConversationId(SHORT_SUFFIX, null, false));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user