feat(urgency): 通用紧急度通道(Declarer/Level + 只抬不压折算)+ IoT 首个生产者 + 她自己的结论走结构化标记穿透安静时段
This commit is contained in:
1 parent
4a2d276881
commit
f91a83ff81
14 files changed
+917
-15
No files matched your search
@@ -4,6 +4,8 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/urgency"
|
||||
)
|
||||
|
||||
// 自主思考被引导(context.go 的 guidancePrompt)以如下紧凑、
|
||||
@@ -12,6 +14,7 @@ import (
|
||||
//
|
||||
// [我决定:push] (或 no_push)
|
||||
// [渠道:web|im|kook|telegram|...|auto]
|
||||
// [紧急:routine|warning|critical] (可省略;见 parseProactiveUrgency)
|
||||
// <温暖的正文内容>
|
||||
//
|
||||
// 这些标记按纯文本解析,因此模型稍有不同地
|
||||
@@ -25,6 +28,9 @@ var (
|
||||
decideMarker = regexp.MustCompile(`(?i)\[\s*我决定\s*[::]\s*(no_push|push)\s*\]`)
|
||||
// channelMarker 匹配决策行上的目标渠道词。
|
||||
channelMarker = regexp.MustCompile(`(?i)\[\s*渠道\s*[::]\s*([a-z0-9_\-]+)\s*\]`)
|
||||
// urgencyMarker 匹配她自报的紧急度档位词。它是**结构化**通道:只认固定枚举,
|
||||
// 绝不从散文里解读意图(项目红线);解析严格(必须带括号)=失败安全。
|
||||
urgencyMarker = regexp.MustCompile(`(?i)\[\s*紧急\s*[::]\s*(routine|warning|critical)\s*\]`)
|
||||
// decidePrefixes 是「尝试了决策但无法解析」的标记形状,
|
||||
// 这类轮次被视为含糊(失败安全)。它
|
||||
// 刻意只含带括号形式,因此仅仅在散文中出现
|
||||
@@ -36,8 +42,14 @@ var (
|
||||
// 与全角括号形式处理,因此格式良好的决策永不泄漏。
|
||||
stripDecideRe = regexp.MustCompile(`(?i)[【\[]\s*我决定\s*[::]\s*(no_push|push)\s*[】\]]`)
|
||||
stripChannelRe = regexp.MustCompile(`(?i)[【\[]\s*渠道\s*[::]\s*[a-z0-9_\-]+\s*[】\]]`)
|
||||
// stripUrgencyRe 删掉带括号的紧急度标记,档位值不限枚举:她写成枚举外的词时
|
||||
// 解析侧不上抬(保守),面向用户的正文里也绝不能留着这段内部标记。
|
||||
stripUrgencyRe = regexp.MustCompile(`(?i)[【\[]\s*紧急\s*[::]\s*[^】\]\s]+\s*[】\]]`)
|
||||
bareDecideRe = regexp.MustCompile(`(?i)我决定\s*[::]\s*(no_push|push)`)
|
||||
bareChannelRe = regexp.MustCompile(`(?i)渠道\s*[::]\s*[a-z0-9_\-]+`)
|
||||
// bareUrgencyRe 只认枚举档位:散文里「紧急:」这类词很常见,
|
||||
// 不该因为恰好紧跟一个英文词就被删掉。
|
||||
bareUrgencyRe = regexp.MustCompile(`(?i)紧急\s*[::]\s*(routine|warning|critical)`)
|
||||
)
|
||||
|
||||
// nonePhrases 是没有标记时表示「无可汇报」的结论。
|
||||
@@ -61,6 +73,8 @@ var nonePhrases = []string{
|
||||
// P2 之前的默认一致。
|
||||
// - 渠道提示是 [渠道:...] 词,转小写;为空/auto 则保持
|
||||
// 默认的活跃客户端优先、IM 降级路由。
|
||||
// - 她自报的紧急度由 parseProactiveUrgency 单独恢复(固定枚举的
|
||||
// 结构化标记,绝不从散文解读)。
|
||||
// - 决策为推送但正文为空或仍读作「无」 → 不推送
|
||||
// (失败安全),因此单独一个标记绝不会推出空消息。
|
||||
func parseProactive(conclusion string) (message, channelHint string, push bool) {
|
||||
@@ -83,6 +97,28 @@ func parseProactive(conclusion string) (message, channelHint string, push bool)
|
||||
return message, channelHint, push
|
||||
}
|
||||
|
||||
// parseProactiveUrgency 从结论的结构化尾段恢复她自报的紧急度 —— 这是通用紧急度通道
|
||||
// 的一种生产者形式(「她自己」):主动思考轮可以读外围插件数据、调工具,因此她要能
|
||||
// 声明「我认为这条紧急、要突破安静时段发出去」。
|
||||
//
|
||||
// 它只认固定枚举 [紧急:routine|warning|critical],绝不从散文/自由文本里解读意图
|
||||
// (项目红线:判断要结构化)。没写、格式错乱或写了枚举外的档位一律得到零值
|
||||
// LevelRoutine(即不上抬)—— 保守默认优于猜测,误判只可能少打扰、不会多打扰。
|
||||
func parseProactiveUrgency(conclusion string) urgency.Level {
|
||||
m := urgencyMarker.FindStringSubmatch(conclusion)
|
||||
if m == nil {
|
||||
return urgency.LevelRoutine
|
||||
}
|
||||
switch strings.ToLower(m[1]) {
|
||||
case "critical":
|
||||
return urgency.LevelCritical
|
||||
case "warning":
|
||||
return urgency.LevelWarning
|
||||
default:
|
||||
return urgency.LevelRoutine
|
||||
}
|
||||
}
|
||||
|
||||
// matchDecide 返回匹配到的决策词(已转小写)以及
|
||||
// 是否存在格式良好的决策标记。
|
||||
func matchDecide(text string) (string, bool) {
|
||||
@@ -118,10 +154,10 @@ func matchChannel(text string) string {
|
||||
return strings.ToLower(m[1])
|
||||
}
|
||||
|
||||
// stripInternalMarkers 移除结构化的决策/渠道标记,因此
|
||||
// stripInternalMarkers 移除结构化的决策/渠道/紧急度标记,因此
|
||||
// 主动消息正文绝不会把它们带给用户。它处理预期的
|
||||
// 带括号形式([我决定:push][渠道:kook])以及模型可能发出的漂移形式——
|
||||
// 裸的 "我决定:push" / "渠道:kook"(无括号)与全角 【我决定:push】——然后
|
||||
// 带括号形式([我决定:push][渠道:kook][紧急:critical])以及模型可能发出的漂移形式——
|
||||
// 裸的 "我决定:push" / "渠道:kook" / "紧急:critical"(无括号)与全角 【我决定:push】——然后
|
||||
// 丢弃因此变空的行并压缩剩余部分。它既在
|
||||
// parseProactive 内部应用(使消息与记录干净),又作为
|
||||
// buildProactiveMessage 里的最后一道守护,因此无论标记如何
|
||||
@@ -133,8 +169,10 @@ func stripInternalMarkers(text string) string {
|
||||
for _, ln := range lines {
|
||||
ln = stripDecideRe.ReplaceAllString(ln, "")
|
||||
ln = stripChannelRe.ReplaceAllString(ln, "")
|
||||
ln = stripUrgencyRe.ReplaceAllString(ln, "")
|
||||
ln = bareDecideRe.ReplaceAllString(ln, "")
|
||||
ln = bareChannelRe.ReplaceAllString(ln, "")
|
||||
ln = bareUrgencyRe.ReplaceAllString(ln, "")
|
||||
ln = strings.TrimSpace(ln)
|
||||
if ln == "" {
|
||||
continue
|
||||
|
||||
Reference in new issue
Block a user