fix: send images as top-level ImageData field, not ChatMessage blob

SendUserCascadeMessageRequest proto field layout (from JS bundle analysis):
- Field 6 is 'images' (repeated ImageData) at the REQUEST level
- NOT a Blob sub-message inside ChatMessage (field 2)

ImageData proto uses base64_data (field 1) + mime_type (field 2),
not raw bytes. The LS was silently ignoring our ChatMessage blob
because the field structure didn't match.

Also protect MITM modifier from stripping messages containing
inlineData (image parts in Google API JSON).
This commit is contained in:
Nikketryhard
2026-02-15 17:46:41 -06:00
parent 2ac2016ed4
commit 0a33c1b706
2 changed files with 64 additions and 22 deletions

View File

@@ -85,7 +85,17 @@ pub fn modify_request(body: &[u8], tool_ctx: Option<&ToolContext>) -> Option<Vec
let before = contents.len();
// Remove messages that are pure Antigravity context injection
// IMPORTANT: Never strip messages containing inlineData (images)
contents.retain(|msg| {
// Always keep messages with image/binary data in any part
if let Some(parts) = msg["parts"].as_array() {
for part in parts {
if part.get("inlineData").is_some() {
return true;
}
}
}
if let Some(text) = msg["parts"][0]["text"].as_str() {
// Strip user_information (OS, workspace paths)
if text.starts_with("<user_information>") {
@@ -151,8 +161,16 @@ pub fn modify_request(body: &[u8], tool_ctx: Option<&ToolContext>) -> Option<Vec
}
}
// Remove now-empty messages
// Remove now-empty messages (but preserve messages with non-text parts like images)
contents.retain(|msg| {
if let Some(parts) = msg["parts"].as_array() {
// Keep if any part has inlineData
for part in parts {
if part.get("inlineData").is_some() {
return true;
}
}
}
if let Some(text) = msg["parts"][0]["text"].as_str() {
!text.trim().is_empty()
} else {