You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

81 lines
4.4 KiB

package memory
import (
"yunyan/comm"
"yunyan/modules"
"yunyan/lego/utils/mapstructure"
)
type Options struct {
modules.Options
// 周期报告
MaxReportProcess int `json:"max_report_process" mapstructure:"max_report_process"` //报告生成并发 worker 数,默认 3
ReportCronWeek string `json:"report_cron_week" mapstructure:"report_cron_week"` //周报 cron(秒级 6 位),默认每周一 00:30
ReportCronMonth string `json:"report_cron_month" mapstructure:"report_cron_month"` //月报 cron,默认每月 1 号 00:30
ReportMinItems int `json:"report_min_items" mapstructure:"report_min_items"` //上周期至少多少条记录才生成报告,默认 3
ReportPrompt string `json:"report_prompt" mapstructure:"report_prompt"` //报告播报文案的 system prompt
ReportStaleSec int64 `json:"report_stale_sec" mapstructure:"report_stale_sec"` //报告卡在 pending/processing 多久算死,默认 900s
// 会议纪要 → 待办抽取
MeetingExtract bool `json:"meeting_extract" mapstructure:"meeting_extract"` //是否开启会议待办抽取,默认 true
MeetingExtractPrompt string `json:"meeting_extract_prompt" mapstructure:"meeting_extract_prompt"` //抽取 prompt(代码内置默认值,不放 echomeet_template)
// 内容门槛:低于任一阈值的录音不抽待办(纪要照出,只是不进拾忆)。
// 6 秒的测试通话、20 秒的单人自述被抽成「继续进行进一步的功能测试」这类废话待办,
// 再靠条数凑够周报阈值又触发一次 LLM 调用——2026-09-18 测试库里 id=23/24/26 都是这么来的。
MeetingExtractMinSeconds int32 `json:"meeting_extract_min_seconds" mapstructure:"meeting_extract_min_seconds"` //短于多少秒不抽取,默认 60;<=0 表示不限
MeetingExtractMinChars int `json:"meeting_extract_min_chars" mapstructure:"meeting_extract_min_chars"` //转写正文少于多少字不抽取,默认 120;<=0 表示不限
}
func (this *Options) LoadConfig(settings map[string]interface{}) (err error) {
// 布尔项的默认值必须在 Decode 之前给,否则配置里没写这一项时会被零值覆盖成 false
this.MeetingExtract = true
if settings != nil {
if err = this.Options.LoadConfig(settings); err != nil {
return
}
if err = mapstructure.Decode(settings, this); err != nil {
return
}
}
if this.MaxReportProcess <= 0 {
this.MaxReportProcess = 3
}
if this.ReportCronWeek == "" {
// 秒 分 时 日 月 周:每周一 00:30:00
// ⚠️ 这是容器本地时区(Asia/Shanghai,Dockerfile 与 compose 都设了 TZ),
// 对所有区域所有用户都是北京时间。海外用户的「上周」边界会偏,见设计文档 §5.3。
this.ReportCronWeek = "0 30 0 ? * MON"
}
if this.ReportCronMonth == "" {
this.ReportCronMonth = "0 30 0 1 * ?"
}
if this.ReportMinItems <= 0 {
this.ReportMinItems = 3
}
if this.ReportStaleSec <= 0 {
this.ReportStaleSec = 900
}
// ⚠️ 这两个门槛允许配 0(= 不限),所以只在「配置里没写这一项」时才回默认值。
// mapstructure 解不出来时字段保持零值,与「运营显式填了 0」无法区分,
// 于是判据取「负数才算没配」——想关掉门槛就填 0,想用默认就别写这两行。
if this.MeetingExtractMinSeconds < 0 {
this.MeetingExtractMinSeconds = 0
} else if _, ok := settings["meeting_extract_min_seconds"]; !ok {
this.MeetingExtractMinSeconds = comm.MeetingMinSeconds
}
if this.MeetingExtractMinChars < 0 {
this.MeetingExtractMinChars = 0
} else if _, ok := settings["meeting_extract_min_chars"]; !ok {
this.MeetingExtractMinChars = 120
}
if this.ReportPrompt == "" {
this.ReportPrompt = "你是一位贴心的生活助理。用户会给你一段 JSON 格式的周期统计数据(已由程序精确算出)。" +
"请把它组织成一段适合语音朗读的自然中文短文,控制在 150 字以内。要求:" +
"1) 直接说结论,不要复述字段名,不要出现 JSON、字段、数据这类词;" +
"2) 数字必须原样引用,一个都不能改、不能四舍五入、不能自己做加减;" +
"3) 依次覆盖:完成情况、未完成的事、花销、灵感;某一项数据为空就跳过不提;" +
"4) 语气平实友好,不要用感叹号堆砌,不要说教;" +
"5) 只输出这段话本身,不要标题、不要分点、不要任何解释。"
}
return
}