feat(channels): 陌生人私聊正常聊天(跳概率门)+ 强制流控 6条/分与回合槽位 + 安静时段不再硬静默 + 受限车道边界行前置
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

- 陌生人私聊:不再走「值不值得回」的概率门,唯一闸门 = 每发送者 6 条/分滑窗 + 同会话 1 个在跑回合
- 被限流只登记不回,且留带 source 的可见告警(不静默)
- 安静时段在回复侧只作信号(规则层不再静默),群聊取消夜间静默
- 锁定流控常量:FlowDirectDefault 加字面量钉桩测试(放大它 = 静默关流控,且会让额度循环跑百万轮)
This commit is contained in:
AskaEth committed 2026-10-05 13:26:15 +08:00
1 parent c6f5c3fea0
commit 7ae4298871
10 files changed
+654 -118

No files matched your search

+32 -3
View File
@@ -22,7 +22,9 @@ import (
// 看到的历史逐条一致 —— 她不会像第一次见到主人(主人 2026-10-05 要求两条车道环境一致)。
// - **群聊 / 陌生人(受限车道)**:播种**该隔离会话自己**(`sess-*`)的最近转录,因此群里
// 前几句、以及被最小打扰静默掉而只登记不回的那几条(light.go 的 registerSilenced 已把它们
// 落进同一会话)都在她的上下文里,她据此才能理解一段连贯对话的意图。
// 落进同一会话)都在她的上下文里,她据此才能理解一段连贯对话的意图。**顺序为
// frame 先行**:来源行 + 第三方身份边界在最前、转录居中、当次消息在最后
// (主人 2026-10-05 裁定,见 seedTurnTranscript)。
//
// 两条车道读的会话不同,重建逻辑与条数上限却是同一份:internal/runtime/transcript
// (ContextCount / Read / Message)—— 与网关同一份实现、同一个常量,绝不另写第二套
@@ -51,6 +53,13 @@ func turnEnv(sess session.Session, target inboundTarget, personaID string) loop.
// - 主人私聊 → 主会话(`web`)的转录,与 Web 主会话逐条一致;
// - 群聊 / 陌生人 → 该隔离会话(`sess-*`)的转录,含被静默登记的群成员发言。
//
// **受限车道的顺序是「frame 先行」**(主人 2026-10-05 裁定):来源系统行 +
// 第三方身份边界必须排在**最前**,转录居中,当次用户消息在最后——即
// `[边界/来源系统行, …转录…, 当次用户消息]`。理由是提示词注入面:若把转录
// 前置在边界之前,群友的历史发言会先于「这是群、这些人是第三方」进入她的
// 上下文。主人私聊车道**顺序逐字不变**(转录最前、来源行、当次消息),因为
// 那条车道的上下文隔离本就不同。
//
// 时刻与网关一致:调用点在本回合用户消息落库**之前**(runInboundTurn 里装配先于
// persistToMain / persistIsolated),因此当次消息绝不会在上下文里出现两次。
//
@@ -69,7 +78,27 @@ func (b *Bridge) seedTurnTranscript(ctx context.Context, target inboundTarget, m
if len(seed) == 0 {
return msgs
}
out := make([]model.Message, 0, len(seed)+len(msgs))
// 主人私聊:转录前置在最前(既有顺序,逐字不变)。
if target.private {
out := make([]model.Message, 0, len(seed)+len(msgs))
out = append(out, seed...)
return append(out, msgs...)
}
return insertSeedAfterFrame(msgs, seed)
}
// insertSeedAfterFrame 把受限车道的转录插在**最前面的系统框架行之后**
// (来源行 + 第三方身份边界仍在最前,frame 先行),当次用户消息保持在最后:
// `[系统框架行, …转录…, 当次用户消息]`。受限车道的本回合消息恰好是
// 「框架系统行 + 当次用户消息」,因此这一插入位置等价于「边界最前、历史居中、
// 当次最后」,且**当次消息绝不重复**。
func insertSeedAfterFrame(msgs, seed []model.Message) []model.Message {
frame := 0
for frame < len(msgs) && msgs[frame].Role == model.RoleSystem {
frame++
}
out := make([]model.Message, 0, len(msgs)+len(seed))
out = append(out, msgs[:frame]...)
out = append(out, seed...)
return append(out, msgs...)
return append(out, msgs[frame:]...)
}