feat: 提醒到期 → LLM生成自然提醒语 → 推送
- Gateway ReminderScheduler 到期时调用 ai-core /api/v1/internal/reminder-trigger - ai-core 用 LLM 生成温柔俏皮的提醒语,通过 messagePusher 推送 - Thinker 新增 TriggerReminderMessage 方法 - 环境变量: AI_CORE_URL (Gateway 已有) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -516,6 +516,60 @@ func main() {
|
||||
w.Write([]byte(`{"status":"ok"}`))
|
||||
})
|
||||
|
||||
// 提醒触发端点:Gateway 调度器在提醒到期时调用,由 LLM 生成自然提醒语推送
|
||||
mux.HandleFunc("/api/v1/internal/reminder-trigger", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
if r.Header.Get("X-Internal-Token") != os.Getenv("INTERNAL_SERVICE_TOKEN") {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
var req struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
UserID string `json:"user_id"`
|
||||
SessionID string `json:"session_id"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
// Generate a natural reminder via LLM.
|
||||
prompt := fmt.Sprintf(`【系统提醒】现在有一条提醒到时间了:
|
||||
标题:%s
|
||||
描述:%s
|
||||
|
||||
请用昔涟的口吻,用一句话自然地提醒开拓者。语气温柔俏皮,像朋友间的关心。
|
||||
只输出提醒语本身,不要加前缀或引号。`, req.Title, req.Description)
|
||||
|
||||
messages := []model.LLMMessage{
|
||||
{Role: model.RoleSystem, Content: "你是昔涟。用温柔俏皮的语气,一句话提醒开拓者。"},
|
||||
{Role: model.RoleUser, Content: prompt},
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second)
|
||||
defer cancel()
|
||||
resp, err := chatAdapter.Chat(ctx, messages)
|
||||
if err != nil {
|
||||
log.Printf("[reminder-trigger] LLM生成失败: %v", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
reminderMsg := strings.TrimSpace(resp.Content)
|
||||
if reminderMsg == "" {
|
||||
reminderMsg = fmt.Sprintf("开拓者~「%s」的提醒到时间啦♪", req.Title)
|
||||
}
|
||||
log.Printf("[reminder-trigger] 生成提醒语: %s", reminderMsg)
|
||||
|
||||
// Push through the message pusher if available.
|
||||
if thinker != nil {
|
||||
thinker.TriggerReminderMessage(req.UserID, req.SessionID, reminderMsg)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte(`{"status":"ok"}`))
|
||||
})
|
||||
|
||||
mux.HandleFunc("/api/v1/health", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte(`{"status":"ok","service":"ai-core","model":"` + chatAdapter.ModelName() + `"}`))
|
||||
|
||||
@@ -350,6 +350,26 @@ func (t *Thinker) UpdatePresence(online bool, sessionID string) {
|
||||
}
|
||||
}
|
||||
|
||||
// TriggerReminderMessage pushes a reminder message generated by LLM to the user.
|
||||
// Called by the internal reminder-trigger endpoint when a reminder fires.
|
||||
func (t *Thinker) TriggerReminderMessage(userID, sessionID, message string) {
|
||||
t.mu.Lock()
|
||||
pusher := t.messagePusher
|
||||
pushSessionID := sessionID
|
||||
if pushSessionID == "" {
|
||||
pushSessionID = t.activeSessionID
|
||||
}
|
||||
if pushSessionID == "" {
|
||||
pushSessionID = t.adminSessionID
|
||||
}
|
||||
t.mu.Unlock()
|
||||
|
||||
if pusher != nil && message != "" {
|
||||
log.Printf("[提醒推送] 推送LLM提醒: user=%s session=%s msg=%s", userID, pushSessionID, message)
|
||||
pusher(userID, pushSessionID, message)
|
||||
}
|
||||
}
|
||||
|
||||
// ThinkerConfig 后台思考配置
|
||||
type ThinkerConfig struct {
|
||||
Enabled bool
|
||||
|
||||
Reference in New Issue
Block a user