docs(comments): 注释中文化 · internal/services/channelbridge(纯替换)
- 只翻注释/文档字符串:剥掉注释后代码行逐字节不变(机械校验只剩允许的行尾注释形态) - 术语对齐既有译法(owner→主人、persona→角色、engage→参与度判定、quiet hours→安静时段、backoff→退避) - 复核:go build 绿 + channelbridge 包测试绿;gofmt 干净
This commit is contained in:
1 parent
61cf80d5ee
commit
093f38d986
28 files changed
+1089
-1089
No files matched your search
@@ -18,8 +18,8 @@ func newProactiveBridge(t *testing.T, owner *user.OwnerProfile, ads ...*fakeAdap
|
||||
return newProactiveBridgeHist(t, owner, nil, ads...)
|
||||
}
|
||||
|
||||
// newProactiveBridgeHist is newProactiveBridge with a history store injected, so a
|
||||
// test can supply a recent window for the "she was last active here" selection.
|
||||
// newProactiveBridgeHist 是注入了历史存储的 newProactiveBridge,便于
|
||||
// 测试为「她最近在哪里活跃」的选择供给近期窗口。
|
||||
func newProactiveBridgeHist(t *testing.T, owner *user.OwnerProfile, hist history.HistoryStore, ads ...*fakeAdapter) *Bridge {
|
||||
t.Helper()
|
||||
chat := &stubChatter{res: &loop.Result{Text: "hi"}}
|
||||
@@ -36,8 +36,8 @@ func newProactiveBridgeHist(t *testing.T, owner *user.OwnerProfile, hist history
|
||||
return b
|
||||
}
|
||||
|
||||
// proactiveMsg builds a minimal autonomous proactive message as backthink's
|
||||
// buildProactiveMessage would for a no-channel decision (the generic sentinel).
|
||||
// proactiveMsg 构建一条最小化的自主主动消息,等同于 backthink 的
|
||||
// buildProactiveMessage 在无渠道决策(通用哨兵值)时的产物。
|
||||
func proactiveMsg(content string) adapter.UnifiedMessage {
|
||||
return adapter.UnifiedMessage{
|
||||
Platform: "cyrene-backthink",
|
||||
@@ -48,9 +48,9 @@ func proactiveMsg(content string) adapter.UnifiedMessage {
|
||||
}
|
||||
}
|
||||
|
||||
// TestBridge_SendProactive_OwnerChannel verifies a proactive push with no signal
|
||||
// falls back to a whitelisted owner channel: the adapter for the owner's platform
|
||||
// is selected and the owner account id is threaded as the DM peer.
|
||||
// TestBridge_SendProactive_OwnerChannel 验证无信号的主动推送
|
||||
// 回退到白名单主人渠道:选中主人平台对应的适配器,
|
||||
// 并把主人账号 id 作为私聊对端串入。
|
||||
func TestBridge_SendProactive_OwnerChannel(t *testing.T) {
|
||||
ad := &fakeAdapter{name: "telegram", connected: true}
|
||||
owner := &user.OwnerProfile{Accounts: []user.OwnerAccount{{Platform: "telegram", AccountID: "100"}}}
|
||||
@@ -77,9 +77,9 @@ func TestBridge_SendProactive_OwnerChannel(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestBridge_SendProactive_PlatformHintSelectsAccount verifies msg.Platform
|
||||
// selects the matching owner account when one exists and is connected, rather
|
||||
// than defaulting to another channel.
|
||||
// TestBridge_SendProactive_PlatformHintSelectsAccount 验证 msg.Platform
|
||||
// 在存在且已连接匹配的主人账号时选中它,
|
||||
// 而不是默认落到另一个渠道。
|
||||
func TestBridge_SendProactive_PlatformHintSelectsAccount(t *testing.T) {
|
||||
ad := &fakeAdapter{name: "kook", connected: true}
|
||||
owner := &user.OwnerProfile{Accounts: []user.OwnerAccount{
|
||||
@@ -102,9 +102,9 @@ func TestBridge_SendProactive_PlatformHintSelectsAccount(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestBridge_SendProactive_DecisionHintPriority verifies a concrete [渠道:...]
|
||||
// decision beats the recent-active platform: even though she last used WeChat, an
|
||||
// explicit kook choice is honored (and still only one channel is used).
|
||||
// TestBridge_SendProactive_DecisionHintPriority 验证具体的 [渠道:...]
|
||||
// 决策优先于最近活跃平台:即使她上次用的是 WeChat,
|
||||
// 显式的 kook 选择仍被采纳(且仍只用一个渠道)。
|
||||
func TestBridge_SendProactive_DecisionHintPriority(t *testing.T) {
|
||||
kook := &fakeAdapter{name: "kook", connected: true}
|
||||
weixin := &fakeAdapter{name: "weixin-ilink", connected: true}
|
||||
@@ -132,9 +132,9 @@ func TestBridge_SendProactive_DecisionHintPriority(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestBridge_SendProactive_RecentActivePlatform verifies a no-decision push lands
|
||||
// on the channel she used most recently, skipping the web session (web is not a
|
||||
// whitelisted IM account) and honoring a whitelisted, connected IM channel.
|
||||
// TestBridge_SendProactive_RecentActivePlatform 验证无决策的推送
|
||||
// 落在她最近使用的渠道上,跳过 Web 会话(Web 不是
|
||||
// 白名单 IM 账号),并采用白名单且已连接的 IM 渠道。
|
||||
func TestBridge_SendProactive_RecentActivePlatform(t *testing.T) {
|
||||
kook := &fakeAdapter{name: "kook", connected: true}
|
||||
weixin := &fakeAdapter{name: "weixin-ilink", connected: true}
|
||||
@@ -142,9 +142,9 @@ func TestBridge_SendProactive_RecentActivePlatform(t *testing.T) {
|
||||
{Platform: "kook", AccountID: "329284282"},
|
||||
{Platform: "weixin-ilink", AccountID: "o9cq802QPKPscBenJAp-SMZPBlnQ@im.wechat"},
|
||||
}}
|
||||
// Recent is oldest-first: the newest message is the web session, then WeChat,
|
||||
// then kook. The web session is skipped (not whitelisted), so the most recent
|
||||
// whitelisted, connected channel — WeChat — is chosen.
|
||||
// Recent 是最旧在前:最新消息来自 Web 会话,然后是 WeChat,
|
||||
// 再是 kook。Web 会话被跳过(不在白名单),因此选中
|
||||
// 最近的白名单已连接渠道——WeChat。
|
||||
hist := &contextHistory{recent: []history.Message{
|
||||
{Role: history.RoleUser, Platform: "kook", Content: "一早聊过", CreatedAt: 1},
|
||||
{Role: history.RoleUser, Platform: "weixin-ilink", Content: "微信聊的", CreatedAt: 2},
|
||||
@@ -166,9 +166,9 @@ func TestBridge_SendProactive_RecentActivePlatform(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestBridge_SendProactive_WeChatCanBeSelected verifies WeChat is a first-class
|
||||
// proactive target: with a WeChat account whitelisted and its adapter connected, a
|
||||
// no-signal push lands on it rather than always defaulting to kook.
|
||||
// TestBridge_SendProactive_WeChatCanBeSelected 验证 WeChat 是一等的
|
||||
// 主动推送目标:WeChat 账号在白名单且适配器已连接时,
|
||||
// 无信号推送落在它上面,而不是总默认到 kook。
|
||||
func TestBridge_SendProactive_WeChatCanBeSelected(t *testing.T) {
|
||||
weixin := &fakeAdapter{name: "weixin-ilink", connected: true}
|
||||
owner := &user.OwnerProfile{Accounts: []user.OwnerAccount{{Platform: "weixin-ilink", AccountID: "o9cq802QPKPscBenJAp-SMZPBlnQ@im.wechat"}}}
|
||||
@@ -188,9 +188,9 @@ func TestBridge_SendProactive_WeChatCanBeSelected(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestBridge_SendProactive_NoSignalFallbackRotates verifies the no-signal fallback
|
||||
// rotates across connected whitelisted channels (instead of always kook), and that
|
||||
// each push reaches exactly one channel.
|
||||
// TestBridge_SendProactive_NoSignalFallbackRotates 验证无信号回退
|
||||
// 会在已连接的白名单渠道间轮转(而不是总是 kook),且
|
||||
// 每次推送只到达一个渠道。
|
||||
func TestBridge_SendProactive_NoSignalFallbackRotates(t *testing.T) {
|
||||
kook := &fakeAdapter{name: "kook", connected: true}
|
||||
weixin := &fakeAdapter{name: "weixin-ilink", connected: true}
|
||||
@@ -219,17 +219,17 @@ func TestBridge_SendProactive_NoSignalFallbackRotates(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestBridge_SendProactive_HintNotWhitelisted_FallsBackToWeChat verifies a concrete
|
||||
// decision channel that is NOT whitelisted degrades to a whitelisted, connected
|
||||
// owner channel rather than erroring or landing on a non-owner channel. This is
|
||||
// how WeChat becomes reachable even though the old default never considered it.
|
||||
// TestBridge_SendProactive_HintNotWhitelisted_FallsBackToWeChat 验证
|
||||
// 不在白名单的具体决策渠道会退化为白名单且已连接的
|
||||
// 主人渠道,而不是报错或落到非主人渠道。这正是
|
||||
// WeChat 变得可达的方式,尽管旧的默认逻辑从不考虑它。
|
||||
func TestBridge_SendProactive_HintNotWhitelisted_FallsBackToWeChat(t *testing.T) {
|
||||
weixin := &fakeAdapter{name: "weixin-ilink", connected: true}
|
||||
owner := &user.OwnerProfile{Accounts: []user.OwnerAccount{{Platform: "weixin-ilink", AccountID: "o9cq802QPKPscBenJAp-SMZPBlnQ@im.wechat"}}}
|
||||
b := newProactiveBridge(t, owner, weixin)
|
||||
|
||||
msg := proactiveMsg("记得喝水哦")
|
||||
msg.Platform = "kook" // kook is not whitelisted for this owner
|
||||
msg.Platform = "kook" // kook 不在该主人的白名单里
|
||||
if err := b.SendProactive(context.Background(), msg); err != nil {
|
||||
t.Fatalf("SendProactive err = %v (a non-whitelisted hint should fall back, not error)", err)
|
||||
}
|
||||
@@ -241,8 +241,8 @@ func TestBridge_SendProactive_HintNotWhitelisted_FallsBackToWeChat(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
// TestBridge_SendProactive_NoOwnerChannel verifies a clear error when the owner
|
||||
// profile has no whitelisted account, so the caller records the reason.
|
||||
// TestBridge_SendProactive_NoOwnerChannel 验证主人档案没有
|
||||
// 白名单账号时返回明确错误,便于调用方记录原因。
|
||||
func TestBridge_SendProactive_NoOwnerChannel(t *testing.T) {
|
||||
b := newProactiveBridge(t, &user.OwnerProfile{})
|
||||
|
||||
@@ -255,8 +255,8 @@ func TestBridge_SendProactive_NoOwnerChannel(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestBridge_SendProactive_NoAdapter verifies the error when the owner has a
|
||||
// whitelisted channel but no adapter is registered/connected for it.
|
||||
// TestBridge_SendProactive_NoAdapter 验证主人有白名单渠道、
|
||||
// 但该渠道没有已注册/已连接适配器时报错。
|
||||
func TestBridge_SendProactive_NoAdapter(t *testing.T) {
|
||||
owner := &user.OwnerProfile{Accounts: []user.OwnerAccount{{Platform: "kook", AccountID: "329284282"}}}
|
||||
b := newProactiveBridge(t, owner)
|
||||
@@ -270,8 +270,8 @@ func TestBridge_SendProactive_NoAdapter(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestBridge_SendProactive_AdapterError verifies an adapter send failure surfaces
|
||||
// as a wrapped error with the platform (so the record/detail is honest).
|
||||
// TestBridge_SendProactive_AdapterError 验证适配器发送失败会以
|
||||
// 带平台的包装错误暴露(使记录/详情如实)。
|
||||
func TestBridge_SendProactive_AdapterError(t *testing.T) {
|
||||
ad := &fakeAdapter{name: "kook", connected: true, sendErr: errors.New("kook disconnected")}
|
||||
owner := &user.OwnerProfile{Accounts: []user.OwnerAccount{{Platform: "kook", AccountID: "329284282"}}}
|
||||
|
||||
Reference in new issue
Block a user