feat: sync deployed v1.0.0-rc.38-custom.42

Sync production source including routing, billing, Astra detection and public uptime. Update custom build instructions and license packaging.
This commit is contained in:
cneicy committed 2026-09-26 04:49:11 +08:00
1 parent aa6c3f50f4
commit ceddfd3d6b
828 files changed
+122253 -13702

No files matched your search

+29 -5
View File
@@ -2,7 +2,6 @@ package service
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
@@ -273,6 +272,31 @@ func ConvertSimpleChangeParams(content string) *dto.MidjourneyRequest {
return changeParams
}
// RecordMidjourneyPolicyResponse distinguishes accepted tasks from errors inside
// HTTP 200 responses. Submissions are single-attempt: an ambiguous transport
// failure must never create a duplicate task on another channel.
func RecordMidjourneyPolicyResponse(c *gin.Context, response *dto.MidjourneyResponseWithStatusCode, requestErr error) bool {
if response == nil {
response = MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "empty_response", http.StatusBadGateway)
}
accepted := requestErr == nil && response.StatusCode == http.StatusOK && (response.Response.Code == 1 || response.Response.Code == 21 || response.Response.Code == 22)
if accepted {
properties, _ := response.Response.Properties.(map[string]any)
if properties["status"] != "FAILURE" {
return true
}
}
state := RequestPolicy(c)
event := PolicyEvent{ChannelID: c.GetInt("channel_id"), Status: response.StatusCode, ErrorCode: strconv.Itoa(response.Response.Code), ErrorSource: "upstream", Decision: PolicyDecision{Action: "failure", Reason: "upstream_failure", Source: "upstream"}}
state.AddEvent(event)
event.Decision, event.Health = PolicyDecision{Action: "stop", Reason: "non_retryable_error", Source: "system"}, "unchanged"
if accepted {
event.Decision.Reason = "task_accepted"
}
state.AddEvent(event)
return false
}
func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestURL string) (*dto.MidjourneyResponseWithStatusCode, []byte, error) {
var nullBytes []byte
//var requestBody io.Reader
@@ -281,7 +305,7 @@ func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestU
var mapResult map[string]any
// if get request, no need to read request body
if c.Request.Method != "GET" {
err := json.NewDecoder(c.Request.Body).Decode(&mapResult)
err := common.DecodeJson(c.Request.Body, &mapResult)
if err != nil {
return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "read_request_body_failed", http.StatusInternalServerError), nullBytes, err
}
@@ -303,7 +327,7 @@ func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestU
mapResult["prompt"] = prompt
}
}
reqBody, err := json.Marshal(mapResult)
reqBody, err := common.Marshal(mapResult)
if err != nil {
return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "marshal_request_body_failed", http.StatusInternalServerError), nullBytes, err
}
@@ -350,9 +374,9 @@ func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestU
if len(responseBody) == 0 {
return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "empty_response_body", statusCode), responseBody, nil
} else {
err = json.Unmarshal(responseBody, &midjResponse)
err = common.Unmarshal(responseBody, &midjResponse)
if err != nil {
err2 := json.Unmarshal(responseBody, &midjourneyUploadsResponse)
err2 := common.Unmarshal(responseBody, &midjourneyUploadsResponse)
if err2 != nil {
return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "unmarshal_response_body_failed", statusCode), responseBody, err
}