-
Notifications
You must be signed in to change notification settings - Fork 19
/
service.go
66 lines (55 loc) · 2.21 KB
/
service.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
package luis
import (
"net/http"
"sort"
"github.com/nyaruka/gocommon/httpx"
"github.com/nyaruka/gocommon/stringsx"
"github.com/nyaruka/goflow/envs"
"github.com/nyaruka/goflow/flows"
)
// a classification service implementation for a LUIS app
type service struct {
client *Client
classifier *flows.Classifier
redactor stringsx.Redactor
}
// NewService creates a new classification service
func NewService(httpClient *http.Client, httpRetries *httpx.RetryConfig, httpAccess *httpx.AccessConfig, classifier *flows.Classifier, endpoint, appID, key, slot string) flows.ClassificationService {
return &service{
client: NewClient(httpClient, httpRetries, httpAccess, endpoint, appID, key, slot),
classifier: classifier,
redactor: stringsx.NewRedactor(flows.RedactionMask, key),
}
}
func (s *service) Classify(env envs.Environment, input string, logHTTP flows.HTTPLogCallback) (*flows.Classification, error) {
response, trace, err := s.client.Predict(input)
if trace != nil {
logHTTP(flows.NewHTTPLog(trace, flows.HTTPStatusFromCode, s.redactor))
}
if err != nil {
return nil, err
}
result := &flows.Classification{
Intents: make([]flows.ExtractedIntent, 0, len(response.Prediction.Intents)),
Entities: make(map[string][]flows.ExtractedEntity, len(response.Prediction.Entities.Values)),
}
for name, intent := range response.Prediction.Intents {
result.Intents = append(result.Intents, flows.ExtractedIntent{Name: name, Confidence: intent.Score})
}
sort.SliceStable(result.Intents, func(i, j int) bool { return result.Intents[i].Confidence.GreaterThan(result.Intents[j].Confidence) })
for name, matches := range response.Prediction.Entities.Instance {
var entities []flows.ExtractedEntity
for _, match := range matches {
entities = append(entities, flows.ExtractedEntity{Value: match.Text, Confidence: match.Score})
}
result.Entities[name] = entities
}
// if sentiment analysis was included, convert to an entity
if response.Prediction.Sentiment != nil {
result.Entities["sentiment"] = []flows.ExtractedEntity{
{Value: response.Prediction.Sentiment.Label, Confidence: response.Prediction.Sentiment.Score},
}
}
return result, nil
}
var _ flows.ClassificationService = (*service)(nil)