package llmapi import ( "encoding/json" "errors" "fmt" "log/slog" "strings" ) type RespParser interface { ParseBytes(body []byte) (map[string]any, error) } // DeepSeekParser: deepseek implementation of RespParser type deepSeekParser struct { log *slog.Logger } func NewDeepSeekParser(log *slog.Logger) *deepSeekParser { return &deepSeekParser{log: log} } func (p *deepSeekParser) ParseBytes(body []byte) (map[string]any, error) { // parsing logic here dsResp := DSResp{} if err := json.Unmarshal(body, &dsResp); err != nil { p.log.Error("failed to unmarshall", "error", err) return nil, err } if len(dsResp.Choices) == 0 { p.log.Error("empty choices", "dsResp", dsResp) err := errors.New("empty choices in dsResp") return nil, err } text := dsResp.Choices[0].Text li := strings.Index(text, "{") ri := strings.LastIndex(text, "}") if li < 0 || ri < 1 { p.log.Error("not a json", "msg", text) err := fmt.Errorf("fn: ParseBytes, not a json; data: %s", text) return nil, err } sj := text[li : ri+1] respMap := make(map[string]any) if err := json.Unmarshal([]byte(sj), &respMap); err != nil { p.log.Error("failed to unmarshal response", "error", err, "string-json", sj) return nil, err } return respMap, nil } // llama.cpp implementation of RespParser type lcpRespParser struct { log *slog.Logger } func NewLCPRespParser(log *slog.Logger) *lcpRespParser { return &lcpRespParser{log: log} } func (p *lcpRespParser) ParseBytes(body []byte) (map[string]any, error) { // parsing logic here resp := LLMResp{} if err := json.Unmarshal(body, &resp); err != nil { p.log.Error("failed to unmarshal", "error", err) return nil, err } // if len(resp.Choices) == 0 { // p.log.Error("empty choices", "resp", resp) // err := errors.New("empty choices in resp") // return nil, err // } // text := resp.Choices[0].Message.Content text := resp.Content li := strings.Index(text, "{") ri := strings.LastIndex(text, "}") if li < 0 || ri < 1 { p.log.Error("not a json", "msg", text) err := fmt.Errorf("fn: ParseBytes, not a json; data: %s", text) return nil, err } sj := text[li : ri+1] respMap := make(map[string]any) if err := json.Unmarshal([]byte(sj), &respMap); err != nil { p.log.Error("failed to unmarshal response", "error", err, "string-json", sj) return nil, err } return respMap, nil }