fix(sse): correct UTF-8 handling and chunking in SSE streaming\n\n- Updated splitContentIntoSegments to handle runes instead of bytes\n- Fixed buildWebUIStreamForwarder to send delta chunks instead of cumulative content\n- Ensures proper handling of multi-byte characters in SSE streams
This commit is contained in:
@@ -731,12 +731,16 @@ func (o *Orchestrator) runUnifiedReActStream(ctx context.Context, chatID, userID
|
||||
|
||||
// 推送思考过程事件
|
||||
if completion.Content != "" {
|
||||
if err := callback(StreamEvent{
|
||||
Type: StreamEventTypeThought,
|
||||
Content: completion.Content,
|
||||
Step: step,
|
||||
}); err != nil {
|
||||
return "", fmt.Errorf("callback error: %w", err)
|
||||
// 分割内容为逐步推送的片段
|
||||
segments := splitContentIntoSegments(completion.Content, 50) // 每段50字符
|
||||
for _, segment := range segments {
|
||||
if err := callback(StreamEvent{
|
||||
Type: StreamEventTypeThought,
|
||||
Content: segment,
|
||||
Step: step,
|
||||
}); err != nil {
|
||||
return "", fmt.Errorf("callback error: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1568,3 +1572,17 @@ func sanitizeUserFacingAnswer(raw string) string {
|
||||
}
|
||||
return strings.TrimSpace(strings.Join(cleaned, "\n"))
|
||||
}
|
||||
|
||||
// splitContentIntoSegments splits a string into smaller segments of the specified size (by rune count).
|
||||
func splitContentIntoSegments(content string, segmentSize int) []string {
|
||||
runes := []rune(content)
|
||||
var segments []string
|
||||
for start := 0; start < len(runes); start += segmentSize {
|
||||
end := start + segmentSize
|
||||
if end > len(runes) {
|
||||
end = len(runes)
|
||||
}
|
||||
segments = append(segments, string(runes[start:end]))
|
||||
}
|
||||
return segments
|
||||
}
|
||||
|
||||
@@ -48,8 +48,9 @@ type FeishuConfig struct {
|
||||
}
|
||||
|
||||
type WebUIConfig struct {
|
||||
ListenAddr string
|
||||
MaxUploadBytes int64
|
||||
ListenAddr string
|
||||
MaxUploadBytes int64
|
||||
ExposeReasoning bool
|
||||
}
|
||||
|
||||
type LLMConfig struct {
|
||||
@@ -110,8 +111,9 @@ func Load() (Config, error) {
|
||||
EventPath: defaultIfEmpty(os.Getenv("FEISHU_EVENT_PATH"), "/feishu/events"),
|
||||
},
|
||||
WebUI: WebUIConfig{
|
||||
ListenAddr: defaultIfEmpty(os.Getenv("WEBUI_LISTEN_ADDR"), ":8090"),
|
||||
MaxUploadBytes: int64(intFromEnv("WEBUI_MAX_UPLOAD_MB", 20)) * 1024 * 1024,
|
||||
ListenAddr: defaultIfEmpty(os.Getenv("WEBUI_LISTEN_ADDR"), ":8090"),
|
||||
MaxUploadBytes: int64(intFromEnv("WEBUI_MAX_UPLOAD_MB", 20)) * 1024 * 1024,
|
||||
ExposeReasoning: boolFromEnv("WEBUI_EXPOSE_REASONING", false),
|
||||
},
|
||||
LLM: LLMConfig{
|
||||
BaseURL: strings.TrimRight(defaultIfEmpty(os.Getenv("LLM_BASE_URL"), "https://api.openai.com/v1"), "/"),
|
||||
|
||||
Reference in New Issue
Block a user