Enha: add openrouter parser
This commit is contained in:
@ -27,61 +27,6 @@ var (
|
||||
GuesserSimplePrompt = `we are playing game of alias;\n you were given a clue: \"%s\";\nplease return your guess and words that could be meant by the clue, but you do not wish to open yet, in json like:\n{\n\"guess\": \"most_relevant_word_to_the_clue\",\n\"could_be\": [\"this\", \"that\", ...]\n}\nhere is the words that left:\n%s`
|
||||
)
|
||||
|
||||
type DSResp struct {
|
||||
ID string `json:"id"`
|
||||
Choices []struct {
|
||||
Text string `json:"text"`
|
||||
Index int `json:"index"`
|
||||
FinishReason string `json:"finish_reason"`
|
||||
} `json:"choices"`
|
||||
Created int `json:"created"`
|
||||
Model string `json:"model"`
|
||||
SystemFingerprint string `json:"system_fingerprint"`
|
||||
Object string `json:"object"`
|
||||
}
|
||||
|
||||
type LLMResp struct {
|
||||
Index int `json:"index"`
|
||||
Content string `json:"content"`
|
||||
Tokens []any `json:"tokens"`
|
||||
IDSlot int `json:"id_slot"`
|
||||
Stop bool `json:"stop"`
|
||||
Model string `json:"model"`
|
||||
TokensPredicted int `json:"tokens_predicted"`
|
||||
TokensEvaluated int `json:"tokens_evaluated"`
|
||||
Prompt string `json:"prompt"`
|
||||
HasNewLine bool `json:"has_new_line"`
|
||||
Truncated bool `json:"truncated"`
|
||||
StopType string `json:"stop_type"`
|
||||
StoppingWord string `json:"stopping_word"`
|
||||
TokensCached int `json:"tokens_cached"`
|
||||
}
|
||||
|
||||
type MimeResp struct {
|
||||
Clue string `json:"clue"`
|
||||
Number string `json:"number"`
|
||||
Answer []string `json:"words_I_mean_my_team_to_open"`
|
||||
}
|
||||
|
||||
type GusserResp struct {
|
||||
Guesses []string `json:"guesses"`
|
||||
CouldBe []string `json:"could_be"`
|
||||
}
|
||||
|
||||
type Bot struct {
|
||||
Role string `json:"role"`
|
||||
Team string `json:"team"`
|
||||
cfg *config.Config `json:"-"`
|
||||
RoomID string `json:"room_id"` // can we get a room from here?
|
||||
BotName string `json:"bot_name"`
|
||||
log *slog.Logger `json:"-"`
|
||||
LLMParser RespParser `json:"-"`
|
||||
// channels for communicaton
|
||||
// channels are not serializable
|
||||
// SignalsCh chan bool
|
||||
// DoneCh chan bool
|
||||
}
|
||||
|
||||
func convertToSliceOfStrings(value any) ([]string, error) {
|
||||
switch v := value.(type) {
|
||||
case []string:
|
||||
@ -299,6 +244,8 @@ func NewBot(role, team, name, roomID string, cfg *config.Config, recovery bool)
|
||||
bot.LLMParser = NewLCPRespParser(bot.log)
|
||||
if strings.Contains(cfg.LLMConfig.URL, "api.deepseek.com") {
|
||||
bot.LLMParser = NewDeepSeekParser(bot.log)
|
||||
} else if strings.Contains(cfg.LLMConfig.URL, "openrouter.ai") {
|
||||
bot.LLMParser = NewOpenRouterParser(bot.log)
|
||||
}
|
||||
// add to room
|
||||
room, err := getRoomByID(bot.RoomID)
|
||||
|
86
llmapi/models.go
Normal file
86
llmapi/models.go
Normal file
@ -0,0 +1,86 @@
|
||||
package llmapi
|
||||
|
||||
import (
|
||||
"gralias/config"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
type OpenRouterResp struct {
|
||||
ID string `json:"id"`
|
||||
Provider string `json:"provider"`
|
||||
Model string `json:"model"`
|
||||
Object string `json:"object"`
|
||||
Created int `json:"created"`
|
||||
Choices []struct {
|
||||
Logprobs any `json:"logprobs"`
|
||||
FinishReason string `json:"finish_reason"`
|
||||
NativeFinishReason string `json:"native_finish_reason"`
|
||||
Index int `json:"index"`
|
||||
Message struct {
|
||||
Role string `json:"role"`
|
||||
Content string `json:"content"`
|
||||
Refusal any `json:"refusal"`
|
||||
Reasoning any `json:"reasoning"`
|
||||
} `json:"message"`
|
||||
} `json:"choices"`
|
||||
Usage struct {
|
||||
PromptTokens int `json:"prompt_tokens"`
|
||||
CompletionTokens int `json:"completion_tokens"`
|
||||
TotalTokens int `json:"total_tokens"`
|
||||
} `json:"usage"`
|
||||
}
|
||||
|
||||
type DSResp struct {
|
||||
ID string `json:"id"`
|
||||
Choices []struct {
|
||||
Text string `json:"text"`
|
||||
Index int `json:"index"`
|
||||
FinishReason string `json:"finish_reason"`
|
||||
} `json:"choices"`
|
||||
Created int `json:"created"`
|
||||
Model string `json:"model"`
|
||||
SystemFingerprint string `json:"system_fingerprint"`
|
||||
Object string `json:"object"`
|
||||
}
|
||||
|
||||
type LLMResp struct {
|
||||
Index int `json:"index"`
|
||||
Content string `json:"content"`
|
||||
Tokens []any `json:"tokens"`
|
||||
IDSlot int `json:"id_slot"`
|
||||
Stop bool `json:"stop"`
|
||||
Model string `json:"model"`
|
||||
TokensPredicted int `json:"tokens_predicted"`
|
||||
TokensEvaluated int `json:"tokens_evaluated"`
|
||||
Prompt string `json:"prompt"`
|
||||
HasNewLine bool `json:"has_new_line"`
|
||||
Truncated bool `json:"truncated"`
|
||||
StopType string `json:"stop_type"`
|
||||
StoppingWord string `json:"stopping_word"`
|
||||
TokensCached int `json:"tokens_cached"`
|
||||
}
|
||||
|
||||
type MimeResp struct {
|
||||
Clue string `json:"clue"`
|
||||
Number string `json:"number"`
|
||||
Answer []string `json:"words_I_mean_my_team_to_open"`
|
||||
}
|
||||
|
||||
type GusserResp struct {
|
||||
Guesses []string `json:"guesses"`
|
||||
CouldBe []string `json:"could_be"`
|
||||
}
|
||||
|
||||
type Bot struct {
|
||||
Role string `json:"role"`
|
||||
Team string `json:"team"`
|
||||
cfg *config.Config `json:"-"`
|
||||
RoomID string `json:"room_id"` // can we get a room from here?
|
||||
BotName string `json:"bot_name"`
|
||||
log *slog.Logger `json:"-"`
|
||||
LLMParser RespParser `json:"-"`
|
||||
// channels for communicaton
|
||||
// channels are not serializable
|
||||
// SignalsCh chan bool
|
||||
// DoneCh chan bool
|
||||
}
|
@ -88,3 +88,40 @@ func (p *lcpRespParser) ParseBytes(body []byte) (map[string]any, error) {
|
||||
}
|
||||
return respMap, nil
|
||||
}
|
||||
|
||||
type openRouterParser struct {
|
||||
log *slog.Logger
|
||||
}
|
||||
|
||||
func NewOpenRouterParser(log *slog.Logger) *openRouterParser {
|
||||
return &openRouterParser{log: log}
|
||||
}
|
||||
|
||||
func (p *openRouterParser) ParseBytes(body []byte) (map[string]any, error) {
|
||||
// parsing logic here
|
||||
resp := OpenRouterResp{}
|
||||
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
|
||||
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
|
||||
}
|
||||
|
Reference in New Issue
Block a user