BUG: multimodal router drops media metadata when forwarding seeds and responses
Maintainer thường phản hồi trong vòng 2 ngày
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 35/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Đình trệ
- Công nghệ
- python
- Lĩnh vực
- backend-api-design
Hướng nghiên cứu
Start with pyrit/executor/attack/component/modality_router.py, especially _ModalityFeedbackRouter._build_multimodal_message(), and inspect how it creates media pieces from converted values. Read the message formatting helper and existing modality router tests, then run the focused tests. Done means all three forwarding paths retain the agreed media metadata, transient metadata is handled as specified, and tests confirm source metadata is unchanged and copied metadata is independently owned.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Describe the bug
_ModalityFeedbackRouter._build_multimodal_message() creates fresh media pieces from each source piece's converted_value and converted_value_data_type, but discards its prompt_metadata entirely.
This affects media forwarded from a seed to the adversarial chat, from an objective response to the adversarial chat, and from an objective response into the next objective request. For example, a media piece's context_description is lost. format_message_piece_for_context() reads this metadata when formatting non-text content, so the copied piece produces only a generic modality placeholder instead of retaining its description.
Related: #3301 and #3302 concern fill_adversarial_placeholders(). This is a separate follow-up for the shared multimodal builder; that builder is unchanged by #3302. The router was introduced in #1377.
The converted media payload is already forwarded correctly. This issue is not asking to change that behavior or make the builder preserve the previous turn's original/converted lineage wholesale.
Steps/Code to Reproduce
Run in a PyRIT environment. No files, providers, credentials, or database initialization are needed.
from unittest.mock import MagicMock
from pyrit.executor.attack.component.modality_router import _ModalityFeedbackRouter
from pyrit.message_normalizer._helpers import format_message_piece_for_context
from pyrit.models import Message, MessagePiece
from pyrit.prompt_target import PromptTarget
from pyrit.prompt_target.common.target_capabilities import TargetCapabilities
from pyrit.prompt_target.common.target_configuration import TargetConfiguration
def target():
mocked = MagicMock(spec=PromptTarget)
mocked.configuration = TargetConfiguration(
capabilities=TargetCapabilities(
input_modalities=frozenset({
frozenset({"text"}),
frozenset({"text", "image_path"}),
})
)
)
return mocked
router = _ModalityFeedbackRouter(
adversarial_chat=target(), objective_target=target()
)
media = MessagePiece(
role="assistant",
original_value="source.png",
original_value_data_type="image_path",
converted_value="resized.png",
converted_value_data_type="image_path",
prompt_metadata={"context_description": "A blue square"},
)
response = media.to_message()
seed = Message(message_pieces=[
MessagePiece.adversarial_placeholder(),
media.model_copy(update={"role": "user"}),
])
print("source:", format_message_piece_for_context(piece=media))
forwarded_messages = {
"adversarial response": router.build_adversarial_input_message(
text="feedback", last_response=response
),
"adversarial seed": router.build_adversarial_input_message(
text="feedback", last_response=None, seed_message=seed
),
"objective response": router.build_objective_input_message(
text="edit", last_response=response, turn_index=1
),
}
for direction, message in forwarded_messages.items():
copied = message.get_piece(1)
print(direction, copied.converted_value, copied.prompt_metadata,
format_message_piece_for_context(piece=copied))
Expected Results
Media-scoped metadata that is still meaningful for the forwarded payload, such as context_description, survives forwarding. The copied media still points to resized.png, and formatting it retains [Image_path - A blue square].
Define the metadata-copying contract explicitly rather than blindly carrying previous-request or response-only state into a fresh request. Preserve independent ownership of mutable metadata and fresh message-piece/conversation IDs.
Add regression coverage for seed-to-adversarial forwarding and response forwarding in both directions, including source immutability and the treatment of transient metadata.
Actual Results
source: [Image_path - A blue square]
adversarial response resized.png {} [Image_path]
adversarial seed resized.png {} [Image_path]
objective response resized.png {} [Image_path]
The converted value survives, but the media copy's metadata is empty in all three paths. The source piece's metadata is unchanged.
Screenshots
N/A. This is an SDK/message-construction issue.
Versions
- OS: Windows 11.
- Browser: N/A.
- Python: 3.14.4.
- PyRIT: 1.2.0.dev0, editable checkout at
5343d3075e5b0a0abc91ee90413d6833e4e0ab26(PR #3302). The affected builder is unchanged from its basef4fb86808c41210a164b2c8983c10919c051e7a1. - Reproduced offline through all three public routing paths.
pyrit.show_versions() output, with the local executable path omitted:
System:
python: 3.14.4 (main, Apr 14 2026, 14:30:57) [MSC v.1944 64 bit (AMD64)]
machine: Windows-11-10.0.26300-SP0
Python dependencies:
pyrit: 1.2.0.dev0
Cython: None
numpy: 2.4.6
openai: 2.54.0
packaging: 25.0
pip: None
scipy: 1.17.1
setuptools: 84.0.0
sqlite3: None
torch: None
transformers: 5.19.0
- Ngôn ngữ chính
- Python
- Star
- 4.6k
- Fork
- 962
- Merge trung bình
- 2 ngày 15 giờ
- Pull request đã merge (30 ngày)
- 398
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Không có hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của microsoft/PyRIT
-
BUG: MarkdownInjectionScorer misses shortcut-reference images with path-based exfiltration, and raw HTML <img>Có thể đã có người làm @aatif101 đã nhận 1 ngày trước. Đang mởBug: triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
microsoft/PyRIT#3343 · 2 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 2 ngày
-
BUG: UrlConverter preserves forward slashes by default, preventing path payload evasionCó thể đã có người làm @Kaap10 đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 25/100
Maintainer thường phản hồi trong vòng 2 ngày
-
BUG: XSSOutputScorer misses SVG and JavaScript data URIsCó thể đã có người làm @Kaap10 đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 2 ngày
-
BUG: FuzzerGenerator accepts a jailbreak goal below 1 and a success threshold outside [0, 1]Có thể đã có người làm @ShivamSharma43 đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 2 ngày
-
BUG: ManyShotJailbreakAttack accepts a negative example_count and drops examples from the endCó thể đã có người làm @ShivamSharma43 đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 2 ngày
Tất cả issue của microsoft/PyRIT
Issue tương tự
-
[Bug]: `hermes plugins update` clones an entire monorepo twice - `subdir` is resolved but dropped at both catalog-update call sitesCó thể đã có người làm @HootRock đã nhận hôm nay. Đang mởcomp/cli P2 type/perf
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
NousResearch/hermes-agent#142417 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug enhancement python
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
DewaldOosthuizen/tech-cheat-sheets-and-notes#392 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug p2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Restore postgresql_vm_test_charm actions.yaml change (removed in canonical/postgresql-operator#2054)Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 85/100
canonical/postgresql-single-kernel-library#390 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày