mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(coderd): fix isContextLimitKey false positive on max_context_version (#23950)
`isContextLimitKey` had a fallback heuristic that matched any key starting with `"max"` containing `"context"`, causing false positives on keys like `"max_context_version"`. A provider returning such metadata would have the value parsed as a context limit. Replace substring matching on the separator-stripped key with word-level matching. A new `metadataKeyWords` function tokenizes keys by splitting on separators and camelCase boundaries, then the fallback requires `"context"` paired with a limit-related word (`"limit"`, `"window"` + qualifier, `"length"` + qualifier, or `"tokens"` + qualifier). Known exact forms like `"context_window"` remain in the fast-path switch. Closes https://github.com/coder/coder/issues/23332
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"charm.land/fantasy"
|
||||
fantasyanthropic "charm.land/fantasy/providers/anthropic"
|
||||
@@ -1317,11 +1318,25 @@ func isContextLimitKey(key string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
return strings.Contains(normalized, "context") &&
|
||||
(strings.Contains(normalized, "limit") ||
|
||||
strings.Contains(normalized, "window") ||
|
||||
strings.Contains(normalized, "length") ||
|
||||
strings.HasPrefix(normalized, "max"))
|
||||
words := metadataKeyWords(key)
|
||||
if !slices.Contains(words, "context") {
|
||||
return false
|
||||
}
|
||||
|
||||
if slices.Contains(words, "limit") {
|
||||
return true
|
||||
}
|
||||
|
||||
if slices.Contains(words, "window") {
|
||||
return slices.Contains(words, "size") || slices.Contains(words, "max")
|
||||
}
|
||||
|
||||
if slices.Contains(words, "length") {
|
||||
return slices.Contains(words, "max")
|
||||
}
|
||||
|
||||
return (slices.Contains(words, "token") || slices.Contains(words, "tokens")) &&
|
||||
(slices.Contains(words, "max") || slices.Contains(words, "limit"))
|
||||
}
|
||||
|
||||
func normalizeMetadataKey(key string) string {
|
||||
@@ -1342,6 +1357,40 @@ func normalizeMetadataKey(key string) string {
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func metadataKeyWords(key string) []string {
|
||||
words := make([]string, 0, 4)
|
||||
var current strings.Builder
|
||||
|
||||
flush := func() {
|
||||
if current.Len() == 0 {
|
||||
return
|
||||
}
|
||||
words = append(words, current.String())
|
||||
current.Reset()
|
||||
}
|
||||
|
||||
var prev rune
|
||||
var hasPrev bool
|
||||
for _, r := range key {
|
||||
if !unicode.IsLetter(r) {
|
||||
flush()
|
||||
hasPrev = false
|
||||
continue
|
||||
}
|
||||
|
||||
if hasPrev && unicode.IsUpper(r) && unicode.IsLower(prev) {
|
||||
flush()
|
||||
}
|
||||
|
||||
_, _ = current.WriteRune(unicode.ToLower(r))
|
||||
prev = r
|
||||
hasPrev = true
|
||||
}
|
||||
|
||||
flush()
|
||||
return words
|
||||
}
|
||||
|
||||
func numericContextLimitValue(value any) (int64, bool) {
|
||||
switch typed := value.(type) {
|
||||
case int64:
|
||||
|
||||
Reference in New Issue
Block a user