first commit
This commit is contained in:
72
core/schemas/useragents.go
Normal file
72
core/schemas/useragents.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package schemas
|
||||
|
||||
import "strings"
|
||||
|
||||
// UserAgentIdentifiers lists substrings that may appear in User-Agent for a given integration.
|
||||
// Versions of the same client may use different strings; Matches checks any of them.
|
||||
type UserAgentIdentifiers []string
|
||||
|
||||
var (
|
||||
// ClaudeCLI — Anthropic Claude Code / Claude CLI (identifiers vary by release).
|
||||
ClaudeCLI = UserAgentIdentifiers{"claude-cli", "claude-code", "claude-vscode"}
|
||||
GeminiCLI = UserAgentIdentifiers{"geminicli"}
|
||||
CodexCLI = UserAgentIdentifiers{"codex-tui"}
|
||||
QwenCodeCLI = UserAgentIdentifiers{"qwencode"}
|
||||
OpenCode = UserAgentIdentifiers{"opencode"}
|
||||
Cursor = UserAgentIdentifiers{"cursor"}
|
||||
)
|
||||
|
||||
// integrationUserAgents is the set of known client User-Agent patterns we persist on the context.
|
||||
var integrationUserAgents = []UserAgentIdentifiers{
|
||||
ClaudeCLI, GeminiCLI, CodexCLI, QwenCodeCLI, OpenCode, Cursor,
|
||||
}
|
||||
|
||||
// Matches reports whether userAgent contains any identifier (case-insensitive substring match).
|
||||
func (ids UserAgentIdentifiers) Matches(userAgent string) bool {
|
||||
if len(ids) == 0 || userAgent == "" {
|
||||
return false
|
||||
}
|
||||
ua := strings.ToLower(userAgent)
|
||||
for _, id := range ids {
|
||||
if id == "" {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(ua, strings.ToLower(id)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// String returns the first identifier for logging and tests that need a canonical sample value.
|
||||
func (ids UserAgentIdentifiers) String() string {
|
||||
if len(ids) == 0 {
|
||||
return ""
|
||||
}
|
||||
return ids[0]
|
||||
}
|
||||
|
||||
func ExtractAndSetUserAgentFromHeaders(headers map[string][]string, bifrostCtx *BifrostContext) {
|
||||
if len(headers) == 0 {
|
||||
return
|
||||
}
|
||||
if bifrostCtx == nil {
|
||||
return
|
||||
}
|
||||
var userAgent []string
|
||||
for key, value := range headers {
|
||||
if strings.EqualFold(key, "user-agent") {
|
||||
userAgent = value
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(userAgent) > 0 {
|
||||
ua := userAgent[0]
|
||||
for _, ids := range integrationUserAgents {
|
||||
if ids.Matches(ua) {
|
||||
bifrostCtx.SetValue(BifrostContextKeyUserAgent, ua)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user