mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-03 13:00:52 +08:00
75 lines
2.3 KiB
Go
75 lines
2.3 KiB
Go
package conversation
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// Message represents a minimal role-text pair used for hashing and comparison.
|
|
type Message struct {
|
|
Role string `json:"role"`
|
|
Text string `json:"text"`
|
|
}
|
|
|
|
// StoredMessage mirrors the persisted conversation message structure.
|
|
type StoredMessage struct {
|
|
Role string `json:"role"`
|
|
Content string `json:"content"`
|
|
Name string `json:"name,omitempty"`
|
|
}
|
|
|
|
// Sha256Hex computes SHA-256 hex digest for the specified string.
|
|
func Sha256Hex(s string) string {
|
|
sum := sha256.Sum256([]byte(s))
|
|
return hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
// ToStoredMessages converts in-memory messages into the persisted representation.
|
|
func ToStoredMessages(msgs []Message) []StoredMessage {
|
|
out := make([]StoredMessage, 0, len(msgs))
|
|
for _, m := range msgs {
|
|
out = append(out, StoredMessage{Role: m.Role, Content: m.Text})
|
|
}
|
|
return out
|
|
}
|
|
|
|
// StoredToMessages converts stored messages back into the in-memory representation.
|
|
func StoredToMessages(msgs []StoredMessage) []Message {
|
|
out := make([]Message, 0, len(msgs))
|
|
for _, m := range msgs {
|
|
out = append(out, Message{Role: m.Role, Text: m.Content})
|
|
}
|
|
return out
|
|
}
|
|
|
|
// hashMessage normalizes message data and returns a stable digest.
|
|
func hashMessage(m StoredMessage) string {
|
|
s := fmt.Sprintf(`{"content":%q,"role":%q}`, m.Content, strings.ToLower(m.Role))
|
|
return Sha256Hex(s)
|
|
}
|
|
|
|
// HashConversationWithPrefix computes a conversation hash using the provided prefix (client identifier) and model.
|
|
func HashConversationWithPrefix(prefix, model string, msgs []StoredMessage) string {
|
|
var b strings.Builder
|
|
b.WriteString(strings.ToLower(strings.TrimSpace(prefix)))
|
|
b.WriteString("|")
|
|
b.WriteString(strings.ToLower(strings.TrimSpace(model)))
|
|
for _, m := range msgs {
|
|
b.WriteString("|")
|
|
b.WriteString(hashMessage(m))
|
|
}
|
|
return Sha256Hex(b.String())
|
|
}
|
|
|
|
// HashConversationForAccount keeps compatibility with the per-account hash previously used.
|
|
func HashConversationForAccount(clientID, model string, msgs []StoredMessage) string {
|
|
return HashConversationWithPrefix(clientID, model, msgs)
|
|
}
|
|
|
|
// HashConversationGlobal produces a hash suitable for cross-account lookups.
|
|
func HashConversationGlobal(model string, msgs []StoredMessage) string {
|
|
return HashConversationWithPrefix("global", model, msgs)
|
|
}
|