fix: i2i mode jq command to handle base64 with embedded newlines

- Use 'jq -Rs split' instead of 'jq -R' to properly handle base64 data URIs
  that may contain embedded newlines in the data
- Fix double-nesting of subject_reference array causing API error 2013
- Also fix: base64 -w 0 to avoid line wrapping in base64 output
- Write payload to temp file for curl to avoid shell arg length limits
- Add full response output on API error for easier debugging

Fixes #53
This commit is contained in:
smallmj
2026-04-01 10:27:53 +08:00
parent cf44f7b122
commit 9643620f1a

View File

@@ -44,7 +44,7 @@ image_to_data_url() {
local mime local mime
mime="$(file -b --mime-type "$path" 2>/dev/null)" || mime="image/jpeg" mime="$(file -b --mime-type "$path" 2>/dev/null)" || mime="image/jpeg"
local b64 local b64
b64="$(base64 < "$path")" b64="$(base64 -w 0 < "$path")"
echo "data:${mime};base64,${b64}" echo "data:${mime};base64,${b64}"
} }
@@ -111,13 +111,16 @@ build_payload() {
if [[ -n "$ref_image" ]]; then if [[ -n "$ref_image" ]]; then
local img_url local img_url
img_url="$(resolve_image "$ref_image")" img_url="$(resolve_image "$ref_image")"
# Write the subject_reference array to a temp file, then merge using --from-file # Create temp files and set traps separately to avoid set -u issues
local ref_tmp; ref_tmp="$(mktemp)"; trap "rm -f '$base_tmp' '$ref_tmp'" EXIT INT TERM HUP local ref_tmp; ref_tmp="$(mktemp)"
jq -n --arg img "$img_url" \ trap "rm -f '$base_tmp' '$ref_tmp'" EXIT INT TERM HUP
'[{type: "character", image_file: $img}]' \ local url_tmp; url_tmp="$(mktemp)"; trap "rm -f '$base_tmp' '$ref_tmp' '$url_tmp'" EXIT INT TERM HUP
> "$ref_tmp" # Write URL to temp file to avoid long-argument issues, then build JSON
local tmp2; tmp2="$(mktemp)"; trap "rm -f '$base_tmp' '$ref_tmp' '$tmp2'" EXIT INT TERM HUP echo -n "$img_url" > "$url_tmp"
jq --from-file "$ref_tmp" '. + {subject_reference: .subject_reference}' "$base_tmp" > "$tmp2" # Use jq -s to collect all lines (handles base64 with embedded newlines), take first element
jq -Rs 'split("\n")[0] | {type: "character", image_file: .}' "$url_tmp" > "$ref_tmp"
local tmp2; tmp2="$(mktemp)"; trap "rm -f '$base_tmp' '$ref_tmp' '$url_tmp' '$tmp2'" EXIT INT TERM HUP
jq --slurpfile ref "$ref_tmp" '. + {subject_reference: $ref}' "$base_tmp" > "$tmp2"
mv "$tmp2" "$base_tmp" mv "$tmp2" "$base_tmp"
fi fi
@@ -228,13 +231,18 @@ USAGE
echo "Model: $model" echo "Model: $model"
echo "Generating $n image(s)..." echo "Generating $n image(s)..."
# Write payload to temp file to avoid command-line length limits
local payload_tmp; payload_tmp="$(mktemp)"
trap "rm -f '$payload_tmp'" EXIT INT TERM HUP
echo -n "$payload" > "$payload_tmp"
local raw_output http_code response local raw_output http_code response
raw_output="$(curl -s -w "\n%{http_code}" \ raw_output="$(curl -s -w "\n%{http_code}" \
-X POST "$api_url" \ -X POST "$api_url" \
-H "Authorization: Bearer ${MINIMAX_API_KEY}" \ -H "Authorization: Bearer ${MINIMAX_API_KEY}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
--max-time 120 \ --max-time 120 \
-d "$payload" 2>/dev/null)" || { -d "@$payload_tmp" 2>/dev/null)" || {
echo "Error: curl request failed" >&2 echo "Error: curl request failed" >&2
exit 1 exit 1
} }
@@ -254,6 +262,7 @@ USAGE
local status_msg local status_msg
status_msg="$(echo "$response" | jq -r '.base_resp.status_msg // "Unknown error"')" status_msg="$(echo "$response" | jq -r '.base_resp.status_msg // "Unknown error"')"
echo "Error: API error (code $status_code): $status_msg" >&2 echo "Error: API error (code $status_code): $status_msg" >&2
echo "Full response: $response" >&2
exit 1 exit 1
fi fi