account_traffic_events.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. package service
  2. import (
  3. "strings"
  4. "github.com/tidwall/gjson"
  5. )
  6. // Classify the outcome before treating a terminal frame as successful. Some
  7. // providers report failures inside response.done rather than response.failed.
  8. func accountTrafficEventStatus(payload []byte) (int, bool) {
  9. root := gjson.ParseBytes(payload)
  10. kind := root.Get("type").String()
  11. responseStatus := root.Get("response.status").String()
  12. failed := kind == "error" || kind == "response.failed" || responseStatus == "failed"
  13. if failed {
  14. for _, path := range []string{"error", "response.error", "response.status_details.error"} {
  15. e := root.Get(path)
  16. for _, field := range []string{"status", "status_code"} {
  17. if status := int(e.Get(field).Int()); status == 429 || (status >= 500 && status < 600) {
  18. return status, true
  19. }
  20. }
  21. code := strings.ToLower(e.Get("code").String() + " " + e.Get("type").String())
  22. if strings.Contains(code, "rate_limit") || strings.Contains(code, "usage_limit_reached") {
  23. return 429, true
  24. }
  25. if strings.Contains(code, "server_error") || strings.Contains(code, "overload") || strings.Contains(code, "internal_error") || strings.Contains(code, "upstream_error") {
  26. return 503, true
  27. }
  28. }
  29. return 499, true
  30. }
  31. switch kind {
  32. case "response.incomplete", "response.cancelled", "response.canceled":
  33. return 499, true
  34. case "response.completed", "response.done":
  35. if responseStatus != "" && responseStatus != "completed" {
  36. return 499, true
  37. }
  38. return 200, true
  39. case "message_stop":
  40. return 200, true
  41. }
  42. if root.Get("candidates.0.finishReason").String() == "STOP" || root.Get("choices.0.finish_reason").String() == "stop" {
  43. return 200, true
  44. }
  45. return 0, false
  46. }