Support Gradio 6 Chatbot format and multi-output spaces like tdecae-personal-chatbot
This commit is contained in:
@@ -73,14 +73,14 @@ type ChatMessage struct {
|
|||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ChatMessage) GetContentString() string {
|
func extractContentString(val interface{}) string {
|
||||||
if m.Content == nil {
|
if val == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
if str, ok := m.Content.(string); ok {
|
if str, ok := val.(string); ok {
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
if parts, ok := m.Content.([]interface{}); ok {
|
if parts, ok := val.([]interface{}); ok {
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
for _, p := range parts {
|
for _, p := range parts {
|
||||||
if str, ok := p.(string); ok {
|
if str, ok := p.(string); ok {
|
||||||
@@ -88,16 +88,29 @@ func (m *ChatMessage) GetContentString() string {
|
|||||||
} else if itemMap, ok := p.(map[string]interface{}); ok {
|
} else if itemMap, ok := p.(map[string]interface{}); ok {
|
||||||
if textVal, ok := itemMap["text"].(string); ok {
|
if textVal, ok := itemMap["text"].(string); ok {
|
||||||
sb.WriteString(textVal)
|
sb.WriteString(textVal)
|
||||||
|
} else if valStr, ok := itemMap["value"].(string); ok {
|
||||||
|
sb.WriteString(valStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sb.String()
|
return sb.String()
|
||||||
}
|
}
|
||||||
b, err := json.Marshal(m.Content)
|
if itemMap, ok := val.(map[string]interface{}); ok {
|
||||||
|
if textVal, ok := itemMap["text"].(string); ok {
|
||||||
|
return textVal
|
||||||
|
} else if valStr, ok := itemMap["value"].(string); ok {
|
||||||
|
return valStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(val)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%v", m.Content)
|
return fmt.Sprintf("%v", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ChatMessage) GetContentString() string {
|
||||||
|
return extractContentString(m.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChatCompletionRequest struct {
|
type ChatCompletionRequest struct {
|
||||||
@@ -1520,6 +1533,8 @@ type GradioParamInfo struct {
|
|||||||
ParameterName string `json:"parameter_name"`
|
ParameterName string `json:"parameter_name"`
|
||||||
ParameterDefault interface{} `json:"parameter_default,omitempty"`
|
ParameterDefault interface{} `json:"parameter_default,omitempty"`
|
||||||
Component string `json:"component"`
|
Component string `json:"component"`
|
||||||
|
Type interface{} `json:"type,omitempty"`
|
||||||
|
PythonType interface{} `json:"python_type,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GradioEndpointInfo struct {
|
type GradioEndpointInfo struct {
|
||||||
@@ -1828,20 +1843,32 @@ func InspectSpace(client *http.Client, rawURL, userAgent string) (*SpaceDiscover
|
|||||||
score := 0
|
score := 0
|
||||||
lowerName := strings.ToLower(epName)
|
lowerName := strings.ToLower(epName)
|
||||||
|
|
||||||
if strings.Contains(lowerName, "chat") {
|
// Penalize non-generation/reset/clear/init endpoints or 0-parameter endpoints
|
||||||
|
if len(epInfo.Parameters) == 0 {
|
||||||
|
score -= 500
|
||||||
|
}
|
||||||
|
if strings.Contains(lowerName, "clear") || strings.Contains(lowerName, "reset") || strings.Contains(lowerName, "init") || strings.Contains(lowerName, "undo") || strings.Contains(lowerName, "delete") {
|
||||||
|
score -= 500
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(lowerName, "chat") || strings.Contains(lowerName, "conversation") || strings.Contains(lowerName, "dialogue") {
|
||||||
score += 100
|
score += 100
|
||||||
}
|
}
|
||||||
if strings.Contains(lowerName, "predict") || strings.Contains(lowerName, "respond") || strings.Contains(lowerName, "generate") {
|
if strings.Contains(lowerName, "answer") || strings.Contains(lowerName, "respond") || strings.Contains(lowerName, "generate") || strings.Contains(lowerName, "predict") || strings.Contains(lowerName, "completion") {
|
||||||
score += 50
|
score += 60
|
||||||
|
}
|
||||||
|
if strings.Contains(lowerName, "ask") || strings.Contains(lowerName, "query") || strings.Contains(lowerName, "question") || strings.Contains(lowerName, "talk") {
|
||||||
|
score += 40
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range epInfo.Parameters {
|
for _, p := range epInfo.Parameters {
|
||||||
pLower := strings.ToLower(p.ParameterName)
|
pLower := strings.ToLower(p.ParameterName)
|
||||||
if strings.Contains(pLower, "message") || strings.Contains(pLower, "text") || strings.Contains(pLower, "prompt") {
|
pComp := strings.ToLower(p.Component)
|
||||||
|
if strings.Contains(pLower, "message") || strings.Contains(pLower, "text") || strings.Contains(pLower, "prompt") || strings.Contains(pLower, "query") || strings.Contains(pLower, "question") || strings.Contains(pLower, "input") || pComp == "textbox" {
|
||||||
score += 40
|
score += 40
|
||||||
}
|
}
|
||||||
if strings.Contains(pLower, "history") || strings.Contains(pLower, "chat") {
|
if strings.Contains(pLower, "history") || strings.Contains(pLower, "chat") || strings.Contains(pLower, "messages") || strings.Contains(pLower, "conversation") || pComp == "chatbot" {
|
||||||
score += 20
|
score += 30
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1943,6 +1970,7 @@ func InspectSpace(client *http.Client, rawURL, userAgent string) (*SpaceDiscover
|
|||||||
}
|
}
|
||||||
for idx, p := range bestEndpointInfo.Parameters {
|
for idx, p := range bestEndpointInfo.Parameters {
|
||||||
pName := strings.ToLower(p.ParameterName)
|
pName := strings.ToLower(p.ParameterName)
|
||||||
|
pComp := strings.ToLower(p.Component)
|
||||||
if strings.Contains(pName, "system") {
|
if strings.Contains(pName, "system") {
|
||||||
discovery.SystemIndex = idx
|
discovery.SystemIndex = idx
|
||||||
if p.ParameterDefault != nil && discovery.DefaultSystemPrompt == "" {
|
if p.ParameterDefault != nil && discovery.DefaultSystemPrompt == "" {
|
||||||
@@ -1950,9 +1978,20 @@ func InspectSpace(client *http.Client, rawURL, userAgent string) (*SpaceDiscover
|
|||||||
discovery.DefaultSystemPrompt = strings.TrimSpace(defStr)
|
discovery.DefaultSystemPrompt = strings.TrimSpace(defStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if strings.Contains(pName, "history") || strings.Contains(pName, "chat") {
|
} else if strings.Contains(pName, "history") || strings.Contains(pName, "chat") || strings.Contains(pName, "conversation") || strings.Contains(pName, "messages") || pComp == "chatbot" {
|
||||||
discovery.HistoryIndex = idx
|
discovery.HistoryIndex = idx
|
||||||
} else if strings.Contains(pName, "message") || (strings.Contains(pName, "prompt") && !strings.Contains(pName, "system")) || strings.Contains(pName, "text") {
|
bType, _ := json.Marshal(p.Type)
|
||||||
|
bPyType, _ := json.Marshal(p.PythonType)
|
||||||
|
pPyType := strings.ToLower(string(bPyType))
|
||||||
|
bTypeStr := strings.ToLower(string(bType))
|
||||||
|
if strings.Contains(pPyType, "list[tuple[") || strings.Contains(pPyType, "list[list[") || strings.Contains(bTypeStr, "tuple") {
|
||||||
|
discovery.HistoryFormat = "pairs"
|
||||||
|
} else if strings.Contains(pPyType, "textmessage") || strings.Contains(pPyType, "dict(text: str") || strings.Contains(bTypeStr, "textmessage") || strings.Contains(bTypeStr, "chatbotdatamessages") {
|
||||||
|
discovery.HistoryFormat = "gradio_messages"
|
||||||
|
} else if strings.HasPrefix(configResp.Version, "5.") || strings.HasPrefix(configResp.Version, "6.") {
|
||||||
|
discovery.HistoryFormat = "gradio_messages"
|
||||||
|
}
|
||||||
|
} else if strings.Contains(pName, "message") || (strings.Contains(pName, "prompt") && !strings.Contains(pName, "system")) || strings.Contains(pName, "text") || strings.Contains(pName, "query") || strings.Contains(pName, "question") || strings.Contains(pName, "input") || pComp == "textbox" {
|
||||||
discovery.MessageIndex = idx
|
discovery.MessageIndex = idx
|
||||||
} else if strings.Contains(pName, "think_level") || strings.Contains(pName, "thinking_level") {
|
} else if strings.Contains(pName, "think_level") || strings.Contains(pName, "thinking_level") {
|
||||||
discovery.ThinkLevelIndex = idx
|
discovery.ThinkLevelIndex = idx
|
||||||
@@ -1972,6 +2011,7 @@ func InspectSpace(client *http.Client, rawURL, userAgent string) (*SpaceDiscover
|
|||||||
|
|
||||||
if discovery.FunctionsJSONIndex != -1 || discovery.ThinkLevelIndex != -1 || strings.Contains(cleanURL, "hy3") || strings.Contains(cleanURL, "hunyuan") {
|
if discovery.FunctionsJSONIndex != -1 || discovery.ThinkLevelIndex != -1 || strings.Contains(cleanURL, "hy3") || strings.Contains(cleanURL, "hunyuan") {
|
||||||
discovery.IsHunyuan3 = true
|
discovery.IsHunyuan3 = true
|
||||||
|
discovery.HistoryFormat = "messages"
|
||||||
discovery.Models = append(discovery.Models, "hy3", "hunyuan3", "tencent/Hy3")
|
discovery.Models = append(discovery.Models, "hy3", "hunyuan3", "tencent/Hy3")
|
||||||
if discovery.PrimaryModel == "gradio-chat" || discovery.PrimaryModel == "" {
|
if discovery.PrimaryModel == "gradio-chat" || discovery.PrimaryModel == "" {
|
||||||
discovery.PrimaryModel = "hy3"
|
discovery.PrimaryModel = "hy3"
|
||||||
@@ -2301,6 +2341,26 @@ func (g *GradioGateway) BuildGradioPayload(disc *SpaceDiscovery, req ChatComplet
|
|||||||
pairs = append(pairs, []string{u, a})
|
pairs = append(pairs, []string{u, a})
|
||||||
}
|
}
|
||||||
data[disc.HistoryIndex] = pairs
|
data[disc.HistoryIndex] = pairs
|
||||||
|
} else if disc.HistoryFormat == "gradio_messages" {
|
||||||
|
var gMsgs []map[string]interface{}
|
||||||
|
for _, item := range historyArray {
|
||||||
|
role, _ := item["role"].(string)
|
||||||
|
cStr := ""
|
||||||
|
if s, ok := item["content"].(string); ok {
|
||||||
|
cStr = s
|
||||||
|
}
|
||||||
|
gMsg := map[string]interface{}{
|
||||||
|
"role": role,
|
||||||
|
"content": []map[string]string{
|
||||||
|
{"text": cStr, "type": "text"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
gMsgs = append(gMsgs, gMsg)
|
||||||
|
}
|
||||||
|
if gMsgs == nil {
|
||||||
|
gMsgs = []map[string]interface{}{}
|
||||||
|
}
|
||||||
|
data[disc.HistoryIndex] = gMsgs
|
||||||
} else {
|
} else {
|
||||||
data[disc.HistoryIndex] = historyArray
|
data[disc.HistoryIndex] = historyArray
|
||||||
}
|
}
|
||||||
@@ -2393,9 +2453,8 @@ func ParseGradioStreamOutput(rawJSON string) GradioOutputFrame {
|
|||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if v[0] is an inner slice (e.g. Hy3: [[content, reasoning, tool_calls, history]])
|
// 1. Check if v[0] is an inner slice with len >= 3 (e.g. Hy3: [[content, reasoning, tool_calls, history]])
|
||||||
if inner, ok := v[0].([]interface{}); ok {
|
if inner, ok := v[0].([]interface{}); ok && len(inner) >= 3 {
|
||||||
if len(inner) >= 3 {
|
|
||||||
s0, _ := inner[0].(string)
|
s0, _ := inner[0].(string)
|
||||||
s1, _ := inner[1].(string)
|
s1, _ := inner[1].(string)
|
||||||
frame.Content = s0
|
frame.Content = s0
|
||||||
@@ -2413,7 +2472,143 @@ func ParseGradioStreamOutput(rawJSON string) GradioOutputFrame {
|
|||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(inner) == 2 {
|
// 2. Check if any element of v is a Chatbot message list or Chatbot pair list
|
||||||
|
for _, elem := range v {
|
||||||
|
if msgList, ok := elem.([]interface{}); ok && len(msgList) > 0 {
|
||||||
|
allMaps := true
|
||||||
|
var maps []map[string]interface{}
|
||||||
|
for _, item := range msgList {
|
||||||
|
if m, ok := item.(map[string]interface{}); ok {
|
||||||
|
if _, hasRole := m["role"]; hasRole {
|
||||||
|
maps = append(maps, m)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allMaps = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if allMaps && len(maps) > 0 {
|
||||||
|
var targetMsg map[string]interface{}
|
||||||
|
for i := len(maps) - 1; i >= 0; i-- {
|
||||||
|
if r, _ := maps[i]["role"].(string); r == "assistant" {
|
||||||
|
targetMsg = maps[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if targetMsg == nil {
|
||||||
|
targetMsg = maps[len(maps)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
cText := extractContentString(targetMsg["content"])
|
||||||
|
frame.Content = cText
|
||||||
|
|
||||||
|
if r, ok := targetMsg["reasoning_content"].(string); ok {
|
||||||
|
frame.Reasoning = r
|
||||||
|
} else if meta, ok := targetMsg["metadata"].(map[string]interface{}); ok {
|
||||||
|
if logStr, ok := meta["log"].(string); ok && logStr != "" {
|
||||||
|
frame.Reasoning = logStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tcsRaw, ok := targetMsg["tool_calls"].([]interface{}); ok && len(tcsRaw) > 0 {
|
||||||
|
b, err := json.Marshal(tcsRaw)
|
||||||
|
if err == nil {
|
||||||
|
var tcs []ToolCall
|
||||||
|
if json.Unmarshal(b, &tcs) == nil {
|
||||||
|
frame.ToolCalls = tcs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(frame.ToolCalls) == 0 {
|
||||||
|
tcs, clean, has := DetectToolCalls(cText)
|
||||||
|
if has && len(tcs) > 0 {
|
||||||
|
frame.ToolCalls = tcs
|
||||||
|
frame.Content = clean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frame.OK = true
|
||||||
|
return frame
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if elements are pairs [user, assistant]
|
||||||
|
allPairs := true
|
||||||
|
var pairs [][]interface{}
|
||||||
|
for _, item := range msgList {
|
||||||
|
if p, ok := item.([]interface{}); ok && len(p) == 2 {
|
||||||
|
pairs = append(pairs, p)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
allPairs = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if allPairs && len(pairs) > 0 {
|
||||||
|
lastPair := pairs[len(pairs)-1]
|
||||||
|
cText := extractContentString(lastPair[1])
|
||||||
|
frame.Content = cText
|
||||||
|
tcs, clean, has := DetectToolCalls(cText)
|
||||||
|
if has && len(tcs) > 0 {
|
||||||
|
frame.ToolCalls = tcs
|
||||||
|
frame.Content = clean
|
||||||
|
}
|
||||||
|
frame.OK = true
|
||||||
|
return frame
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check if v itself is a list of message maps: [{"role": "assistant", ...}]
|
||||||
|
allMaps := true
|
||||||
|
var maps []map[string]interface{}
|
||||||
|
for _, item := range v {
|
||||||
|
if m, ok := item.(map[string]interface{}); ok {
|
||||||
|
if _, hasRole := m["role"]; hasRole {
|
||||||
|
maps = append(maps, m)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allMaps = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if allMaps && len(maps) > 0 {
|
||||||
|
var targetMsg map[string]interface{}
|
||||||
|
for i := len(maps) - 1; i >= 0; i-- {
|
||||||
|
if r, _ := maps[i]["role"].(string); r == "assistant" {
|
||||||
|
targetMsg = maps[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if targetMsg == nil {
|
||||||
|
targetMsg = maps[len(maps)-1]
|
||||||
|
}
|
||||||
|
cText := extractContentString(targetMsg["content"])
|
||||||
|
frame.Content = cText
|
||||||
|
if r, ok := targetMsg["reasoning_content"].(string); ok {
|
||||||
|
frame.Reasoning = r
|
||||||
|
}
|
||||||
|
if tcsRaw, ok := targetMsg["tool_calls"].([]interface{}); ok && len(tcsRaw) > 0 {
|
||||||
|
b, err := json.Marshal(tcsRaw)
|
||||||
|
if err == nil {
|
||||||
|
var tcs []ToolCall
|
||||||
|
if json.Unmarshal(b, &tcs) == nil {
|
||||||
|
frame.ToolCalls = tcs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(frame.ToolCalls) == 0 {
|
||||||
|
tcs, clean, has := DetectToolCalls(cText)
|
||||||
|
if has && len(tcs) > 0 {
|
||||||
|
frame.ToolCalls = tcs
|
||||||
|
frame.Content = clean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frame.OK = true
|
||||||
|
return frame
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Check if v[0] is an inner pair [content, reasoning]
|
||||||
|
if inner, ok := v[0].([]interface{}); ok && len(inner) == 2 {
|
||||||
s0, ok0 := inner[0].(string)
|
s0, ok0 := inner[0].(string)
|
||||||
s1, ok1 := inner[1].(string)
|
s1, ok1 := inner[1].(string)
|
||||||
if ok0 && ok1 {
|
if ok0 && ok1 {
|
||||||
@@ -2422,8 +2617,6 @@ func ParseGradioStreamOutput(rawJSON string) GradioOutputFrame {
|
|||||||
frame.OK = true
|
frame.OK = true
|
||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if inner is a chat pair: ["user msg", "assistant msg"]
|
|
||||||
if ok1 {
|
if ok1 {
|
||||||
frame.Content = s1
|
frame.Content = s1
|
||||||
frame.OK = true
|
frame.OK = true
|
||||||
@@ -2431,71 +2624,13 @@ func ParseGradioStreamOutput(rawJSON string) GradioOutputFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if inner is a list of chat message maps: [{"role":..., "content":...}, ...]
|
// 5. Check if v[0] is a non-empty string or single output
|
||||||
// or list of pairs: [["u", "a"], ...]
|
if s, ok := v[0].(string); ok && (s != "" || len(v) == 1) {
|
||||||
if len(inner) > 0 {
|
|
||||||
lastItem := inner[len(inner)-1]
|
|
||||||
if m, ok := lastItem.(map[string]interface{}); ok {
|
|
||||||
if c, ok := m["content"].(string); ok {
|
|
||||||
frame.Content = c
|
|
||||||
frame.OK = true
|
|
||||||
}
|
|
||||||
if r, ok := m["reasoning_content"].(string); ok {
|
|
||||||
frame.Reasoning = r
|
|
||||||
}
|
|
||||||
if tcsRaw, ok := m["tool_calls"].([]interface{}); ok && len(tcsRaw) > 0 {
|
|
||||||
b, err := json.Marshal(tcsRaw)
|
|
||||||
if err == nil {
|
|
||||||
var tcs []ToolCall
|
|
||||||
if err := json.Unmarshal(b, &tcs); err == nil {
|
|
||||||
frame.ToolCalls = tcs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if frame.OK {
|
|
||||||
return frame
|
|
||||||
}
|
|
||||||
} else if pair, ok := lastItem.([]interface{}); ok && len(pair) >= 2 {
|
|
||||||
if aStr, ok := pair[1].(string); ok {
|
|
||||||
frame.Content = aStr
|
|
||||||
frame.OK = true
|
|
||||||
return frame
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if v[0] is string (standard single output e.g. ["content", null])
|
|
||||||
if s, ok := v[0].(string); ok {
|
|
||||||
frame.Content = s
|
frame.Content = s
|
||||||
frame.OK = true
|
frame.OK = true
|
||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if v is a flat list of messages: [{"role": "assistant", ...}]
|
|
||||||
lastItem := v[len(v)-1]
|
|
||||||
if m, ok := lastItem.(map[string]interface{}); ok {
|
|
||||||
if c, ok := m["content"].(string); ok {
|
|
||||||
frame.Content = c
|
|
||||||
frame.OK = true
|
|
||||||
}
|
|
||||||
if r, ok := m["reasoning_content"].(string); ok {
|
|
||||||
frame.Reasoning = r
|
|
||||||
}
|
|
||||||
if tcsRaw, ok := m["tool_calls"].([]interface{}); ok && len(tcsRaw) > 0 {
|
|
||||||
b, err := json.Marshal(tcsRaw)
|
|
||||||
if err == nil {
|
|
||||||
var tcs []ToolCall
|
|
||||||
if err := json.Unmarshal(b, &tcs); err == nil {
|
|
||||||
frame.ToolCalls = tcs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if frame.OK {
|
|
||||||
return frame
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
for _, key := range []string{"text", "content", "response", "data", "value"} {
|
for _, key := range []string{"text", "content", "response", "data", "value"} {
|
||||||
if s, ok := v[key].(string); ok {
|
if s, ok := v[key].(string); ok {
|
||||||
|
|||||||
@@ -298,6 +298,13 @@ func TestParseGradioStreamOutput(t *testing.T) {
|
|||||||
if !frame7.OK || frame7.Content != "Mocked answer" || frame7.Reasoning != "Mocked reasoning" || len(frame7.ToolCalls) != 0 {
|
if !frame7.OK || frame7.Content != "Mocked answer" || frame7.Reasoning != "Mocked reasoning" || len(frame7.ToolCalls) != 0 {
|
||||||
t.Errorf("unexpected frame7: %+v", frame7)
|
t.Errorf("unexpected frame7: %+v", frame7)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 8. Gradio 6 Chatbot multi-output format with TextMessage list
|
||||||
|
g6Raw := `["", [{"role": "user", "content": [{"text": "weather in Tokyo?", "type": "text"}]}, {"role": "assistant", "content": [{"text": "<tool_call>\n{\"name\": \"get_weather\", \"arguments\": {\"city\": \"Tokyo\"}}\n</tool_call>", "type": "text"}]}]]`
|
||||||
|
frame8 := ParseGradioStreamOutput(g6Raw)
|
||||||
|
if !frame8.OK || len(frame8.ToolCalls) != 1 || frame8.ToolCalls[0].Function.Name != "get_weather" {
|
||||||
|
t.Errorf("unexpected frame8: %+v", frame8)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHunyuan3BuildPayload(t *testing.T) {
|
func TestHunyuan3BuildPayload(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user