1package google
2
3import (
4 "cmp"
5 "errors"
6 "io"
7 "regexp"
8 "strconv"
9
10 "charm.land/fantasy"
11 "google.golang.org/genai"
12)
13
14var googleContextPattern = regexp.MustCompile(`input token count.*?(\d+).*?exceeds.*?maximum.*?(\d+)`)
15
16func toProviderErr(err error) error {
17 var apiErr genai.APIError
18 if !errors.As(err, &apiErr) {
19 // Wrap in a `ProviderError` so `.IsRetriable()` works.
20 if errors.Is(err, io.ErrUnexpectedEOF) {
21 return &fantasy.ProviderError{
22 Title: "stream transport error",
23 Message: err.Error(),
24 Cause: err,
25 }
26 }
27 return err
28 }
29
30 providerErr := &fantasy.ProviderError{
31 Message: apiErr.Message,
32 Title: cmp.Or(fantasy.ErrorTitleForStatusCode(apiErr.Code), "provider request failed"),
33 Cause: err,
34 StatusCode: apiErr.Code,
35 ResponseBody: []byte(apiErr.Message),
36 }
37
38 parseContextTooLargeError(apiErr.Message, providerErr)
39
40 return providerErr
41}
42
43func parseContextTooLargeError(message string, providerErr *fantasy.ProviderError) {
44 matches := googleContextPattern.FindStringSubmatch(message)
45 if matches == nil {
46 return
47 }
48 providerErr.ContextTooLargeErr = true
49 providerErr.ContextUsedTokens, _ = strconv.Atoi(matches[1])
50 providerErr.ContextMaxTokens, _ = strconv.Atoi(matches[2])
51}