62 lines
1.2 KiB
Go
62 lines
1.2 KiB
Go
package parser
|
|
|
|
import "encoding/json"
|
|
|
|
type StreamParser func(line string)
|
|
|
|
func CreateStreamParser(onText func(string), onDone func()) StreamParser {
|
|
accumulated := ""
|
|
done := false
|
|
|
|
return func(line string) {
|
|
if done {
|
|
return
|
|
}
|
|
|
|
var obj struct {
|
|
Type string `json:"type"`
|
|
Subtype string `json:"subtype"`
|
|
Message *struct {
|
|
Content []struct {
|
|
Type string `json:"type"`
|
|
Text string `json:"text"`
|
|
} `json:"content"`
|
|
} `json:"message"`
|
|
}
|
|
|
|
if err := json.Unmarshal([]byte(line), &obj); err != nil {
|
|
return
|
|
}
|
|
|
|
if obj.Type == "assistant" && obj.Message != nil {
|
|
text := ""
|
|
for _, p := range obj.Message.Content {
|
|
if p.Type == "text" && p.Text != "" {
|
|
text += p.Text
|
|
}
|
|
}
|
|
if text == "" {
|
|
return
|
|
}
|
|
if text == accumulated {
|
|
return
|
|
}
|
|
if len(accumulated) > 0 && len(text) > len(accumulated) && text[:len(accumulated)] == accumulated {
|
|
delta := text[len(accumulated):]
|
|
if delta != "" {
|
|
onText(delta)
|
|
}
|
|
accumulated = text
|
|
} else {
|
|
onText(text)
|
|
accumulated += text
|
|
}
|
|
}
|
|
|
|
if obj.Type == "result" && obj.Subtype == "success" {
|
|
done = true
|
|
onDone()
|
|
}
|
|
}
|
|
}
|