Skip to content

Commit ffbec72

Browse files
authored
Merge pull request #37 from seymourtang/feat/convoai
feat: Implement Interrupt and GetHistory APIs for conversational AI service
2 parents f38cf3b + 9b9e042 commit ffbec72

File tree

11 files changed

+279
-171
lines changed

11 files changed

+279
-171
lines changed

examples/convoai/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ export CONVOAI_TTS_ELEVENLABS_VOICE_ID=<Your tts elevenLabs voice id>
6767
Run the sample project with the following command:
6868

6969
```bash
70-
go run main.go -ttsVendor=<ttsVendor> --serviceRegion=<serviceRegion>
70+
go run main.go --ttsVendor=<ttsVendor> --serviceRegion=<serviceRegion>
7171
```
7272

7373
`ttsVendor` represents different TTS providers. Choose the appropriate TTS provider based on your requirements.
7474
`serviceRegion` represents chosen service region. The currently supported service regions are:
75-
* `ChineseMainland`
76-
* `Global`
75+
* `1`:`ChineseMainland`
76+
* `2`:`Global`
7777

examples/convoai/README_ZH.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ export CONVOAI_TTS_ELEVENLABS_VOICE_ID=<Your tts elevenLabs voice id>
6767
使用以下命令运行示例项目:
6868

6969
```bash
70-
go run main.go -ttsVendor=<ttsVendor> --serviceRegion=<serviceRegion>
70+
go run main.go --ttsVendor=<ttsVendor> --serviceRegion=<serviceRegion>
7171
```
7272

7373
`ttsVendor` 代表不同的 TTS 提供商。根据您的需求选择合适的 TTS 提供商。
7474
`serviceRegion` 代表选择的服务区域。目前支持的服务区域有:
75-
* `ChineseMainland`
76-
* `Global`
75+
* `1`:`ChineseMainland`
76+
* `2`:`Global`
7777

examples/convoai/service/service.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,33 @@ func (s *Service) RunWithCustomTTS(ttsVendor req.TTSVendor, ttsParam req.TTSVend
170170
time.Sleep(time.Second * 3)
171171
}
172172

173+
interruptResp, err := convoaiClient.Interrupt(ctx, agentId)
174+
if err != nil {
175+
log.Fatalln(err)
176+
}
177+
178+
if interruptResp.IsSuccess() {
179+
log.Printf("Interrupt success:%+v", interruptResp)
180+
} else {
181+
log.Printf("Interrupt failed:%+v", interruptResp)
182+
return
183+
}
184+
time.Sleep(time.Second * 1)
185+
186+
historyResp, err := convoaiClient.GetHistory(ctx, agentId)
187+
if err != nil {
188+
log.Fatalln(err)
189+
}
190+
191+
if historyResp.IsSuccess() {
192+
log.Printf("History success:%+v", historyResp)
193+
} else {
194+
log.Printf("History failed:%+v", historyResp)
195+
return
196+
}
197+
198+
time.Sleep(time.Second * 1)
199+
173200
updateResp, err := convoaiClient.Update(ctx, agentId, &req.UpdateReqBody{
174201
Token: updateToken,
175202
})

services/convoai/api/history.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package api
2+
3+
import (
4+
"context"
5+
"errors"
6+
"net/http"
7+
8+
"github.com/AgoraIO-Community/agora-rest-client-go/agora"
9+
"github.com/AgoraIO-Community/agora-rest-client-go/agora/client"
10+
"github.com/AgoraIO-Community/agora-rest-client-go/agora/log"
11+
"github.com/AgoraIO-Community/agora-rest-client-go/services/convoai/resp"
12+
)
13+
14+
type History struct {
15+
baseHandler
16+
}
17+
18+
func NewHistory(module string, logger log.Logger, client client.Client, prefixPath string) *History {
19+
return &History{
20+
baseHandler: baseHandler{
21+
module: module,
22+
logger: logger,
23+
client: client,
24+
prefixPath: prefixPath,
25+
},
26+
}
27+
}
28+
29+
// buildPath returns the request path.
30+
// /api/conversational-ai-agent/v2/projects/{appid}/agents/{agentId}/history
31+
func (h *History) buildPath(agentId string) string {
32+
return h.prefixPath + "/agents/" + agentId + "/history"
33+
}
34+
35+
func (h *History) Do(ctx context.Context, agentId string) (*resp.HistoryResp, error) {
36+
path := h.buildPath(agentId)
37+
responseData, err := h.client.DoREST(ctx, path, http.MethodGet, nil)
38+
if err != nil {
39+
var internalErr *agora.InternalErr
40+
if !errors.As(err, &internalErr) {
41+
return nil, err
42+
}
43+
}
44+
45+
var historyResp resp.HistoryResp
46+
47+
historyResp.BaseResponse = responseData
48+
49+
if responseData.HttpStatusCode == http.StatusOK {
50+
var successResponse resp.HistorySuccessResp
51+
if err = responseData.UnmarshalToTarget(&successResponse); err != nil {
52+
return nil, err
53+
}
54+
historyResp.SuccessRes = successResponse
55+
} else {
56+
var errResponse resp.ErrResponse
57+
if err = responseData.UnmarshalToTarget(&errResponse); err != nil {
58+
return nil, err
59+
}
60+
historyResp.ErrResponse = errResponse
61+
}
62+
63+
return &historyResp, nil
64+
}

services/convoai/api/interrupt.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package api
2+
3+
import (
4+
"context"
5+
"errors"
6+
"net/http"
7+
8+
"github.com/AgoraIO-Community/agora-rest-client-go/agora"
9+
"github.com/AgoraIO-Community/agora-rest-client-go/agora/client"
10+
"github.com/AgoraIO-Community/agora-rest-client-go/agora/log"
11+
"github.com/AgoraIO-Community/agora-rest-client-go/services/convoai/resp"
12+
)
13+
14+
type Interrupt struct {
15+
baseHandler
16+
}
17+
18+
func NewInterrupt(module string, logger log.Logger, client client.Client, prefixPath string) *Interrupt {
19+
return &Interrupt{
20+
baseHandler: baseHandler{
21+
module: module,
22+
logger: logger,
23+
client: client,
24+
prefixPath: prefixPath,
25+
},
26+
}
27+
}
28+
29+
// buildPath returns the request path.
30+
//
31+
// /api/conversational-ai-agent/v2/projects/{appid}/agents/{agentId}/interrupt
32+
func (i *Interrupt) buildPath(agentId string) string {
33+
return i.prefixPath + "/agents/" + agentId + "/interrupt"
34+
}
35+
36+
func (i *Interrupt) Do(ctx context.Context, agentId string) (*resp.InterruptResp, error) {
37+
path := i.buildPath(agentId)
38+
responseData, err := i.client.DoREST(ctx, path, http.MethodPost, nil)
39+
if err != nil {
40+
var internalErr *agora.InternalErr
41+
if !errors.As(err, &internalErr) {
42+
return nil, err
43+
}
44+
}
45+
46+
var interruptResp resp.InterruptResp
47+
48+
interruptResp.BaseResponse = responseData
49+
50+
if responseData.HttpStatusCode == http.StatusOK {
51+
var successResponse resp.InterruptSuccessResp
52+
if err = responseData.UnmarshalToTarget(&successResponse); err != nil {
53+
return nil, err
54+
}
55+
interruptResp.SuccessRes = successResponse
56+
} else {
57+
var errResponse resp.ErrResponse
58+
if err = responseData.UnmarshalToTarget(&errResponse); err != nil {
59+
return nil, err
60+
}
61+
interruptResp.ErrResponse = errResponse
62+
}
63+
64+
return &interruptResp, nil
65+
}

services/convoai/api/leave.go

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,11 @@ package api
33
import (
44
"context"
55
"errors"
6-
"fmt"
76
"net/http"
8-
"time"
97

108
"github.com/AgoraIO-Community/agora-rest-client-go/agora"
119
"github.com/AgoraIO-Community/agora-rest-client-go/agora/client"
1210
"github.com/AgoraIO-Community/agora-rest-client-go/agora/log"
13-
"github.com/AgoraIO-Community/agora-rest-client-go/agora/retry"
1411
"github.com/AgoraIO-Community/agora-rest-client-go/services/convoai/resp"
1512
)
1613

@@ -38,7 +35,7 @@ func (d *Leave) buildPath(agentId string) string {
3835

3936
func (d *Leave) Do(ctx context.Context, agentId string) (*resp.LeaveResp, error) {
4037
path := d.buildPath(agentId)
41-
responseData, err := d.doRESTWithRetry(ctx, path, http.MethodPost, nil)
38+
responseData, err := d.client.DoREST(ctx, path, http.MethodPost, nil)
4239
if err != nil {
4340
var internalErr *agora.InternalErr
4441
if !errors.As(err, &internalErr) {
@@ -60,51 +57,3 @@ func (d *Leave) Do(ctx context.Context, agentId string) (*resp.LeaveResp, error)
6057

6158
return &response, nil
6259
}
63-
64-
const leaveRetryCount = 3
65-
66-
func (d *Leave) doRESTWithRetry(ctx context.Context, path string, method string, requestBody interface{}) (*agora.BaseResponse, error) {
67-
var (
68-
response *agora.BaseResponse
69-
err error
70-
retryCount int
71-
)
72-
73-
err = retry.Do(func(retryCount int) error {
74-
var doErr error
75-
76-
response, doErr = d.client.DoREST(ctx, path, method, requestBody)
77-
if doErr != nil {
78-
return agora.NewRetryErr(false, doErr)
79-
}
80-
81-
statusCode := response.HttpStatusCode
82-
switch {
83-
case statusCode == 200 || statusCode == 201:
84-
return nil
85-
case statusCode >= 400 && statusCode < 499:
86-
d.logger.Debugf(ctx, d.module, "http status code is %d, no retry,http response:%s", statusCode, response.RawBody)
87-
return agora.NewRetryErr(
88-
false,
89-
agora.NewInternalErr(fmt.Sprintf("http status code is %d, no retry,http response:%s", statusCode, response.RawBody)),
90-
)
91-
default:
92-
d.logger.Debugf(ctx, d.module, "http status code is %d, retry,http response:%s", statusCode, response.RawBody)
93-
return fmt.Errorf("http status code is %d, retry", response.RawBody)
94-
}
95-
}, func() bool {
96-
select {
97-
case <-ctx.Done():
98-
return true
99-
default:
100-
}
101-
return retryCount >= leaveRetryCount
102-
}, func(i int) time.Duration {
103-
return time.Second * time.Duration(i+1)
104-
}, func(err error) {
105-
d.logger.Debugf(ctx, d.module, "http request err:%s", err)
106-
retryCount++
107-
})
108-
109-
return response, err
110-
}

services/convoai/api/list.go

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ import (
66
"fmt"
77
"net/http"
88
"net/url"
9-
"time"
109

1110
"github.com/AgoraIO-Community/agora-rest-client-go/agora"
1211
"github.com/AgoraIO-Community/agora-rest-client-go/agora/client"
1312
"github.com/AgoraIO-Community/agora-rest-client-go/agora/log"
14-
"github.com/AgoraIO-Community/agora-rest-client-go/agora/retry"
1513
"github.com/AgoraIO-Community/agora-rest-client-go/services/convoai/req"
1614
"github.com/AgoraIO-Community/agora-rest-client-go/services/convoai/resp"
1715
)
@@ -86,7 +84,7 @@ func buildQueryFields(options ...req.ListOption) map[string]any {
8684
func (q *List) Do(ctx context.Context, options ...req.ListOption) (*resp.ListResp, error) {
8785
queryFields := buildQueryFields(options...)
8886
path := q.buildPath(queryFields)
89-
responseData, err := q.doRESTWithRetry(ctx, path, http.MethodGet, nil)
87+
responseData, err := q.client.DoREST(ctx, path, http.MethodGet, nil)
9088
if err != nil {
9189
var internalErr *agora.InternalErr
9290
if !errors.As(err, &internalErr) {
@@ -114,51 +112,3 @@ func (q *List) Do(ctx context.Context, options ...req.ListOption) (*resp.ListRes
114112

115113
return &listResp, nil
116114
}
117-
118-
const listRetryCount = 3
119-
120-
func (q *List) doRESTWithRetry(ctx context.Context, path string, method string, requestBody interface{}) (*agora.BaseResponse, error) {
121-
var (
122-
baseResponse *agora.BaseResponse
123-
err error
124-
retryCount int
125-
)
126-
127-
err = retry.Do(func(retryCount int) error {
128-
var doErr error
129-
130-
baseResponse, doErr = q.client.DoREST(ctx, path, method, requestBody)
131-
if doErr != nil {
132-
return agora.NewRetryErr(false, doErr)
133-
}
134-
135-
statusCode := baseResponse.HttpStatusCode
136-
switch {
137-
case statusCode == 200 || statusCode == 201:
138-
return nil
139-
case statusCode >= 400 && statusCode < 499:
140-
q.logger.Debugf(ctx, q.module, "http status code is %d, no retry,http response:%s", statusCode, baseResponse.RawBody)
141-
return agora.NewRetryErr(
142-
false,
143-
agora.NewInternalErr(fmt.Sprintf("http status code is %d, no retry,http response:%s", statusCode, baseResponse.RawBody)),
144-
)
145-
default:
146-
q.logger.Debugf(ctx, q.module, "http status code is %d, retry,http response:%s", statusCode, baseResponse.RawBody)
147-
return fmt.Errorf("http status code is %d, retry", baseResponse.RawBody)
148-
}
149-
}, func() bool {
150-
select {
151-
case <-ctx.Done():
152-
return true
153-
default:
154-
}
155-
return retryCount >= listRetryCount
156-
}, func(i int) time.Duration {
157-
return time.Second * time.Duration(i+1)
158-
}, func(err error) {
159-
q.logger.Debugf(ctx, q.module, "http request err:%s", err)
160-
retryCount++
161-
})
162-
163-
return baseResponse, err
164-
}

0 commit comments

Comments
 (0)