Implement issue 167: Handle multimodal content in print_history pretty-print mode

The print_history function (used by -p flag) now properly displays multimodal
content by:
- Displaying text content parts from ContentPart arrays
- Indicating presence of image_url content parts with [Image] marker
- Rendering mixed content types in a human-readable format

All 35 tests pass.
This commit is contained in:
2026-06-15 22:26:15 +00:00
committed by Jacob Gamble
parent 8ddee0f621
commit 030e3f7656
3 changed files with 107 additions and 1 deletions
+10 -1
View File
@@ -458,10 +458,19 @@ inline std::string Message::dump(int indent) const {
return nlohmann::json(*this).dump(indent);
}
// Operator<< for variant content - outputs string if variant holds string, empty string otherwise
// Operator<< for variant content - outputs string if variant holds string,
// or renders text parts and indicates image parts for vector<ContentPart>
inline std::ostream& operator<<(std::ostream& os, const std::variant<std::string, std::vector<ContentPart>>& content) {
if (auto* str = std::get_if<std::string>(&content)) {
os << *str;
} else if (auto* parts = std::get_if<std::vector<ContentPart>>(&content)) {
for (const auto& part : *parts) {
if (part.type == "text" && part.text.has_value()) {
os << part.text.value();
} else if (part.type == "image_url" && part.image_url.has_value()) {
os << "[Image]";
}
}
}
return os;
}
+3
View File
@@ -69,3 +69,6 @@ add_dr_test(test_multimodal_message)
# Add multimodal round-trip persistence tests
add_dr_test(test_multimodal_roundtrip)
# Add print_history multimodal tests
add_dr_test(test_print_history_multimodal)
+94
View File
@@ -0,0 +1,94 @@
#!/bin/bash
# test_print_history_multimodal.sh - Tests for print_history (-p flag) with multimodal content
# Create a minimal 1x1 PNG file for testing
printf '\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90\x77\x53\xDE\x00\x00\x00\x0C\x49\x44\x41\x54\x08\xD7\x63\xF8\xCF\xC0\x00\x00\x03\x01\x01\x00\x18\xDD\x8D\xB4\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82' > "${TEST_TEMP_DIR}/test.png"
# =============================================================================
# Test 1: Verify -p flag displays text content parts in multimodal messages
# =============================================================================
# Create a chat with multimodal message
echo "$(be_done "Response")" | "${DRHARNESS}" \
-F "${TEST_TEMP_DIR}/chat.json" \
-n \
-d \
-i "${TEST_TEMP_DIR}/test.png" \
-m "describe this image" 2>/dev/null
# Print history using -p flag
OUTPUT=$("${DRHARNESS}" -p "${TEST_TEMP_DIR}/chat.json" 2>/dev/null)
# Verify text content is displayed
if ! echo "$OUTPUT" | grep -q "describe this image"; then
echo "FAIL: Expected 'describe this image' in output, got:"
echo "$OUTPUT"
exit 1
fi
# =============================================================================
# Test 2: Verify -p flag indicates presence of image_url content parts
# =============================================================================
# Verify [Image] indicator is present
if ! echo "$OUTPUT" | grep -q "\[Image\]"; then
echo "FAIL: Expected '[Image]' indicator in output, got:"
echo "$OUTPUT"
exit 1
fi
# =============================================================================
# Test 3: Verify text-only messages still display correctly
# =============================================================================
# Create a chat with text-only message
echo "$(be_done "Text response")" | "${DRHARNESS}" \
-F "${TEST_TEMP_DIR}/chat_text.json" \
-n \
-d \
-m "text only prompt" 2>/dev/null
# Print history using -p flag
TEXT_OUTPUT=$("${DRHARNESS}" -p "${TEST_TEMP_DIR}/chat_text.json" 2>/dev/null)
# Verify text content is displayed
if ! echo "$TEXT_OUTPUT" | grep -q "text only prompt"; then
echo "FAIL: Expected 'text only prompt' in output, got:"
echo "$TEXT_OUTPUT"
exit 1
fi
# Verify no [Image] indicator for text-only message
if echo "$TEXT_OUTPUT" | grep -q "\[Image\]"; then
echo "FAIL: Did not expect '[Image]' in text-only output, got:"
echo "$TEXT_OUTPUT"
exit 1
fi
# =============================================================================
# Test 4: Verify multiple images are all indicated
# =============================================================================
# Create second image file
printf '\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90\x77\x53\xDE\x00\x00\x00\x0C\x49\x44\x41\x54\x08\xD7\x63\xF8\xCF\xC0\x00\x00\x03\x01\x01\x00\x18\xDD\x8D\xB4\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82' > "${TEST_TEMP_DIR}/test2.png"
echo "$(be_done "Response 2")" | "${DRHARNESS}" \
-F "${TEST_TEMP_DIR}/chat_multi.json" \
-n \
-d \
-i "${TEST_TEMP_DIR}/test.png" \
-i "${TEST_TEMP_DIR}/test2.png" \
-m "compare images" 2>/dev/null
# Print history using -p flag
MULTI_OUTPUT=$("${DRHARNESS}" -p "${TEST_TEMP_DIR}/chat_multi.json" 2>/dev/null)
# Count [Image] occurrences - should be 2
IMAGE_COUNT=$(echo "$MULTI_OUTPUT" | grep -o "\[Image\]" | wc -l)
if [ "$IMAGE_COUNT" != "2" ]; then
echo "FAIL: Expected 2 '[Image]' indicators for 2 images, got ${IMAGE_COUNT}"
echo "$MULTI_OUTPUT"
exit 1
fi
echo "All print_history multimodal tests passed"