diff --git a/api/openai/chat.go b/api/openai/chat.go index 4028e3ce..a38e2bf3 100644 --- a/api/openai/chat.go +++ b/api/openai/chat.go @@ -12,6 +12,7 @@ import ( "github.com/go-skynet/LocalAI/api/options" "github.com/go-skynet/LocalAI/pkg/grammar" model "github.com/go-skynet/LocalAI/pkg/model" + "github.com/go-skynet/LocalAI/pkg/utils" "github.com/gofiber/fiber/v2" "github.com/rs/zerolog/log" "github.com/valyala/fasthttp" @@ -274,6 +275,8 @@ func ChatEndpoint(cm *config.ConfigLoader, o *options.Option) func(c *fiber.Ctx) if processFunctions { // As we have to change the result before processing, we can't stream the answer (yet?) ss := map[string]interface{}{} + // This prevent newlines to break JSON parsing for clients + s = utils.EscapeNewLines(s) json.Unmarshal([]byte(s), &ss) log.Debug().Msgf("Function return: %s %+v", s, ss) diff --git a/pkg/utils/json.go b/pkg/utils/json.go new file mode 100644 index 00000000..9b3c3deb --- /dev/null +++ b/pkg/utils/json.go @@ -0,0 +1,13 @@ +package utils + +import "regexp" + +var matchNewlines = regexp.MustCompile(`[\r\n]`) + +const doubleQuote = `"[^"\\]*(?:\\[\s\S][^"\\]*)*"` + +func EscapeNewLines(s string) string { + return regexp.MustCompile(doubleQuote).ReplaceAllStringFunc(s, func(s string) string { + return matchNewlines.ReplaceAllString(s, "\\n") + }) +}