-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdetails.go
104 lines (86 loc) · 2.34 KB
/
details.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package main
import (
"errors"
"fmt"
"io"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
func (s *server) GetDetail(req *GetDetailRequest, stream PlaceDetails_GetDetailServer) error {
place := req.GetPlace()
detail := req.GetDetail()
language := req.GetLanguage()
accessToken := req.GetToken()
var detailCreditPrice int32 = 1
var userId string
var detailPrompt string
switch detail {
case "features":
detailPrompt = fmt.Sprintf(`key features of %s, in .md format, in %s language, use mobile emoji`, place, language)
case "history":
detailPrompt = fmt.Sprintf(`history of %s, in .md format, in %s language, use mobile emoji`, place, language)
case "travelNotes":
detailPrompt = fmt.Sprintf(`things to know before visiting %s, in .md format, in %s language, use mobile emoji`, place, language)
default:
return status.Error(codes.Unimplemented, "Unsupported Detail")
}
if accessToken == "guest" {
err := s.limiter.LimitRequest(stream.Context())
if err != nil {
return err
}
} else {
id, err := CheckAccessToken(accessToken)
userId = id
if err != nil {
fmt.Print(err)
return status.Error(codes.Unauthenticated, err.Error())
}
user, err := GetUser(userId, s.db)
if err != nil {
fmt.Print(err)
return status.Error(codes.Internal, "Failed to check user balance")
}
if user.Balance < detailCreditPrice {
return status.Error(codes.ResourceExhausted, "Insufficient balance")
}
}
result, found := s.cacher.Get(detailPrompt)
if found {
responseObj := &GetDetailResponse{
Content: result,
}
stream.Send(responseObj)
ReduceBalance(userId, detailCreditPrice, s.db)
return nil
}
aiStream, err := getStreamChat(detailPrompt)
if err != nil {
return err
}
var message string
for {
response, err := aiStream.Recv()
if errors.Is(err, io.EOF) {
ReduceBalance(userId, detailCreditPrice, s.db)
s.cacher.Save(detailPrompt, message)
return nil
}
if err != nil {
fmt.Printf("\nStream error: %v\n", err)
return err
}
if len(response.Choices) < 1 {
return status.Error(codes.Internal, "There is an internal error")
}
content := response.Choices[0].Delta.Content
fmt.Print(content)
message = message + content
responseObj := &GetDetailResponse{
Content: message,
}
if err := stream.Send(responseObj); err != nil {
return err
}
}
}