feat(database): add repairSmokeAIAdviceIndexes function and corresponding tests
- Implemented repairSmokeAIAdviceIndexes to manage the unique index for fa_smoke_ai_advice. - Added unit tests for the new function to ensure correct index recreation and validation. - Updated AutoMigrate to include the new index repair function.
This commit is contained in:
@@ -154,7 +154,7 @@ func (s *SmokeAINextSmokeService) GetOrGenerate(ctx context.Context, user *userm
|
||||
}
|
||||
inputJSON, _ := json.Marshal(input)
|
||||
|
||||
output, outputJSON, modelName, tokensIn, tokensOut, err := s.callAI(ctx, input)
|
||||
output, outputJSON, modelName, tokensIn, tokensOut, err := s.callAI(ctx, int(user.ID), input)
|
||||
if err != nil {
|
||||
return AINextSmokeSuggestion{}, err
|
||||
}
|
||||
@@ -249,6 +249,14 @@ func (s *SmokeAINextSmokeService) GetOrGenerate(ctx context.Context, user *userm
|
||||
if err != nil {
|
||||
return AINextSmokeSuggestion{}, err
|
||||
}
|
||||
if len(nodes) > 0 {
|
||||
if firstNodeAt, err := parseFlexibleTime(nodes[0], planDate); err == nil {
|
||||
suggestedAt = firstNodeAt.In(time.Local)
|
||||
if suggestedAt.Before(notBeforeAt) {
|
||||
suggestedAt = notBeforeAt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if cachedAdvice != nil {
|
||||
if err := s.db.WithContext(ctx).
|
||||
@@ -612,7 +620,9 @@ func (s *SmokeAINextSmokeService) saveNodes(ctx context.Context, uid int, planDa
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SmokeAINextSmokeService) callAI(ctx context.Context, input aiNextSmokeInput) (aiNextSmokeOutput, []byte, string, *int, *int, error) {
|
||||
func (s *SmokeAINextSmokeService) callAI(ctx context.Context, uid int, input aiNextSmokeInput) (aiNextSmokeOutput, []byte, string, *int, *int, error) {
|
||||
requestModel := preferredSmokeAIModel(s.cfg.Model)
|
||||
|
||||
systemPrompt := strings.TrimSpace(`
|
||||
你是一名专业的戒烟教练与行为改变顾问。你将收到一段 JSON,包含:
|
||||
- 现在时间(as_of)
|
||||
@@ -638,9 +648,16 @@ func (s *SmokeAINextSmokeService) callAI(ctx context.Context, input aiNextSmokeI
|
||||
`)
|
||||
|
||||
userPrompt := fmt.Sprintf("输入(JSON):\n%s", mustJSON(input))
|
||||
appendSmokeAIDebugLog("next_smoke.request", map[string]interface{}{
|
||||
"uid": uid,
|
||||
"model": requestModel,
|
||||
"system_prompt": systemPrompt,
|
||||
"user_prompt": userPrompt,
|
||||
"input": input,
|
||||
})
|
||||
|
||||
reqBody := chatCompletionRequest{
|
||||
Model: s.cfg.Model,
|
||||
Model: requestModel,
|
||||
Messages: []chatMessage{
|
||||
{Role: "system", Content: systemPrompt},
|
||||
{Role: "user", Content: userPrompt},
|
||||
@@ -671,6 +688,12 @@ func (s *SmokeAINextSmokeService) callAI(ctx context.Context, input aiNextSmokeI
|
||||
if err != nil {
|
||||
return aiNextSmokeOutput{}, nil, "", nil, nil, fmt.Errorf("read ai response: %w", err)
|
||||
}
|
||||
appendSmokeAIDebugLog("next_smoke.response", map[string]interface{}{
|
||||
"uid": uid,
|
||||
"model": requestModel,
|
||||
"http_status": resp.StatusCode,
|
||||
"response_body": string(body),
|
||||
})
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return aiNextSmokeOutput{}, nil, "", nil, nil, fmt.Errorf("ai http %d: %s", resp.StatusCode, truncateString(string(body), 512))
|
||||
}
|
||||
@@ -700,7 +723,7 @@ func (s *SmokeAINextSmokeService) callAI(ctx context.Context, input aiNextSmokeI
|
||||
|
||||
modelName := parsed.Model
|
||||
if modelName == "" {
|
||||
modelName = s.cfg.Model
|
||||
modelName = requestModel
|
||||
}
|
||||
|
||||
var tokensIn, tokensOut *int
|
||||
|
||||
Reference in New Issue
Block a user