Skip to content

Commit

Permalink
udpate go
Browse files Browse the repository at this point in the history
  • Loading branch information
userpj committed Nov 14, 2024
1 parent 2685548 commit a554bc2
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 20 deletions.
37 changes: 37 additions & 0 deletions go/appbuilder/app_builder_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,43 @@ func (t *AppBuilderClient) Run(conversationID string, query string, fileIDS []st
return &AppBuilderClientOnceIterator{body: resp.Body}, nil
}

func (t *AppBuilderClient) RunV2(req AppBuilderClientRunRequest) (AppBuilderClientIterator, error) {
if len(req.ConversationID) == 0 {
return nil, errors.New("conversationID mustn't be empty")
}

request := http.Request{}

serviceURL, err := t.sdkConfig.ServiceURLV2("/app/conversation/runs")
if err != nil {
return nil, err
}

header := t.sdkConfig.AuthHeaderV2()
request.URL = serviceURL
request.Method = "POST"
header.Set("Content-Type", "application/json")
request.Header = header
data, _ := json.Marshal(req)
request.Body = NopCloser(bytes.NewReader(data))
request.ContentLength = int64(len(data))

t.sdkConfig.BuildCurlCommand(&request)
resp, err := t.client.Do(&request)
if err != nil {
return nil, err
}
requestID, err := checkHTTPResponse(resp)
if err != nil {
return nil, fmt.Errorf("requestID=%s, err=%v", requestID, err)
}
r := NewSSEReader(1024*1024, bufio.NewReader(resp.Body))
if req.Stream {
return &AppBuilderClientStreamIterator{requestID: requestID, r: r, body: resp.Body}, nil
}
return &AppBuilderClientOnceIterator{body: resp.Body}, nil
}

func (t *AppBuilderClient) RunWithToolCall(req AppBuilderClientRunRequest) (AppBuilderClientIterator, error) {
if len(req.ConversationID) == 0 {
return nil, errors.New("conversationID mustn't be empty")
Expand Down
83 changes: 66 additions & 17 deletions go/appbuilder/app_builder_client_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,33 @@ import (
)

const (
CodeContentType = "code"
TextContentType = "text"
ImageContentType = "image"
RAGContentType = "rag"
FunctionCallContentType = "function_call"
AudioContentType = "audio"
VideoContentType = "video"
StatusContentType = "status"
CodeContentType = "code"
TextContentType = "text"
ImageContentType = "image"
RAGContentType = "rag"
FunctionCallContentType = "function_call"
AudioContentType = "audio"
VideoContentType = "video"
StatusContentType = "status"
ChatflowInterruptContentType = "chatflow_interrupt"
PublishMessageContentType = "publish_message"
)

const (
ChatflowEventType = "chatflow"
)

var TypeToStruct = map[string]reflect.Type{
CodeContentType: reflect.TypeOf(CodeDetail{}),
TextContentType: reflect.TypeOf(TextDetail{}),
ImageContentType: reflect.TypeOf(ImageDetail{}),
RAGContentType: reflect.TypeOf(RAGDetail{}),
FunctionCallContentType: reflect.TypeOf(FunctionCallDetail{}),
AudioContentType: reflect.TypeOf(AudioDetail{}),
VideoContentType: reflect.TypeOf(VideoDetail{}),
StatusContentType: reflect.TypeOf(StatusDetail{}),
CodeContentType: reflect.TypeOf(CodeDetail{}),
TextContentType: reflect.TypeOf(TextDetail{}),
ImageContentType: reflect.TypeOf(ImageDetail{}),
RAGContentType: reflect.TypeOf(RAGDetail{}),
FunctionCallContentType: reflect.TypeOf(FunctionCallDetail{}),
AudioContentType: reflect.TypeOf(AudioDetail{}),
VideoContentType: reflect.TypeOf(VideoDetail{}),
StatusContentType: reflect.TypeOf(StatusDetail{}),
ChatflowInterruptContentType: reflect.TypeOf(ChatflowInterruptDetail{}),
PublishMessageContentType: reflect.TypeOf(PublishMessageDetail{}),
}

type AppBuilderClientRunRequest struct {
Expand All @@ -53,6 +61,7 @@ type AppBuilderClientRunRequest struct {
Tools []Tool `json:"tools"`
ToolOutputs []ToolOutput `json:"tool_outputs"`
ToolChoice *ToolChoice `json:"tool_choice"`
Action *Action `json:"action"`
}

type Tool struct {
Expand Down Expand Up @@ -81,6 +90,36 @@ type ToolChoiceFunction struct {
Input map[string]interface{} `json:"input"`
}

type Action struct {
ActionType string `json:"action_type"`
Paramters *ActionParamters `json:"parameters"`
}

type ActionParamters struct {
InterruptEvent *ActionInterruptEvent `json:"interrupt_event"`
}

type ActionInterruptEvent struct {
ID string `json:"id"`
Type string `json:"type"`
}

func NewResumeAction(eventId string) *Action {
return NewAction("resume", eventId, "chat")
}

func NewAction(actionType string, eventId string, eventType string) *Action {
return &Action{
ActionType: actionType,
Paramters: &ActionParamters{
InterruptEvent: &ActionInterruptEvent{
ID: eventId,
Type: eventType,
},
},
}
}

type AgentBuilderRawResponse struct {
RequestID string `json:"request_id"`
Date string `json:"date"`
Expand Down Expand Up @@ -122,7 +161,7 @@ type Event struct {
EventType string
ContentType string
Usage Usage
Detail any // 将any替换为interface{}
Detail any
ToolCalls []ToolCall
}

Expand Down Expand Up @@ -185,6 +224,16 @@ type VideoDetail struct {

type StatusDetail struct{}

type ChatflowInterruptDetail struct {
InterruptEventID string `json:"interrupt_event_id"`
InterruptEventType string `json:"interrupt_event_type"`
}

type PublishMessageDetail struct {
Message string `json:"message"`
MessageID string `json:"message_id"`
}

type DefaultDetail struct {
URLS []string `json:"urls"`
Files []string `json:"files"`
Expand Down
102 changes: 101 additions & 1 deletion go/appbuilder/app_builder_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ func TestAppBuilderClientRunToolChoice(t *testing.T) {
input := make(map[string]any)
input["city"] = "北京"
end_user_id := "go_user_id_0"
i, err := client.RunWithToolCall(AppBuilderClientRunRequest{
i, err := client.RunV2(AppBuilderClientRunRequest{
ConversationID: conversationID,
AppID: appID,
Query: "你能干什么",
Expand Down Expand Up @@ -610,3 +610,103 @@ func TestAppBuilderClientRunToolChoice(t *testing.T) {
t.Logf("%s========== OK: %s ==========%s", "\033[32m", t.Name(), "\033[0m")
}
}

func TestAppBuilderClientRunChatflow(t *testing.T) {
var logBuffer bytes.Buffer

os.Setenv("APPBUILDER_LOGLEVEL", "DEBUG")

config, err := NewSDKConfig("", "")
if err != nil {
t.Logf("%s========== FAIL: %s ==========%s", "\033[31m", t.Name(), "\033[0m")
t.Fatalf("new http client config failed: %v", err)
}

appID := "4403205e-fb83-4fac-96d8-943bdb63796f"
client, err := NewAppBuilderClient(appID, config)
if err != nil {
t.Logf("%s========== FAIL: %s ==========%s", "\033[31m", t.Name(), "\033[0m")
t.Fatalf("new AgentBuidler instance failed")
}

conversationID, err := client.CreateConversation()
if err != nil {
t.Logf("%s========== FAIL: %s ==========%s", "\033[31m", t.Name(), "\033[0m")
t.Fatalf("create conversation failed: %v", err)
}

i, err := client.RunV2(AppBuilderClientRunRequest{
ConversationID: conversationID,
AppID: appID,
Query: "查天气",
Stream: true,
})

if err != nil {
t.Logf("%s========== FAIL: %s ==========%s", "\033[31m", t.Name(), "\033[0m")
t.Fatalf("run failed:%v", err)
}

var interruptId string
for answer, err := i.Next(); err == nil; answer, err = i.Next() {
for _, ev := range answer.Events {
if ev.ContentType == ChatflowInterruptContentType {
if ev.EventType != ChatflowEventType {
t.Logf("%s========== FAIL: %s ==========%s", "\033[31m", t.Name(), "\033[0m")
t.Fatalf("event type error:%v", err)
}

deatil := ev.Detail.(ChatflowInterruptDetail)
interruptId = deatil.InterruptEventID
break
}
}
}

if len(interruptId) == 0 {
t.Logf("%s========== FAIL: %s ==========%s", "\033[31m", t.Name(), "\033[0m")
t.Fatalf("interrupt id is empty")
}

i2, err := client.RunV2(AppBuilderClientRunRequest{
ConversationID: conversationID,
AppID: appID,
Query: "我先查个航班动态",
Stream: true,
Action: NewResumeAction(interruptId),
})
if err != nil {
t.Logf("%s========== FAIL: %s ==========%s", "\033[31m", t.Name(), "\033[0m")
t.Fatalf("run failed:%v", err)
}

var message string
for answer, err := i2.Next(); err == nil; answer, err = i2.Next() {
for _, ev := range answer.Events {
if ev.ContentType == PublishMessageContentType {
if ev.EventType != ChatflowEventType {
t.Logf("%s========== FAIL: %s ==========%s", "\033[31m", t.Name(), "\033[0m")
t.Fatalf("event type error:%v", err)
}

detail := ev.Detail.(PublishMessageDetail)
message = detail.Message
break
}
}
}
if len(message) == 0 {
t.Logf("%s========== FAIL: %s ==========%s", "\033[31m", t.Name(), "\033[0m")
t.Fatalf("message is empty")
}
fmt.Println(message)

// 如果测试失败,则输出缓冲区中的日志
if t.Failed() {
t.Logf("%s========== FAIL: %s ==========%s", "\033[31m", t.Name(), "\033[0m")
fmt.Println(logBuffer.String())
} else { // else 紧跟在右大括号后面
// 测试通过,打印文件名和测试函数名
t.Logf("%s========== OK: %s ==========%s", "\033[32m", t.Name(), "\033[0m")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,6 @@ public void AppBuilderClientRunChatflowTest() throws IOException, AppBuilderServ
for (Event event : result.getEvents()) {
System.out.println(event.getContentType());
if (event.getContentType().equals("chatflow_interrupt")) {
System.out.println("11111");
System.out.println(event.getDetail());
assertEquals(event.getEventType(), "chatflow");
interruptEventId = event.getDetail().get("interrupt_event_id").toString();
}
Expand Down

0 comments on commit a554bc2

Please sign in to comment.