新增: 自动升级体系 + WorkerW重建检测 + 知识卡片优化

自动升级:
- 版本变量注入 (-ldflags -X main.version)
- 远程 version.json 检查 + 弹窗提示(非强制右下角/强制居中)
- updater.exe 嵌入主程序, 运行时释放到临时目录
- 下载+SHA256校验+备份+替换+回滚 全流程
- 托盘菜单"检查更新"

稳定性:
- WorkerW 重建自动检测(每10s)并重新嵌入
- 左键托盘点击防抖
- 设置窗口已打开时正确前置

优化:
- 知识卡片prompt改为面向开发者的硬核内容
- 配置目录统一到 ~/.u-desktop/
- 设置窗口WebView2数据目录改为configDir下
This commit is contained in:
2026-05-28 19:06:26 +08:00
parent aee7997195
commit f5a473c4b8
23 changed files with 859 additions and 90 deletions

View File

@@ -17,7 +17,7 @@ import (
)
const cpaURL = "https://cpa.1216.top/v1/chat/completions"
const cpaModel = "glm-4.5-air"
const cpaModel = "glm-5.1"
const minKnowledgeRunes = 80
type knowledgeData struct {
@@ -100,17 +100,28 @@ func fetchKnowledgeFromLLM(keyword string, cfg *Config) string {
basePrompt := buildKnowledgePrompt(keyword, cfg.KnowledgePrompt)
messages := []map[string]string{
{
"role": "system",
"content": "你是严谨的中文知识卡片作者,输出必须具体、准确、有信息密度。不要写空泛鸡汤,不要只给一句定义。",
"role": "system",
"content": `你是一位资深技术专家,面向有多年经验的开发者撰写知识卡片。
内容标准:
- 必须包含可直接用于生产的硬核知识:底层原理、性能陷阱、边界条件、源码级细节
- 优先讲"为什么"而非"是什么"——机制、权衡、踩坑经验
- 用具体数值、代码片段(仅关键词级别)、或真实场景佐证
- 读者看完能立刻在项目中应用或避免踩坑
禁止:
- 入门级科普、"是什么"式定义、百科搬运
- 空泛鸡汤("很重要"、"提升效率"、"广泛应用"
- 标题、序号、Markdown标记、emoji`,
},
{"role": "user", "content": basePrompt},
}
body := map[string]interface{}{
"model": cpaModel,
"max_tokens": 512,
"temperature": 0.55,
"messages": messages,
"model": cpaModel,
"max_completion_tokens": 2048,
"temperature": 0.55,
"messages": messages,
}
content := requestKnowledgeCompletion(body)
content = normalizeKnowledgeContent(content)
@@ -137,13 +148,13 @@ func fetchKnowledgeFromLLM(keyword string, cfg *Config) string {
}
func buildKnowledgePrompt(keyword, customPrompt string) string {
basePrompt := fmt.Sprintf(`围绕关键词「%s」生成一条桌面知识卡片。
硬性要求:
1. 120-180个中文字符分成2-3句
2. 必须讲清一个具体机制、原理、权衡或实践经验;
3. 必须包含一个具体例子、场景或判断标准;
4. 避免“很重要、非常有用、提升效率”这类空泛表述;
5. 不要标题、号、Markdown、表情,直接输出正文。`, keyword)
basePrompt := fmt.Sprintf(`围绕「%s」写一条面向资深开发者的技术知识卡片。
要求:
- 100-160字2-3句连贯正文
- 必须触及底层机制、性能细节或生产踩坑经验
- 必须包含一个具体场景或数值佐证(如延迟数据、内存阈值、版本差异等)
- 直接输出正文,不要标题、号、Markdown`, keyword)
if customPrompt != "" {
basePrompt += "\n附加风格要求不能覆盖上面的字数和质量要求" + customPrompt
}
@@ -173,10 +184,16 @@ func requestKnowledgeCompletion(body map[string]interface{}) string {
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
log.Printf("知识API返回状态码: %d", resp.StatusCode)
return ""
}
var result struct {
Choices []struct {
Message struct {
Content string `json:"content"`
Content string `json:"content"`
ReasoningContent string `json:"reasoning_content"`
} `json:"message"`
} `json:"choices"`
}
@@ -185,7 +202,11 @@ func requestKnowledgeCompletion(body map[string]interface{}) string {
return ""
}
if len(result.Choices) > 0 {
return result.Choices[0].Message.Content
c := result.Choices[0].Message.Content
if c == "" {
c = result.Choices[0].Message.ReasoningContent
}
return c
}
return ""
}
@@ -256,6 +277,7 @@ func fetchAndPushKnowledge() {
}
if content == "" {
pushKnowledgeJSON("知识卡片加载失败,稍后重试", keyword)
return
}