Files
msime-windows/server/tests/src/test_ai_context_policy.cpp
T
Lu Fan(SonnyCalcr) 715028e1b9 feat(server): AI 联想上下文跳过密码框、换应用清空、过滤类凭证串 (#845)
AI 联想会把最近的上屏文本作为上下文发到云端,以前不区分输入框,也跨应用累积。

- 密码 / PIN 输入框:TSF 在一段输入的首键上读 InputScope(IS_PASSWORD、IS_NUMERIC_PIN 等),
  按键包带上 FanyImePipeFlags::SensitiveField;Server 收到后不发 AI 请求,上屏也不进上下文
- 只在 AI 联想开启时才检测:Server 通过新的 worker opcode AiContextUploadChanged(34)
  告诉 TSF 开关状态,关着时按键路径只多一次 atomic load
- 上下文按焦点会话归属:client_id 或 activation_epoch 变了就清空,不再把 A 应用里打的字带进
  B 应用的请求
- 发送前去掉像凭证的 ASCII 串:不含空白、长度 >= 8 且混了字母 / 数字 / 符号中两类以上
2026-10-11 21:58:34 +08:00

35 lines
1.6 KiB
C++

#include "ipc/ai_context_policy.h"
#include "tests/includes/test_framework.h"
TEST_CASE(ai_context_drops_credential_like_ascii_runs)
{
using FanyImeIpc::StripCredentialLikeText;
REQUIRE_EQ(StripCredentialLikeText("密码是Abc12345然后"), std::string("密码是然后"));
REQUIRE_EQ(StripCredentialLikeText("key sk-proj-abcdEFGH1234 已填"), std::string("key 已填"));
REQUIRE_EQ(StripCredentialLikeText("p@ssword"), std::string());
REQUIRE_EQ(StripCredentialLikeText("2026-10-11"), std::string());
}
TEST_CASE(ai_context_keeps_plain_words_numbers_and_chinese)
{
using FanyImeIpc::StripCredentialLikeText;
REQUIRE_EQ(StripCredentialLikeText("明天3点开会"), std::string("明天3点开会"));
REQUIRE_EQ(StripCredentialLikeText("用Python写个脚本"), std::string("用Python写个脚本"));
REQUIRE_EQ(StripCredentialLikeText("international"), std::string("international"));
REQUIRE_EQ(StripCredentialLikeText("13800138000"), std::string("13800138000"));
// Short mixed runs are below the length threshold.
REQUIRE_EQ(StripCredentialLikeText("A4纸和e.g."), std::string("A4纸和e.g."));
REQUIRE_EQ(StripCredentialLikeText(""), std::string());
}
TEST_CASE(ai_context_credential_threshold_needs_length_and_two_classes)
{
using FanyImeIpc::IsCredentialLikeAsciiRun;
REQUIRE(!IsCredentialLikeAsciiRun("abc1234"));
REQUIRE(IsCredentialLikeAsciiRun("abcd1234"));
REQUIRE(!IsCredentialLikeAsciiRun("abcdefgh"));
REQUIRE(!IsCredentialLikeAsciiRun("12345678"));
REQUIRE(IsCredentialLikeAsciiRun("abcdefg!"));
REQUIRE(IsCredentialLikeAsciiRun("1234-567"));
}