helpers.go 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package taskcommon
  2. import (
  3. "encoding/base64"
  4. "fmt"
  5. "github.com/QuantumNous/new-api/common"
  6. "github.com/QuantumNous/new-api/model"
  7. relaycommon "github.com/QuantumNous/new-api/relay/common"
  8. "github.com/QuantumNous/new-api/setting/system_setting"
  9. "github.com/gin-gonic/gin"
  10. )
  11. // UnmarshalMetadata converts a map[string]any metadata to a typed struct via JSON round-trip.
  12. // This replaces the repeated pattern: json.Marshal(metadata) → json.Unmarshal(bytes, &target).
  13. func UnmarshalMetadata(metadata map[string]any, target any) error {
  14. if metadata == nil {
  15. return nil
  16. }
  17. metaBytes, err := common.Marshal(metadata)
  18. if err != nil {
  19. return fmt.Errorf("marshal metadata failed: %w", err)
  20. }
  21. if err := common.Unmarshal(metaBytes, target); err != nil {
  22. return fmt.Errorf("unmarshal metadata failed: %w", err)
  23. }
  24. return nil
  25. }
  26. // DefaultString returns val if non-empty, otherwise fallback.
  27. func DefaultString(val, fallback string) string {
  28. if val == "" {
  29. return fallback
  30. }
  31. return val
  32. }
  33. // DefaultInt returns val if non-zero, otherwise fallback.
  34. func DefaultInt(val, fallback int) int {
  35. if val == 0 {
  36. return fallback
  37. }
  38. return val
  39. }
  40. // EncodeLocalTaskID encodes an upstream operation name to a URL-safe base64 string.
  41. // Used by Gemini/Vertex to store upstream names as task IDs.
  42. func EncodeLocalTaskID(name string) string {
  43. return base64.RawURLEncoding.EncodeToString([]byte(name))
  44. }
  45. // DecodeLocalTaskID decodes a base64-encoded upstream operation name.
  46. func DecodeLocalTaskID(id string) (string, error) {
  47. b, err := base64.RawURLEncoding.DecodeString(id)
  48. if err != nil {
  49. return "", err
  50. }
  51. return string(b), nil
  52. }
  53. // BuildProxyURL constructs the video proxy URL using the public task ID.
  54. // e.g., "https://your-server.com/v1/videos/task_xxxx/content"
  55. func BuildProxyURL(taskID string) string {
  56. return fmt.Sprintf("%s/v1/videos/%s/content", system_setting.ServerAddress, taskID)
  57. }
  58. // Status-to-progress mapping constants for polling updates.
  59. const (
  60. ProgressSubmitted = "10%"
  61. ProgressQueued = "20%"
  62. ProgressInProgress = "30%"
  63. ProgressComplete = "100%"
  64. )
  65. // ---------------------------------------------------------------------------
  66. // BaseBilling — embeddable no-op implementations for TaskAdaptor billing methods.
  67. // Adaptors that do not need custom billing can embed this struct directly.
  68. // ---------------------------------------------------------------------------
  69. type BaseBilling struct{}
  70. // EstimateBilling returns nil (no extra ratios; use base model price).
  71. func (BaseBilling) EstimateBilling(_ *gin.Context, _ *relaycommon.RelayInfo) map[string]float64 {
  72. return nil
  73. }
  74. // AdjustBillingOnSubmit returns nil (no submit-time adjustment).
  75. func (BaseBilling) AdjustBillingOnSubmit(_ *relaycommon.RelayInfo, _ []byte) map[string]float64 {
  76. return nil
  77. }
  78. // AdjustBillingOnComplete returns 0 (keep pre-charged amount).
  79. func (BaseBilling) AdjustBillingOnComplete(_ *model.Task, _ *relaycommon.TaskInfo) int {
  80. return 0
  81. }