-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchat_message.go
128 lines (104 loc) · 4.1 KB
/
chat_message.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package dify
import (
"bufio"
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
)
// chatMessageEndpoint - Endpoint for creating a chat message.
const chatMessageEndpoint = "/v1/chat-messages"
// ChatMessageRequest - Request body for creating a chat message.
type ChatMessageRequest struct {
Query string `json:"query"` // User input/question content.
Inputs map[string]interface{} `json:"inputs"` // Variables defined, contains multiple key/value pairs.
ResponseMode ResponseMode `json:"response_mode"` // Response mode, `streaming`(recommended) or `blocking`.
User string `json:"user"` // Identity of the end user.
Files []File `json:"files"` // Uploaded files.
ConversationID string `json:"conversation_id,omitempty"` // Conversation ID, optional.
AutoGenerateName *bool `json:"auto_generate_name,omitempty"` // Automatically generate titles, by default `true`.
}
// CreateChatMessage - Creates a chat message in blocking mode.
func (c *Client) CreateChatMessage(ctx context.Context, req ChatMessageRequest) (*ChatCompletionResponse, error) {
url := fmt.Sprintf("%s%s", c.config.BaseURL, chatMessageEndpoint)
req.ResponseMode = BlockingMode
body, err := json.Marshal(req)
if err != nil {
return nil, fmt.Errorf("failed to marshal request: %v", err)
}
request, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(body))
if err != nil {
return nil, fmt.Errorf("failed to create request: %v", err)
}
request.Header.Set("Authorization", "Bearer "+c.config.APIKey)
request.Header.Set("Content-Type", "application/json")
resp, err := c.client.Do(request)
if err != nil {
return nil, fmt.Errorf("failed to send request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
buf := &bytes.Buffer{}
_, err = buf.ReadFrom(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response body: %v", err)
}
return nil, fmt.Errorf("unexpected response status %d: %s", resp.StatusCode, buf.String())
}
var response ChatCompletionResponse
err = json.NewDecoder(resp.Body).Decode(&response)
if err != nil {
return nil, fmt.Errorf("failed to decode response: %v", err)
}
return &response, nil
}
// CreateChatMessageStream - Creates a chat message in streaming mode.
func (c *Client) CreateChatMessageStream(ctx context.Context, req ChatMessageRequest) (<-chan ChunkChatCompletionResponse, error) {
url := fmt.Sprintf("%s%s", c.config.BaseURL, chatMessageEndpoint)
req.ResponseMode = StreamingMode
body, err := json.Marshal(req)
if err != nil {
return nil, fmt.Errorf("failed to marshal request: %v", err)
}
request, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(body))
if err != nil {
return nil, fmt.Errorf("failed to create request: %v", err)
}
request.Header.Set("Authorization", "Bearer "+c.config.APIKey)
request.Header.Set("Content-Type", "application/json")
resp, err := c.client.Do(request)
if err != nil {
return nil, fmt.Errorf("failed to send request: %v", err)
}
if resp.StatusCode != http.StatusOK {
buf := &bytes.Buffer{}
_, err = buf.ReadFrom(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response body: %v", err)
}
return nil, fmt.Errorf("unexpected response status %d: %s", resp.StatusCode, buf.String())
}
stream := make(chan ChunkChatCompletionResponse)
go func() {
defer resp.Body.Close()
defer close(stream)
scanner := bufio.NewScanner(resp.Body)
for scanner.Scan() {
line := scanner.Bytes()
if bytes.HasPrefix(line, []byte("data: ")) {
data := bytes.TrimPrefix(line, []byte("data: "))
var chunk ChunkChatCompletionResponse
if err := json.Unmarshal(data, &chunk); err != nil {
fmt.Printf("failed to unmarshal chunk: %v\n", err)
return
}
stream <- chunk
}
}
if err := scanner.Err(); err != nil {
fmt.Printf("error reading response body: %v\n", err)
}
}()
return stream, nil
}