Skip to content

Commit b1353f4

Browse files
authored
fix: append runtime meta to ChatMessage's extracted meta in AnswerBuilder (#8544)
* append runtime meta to extracted meta * add pylint ignore flag to .run() * explicitly convert reply to string
1 parent 2cc45dd commit b1353f4

File tree

3 files changed

+63
-4
lines changed

3 files changed

+63
-4
lines changed

haystack/components/builders/answer_builder.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def __init__(self, pattern: Optional[str] = None, reference_pattern: Optional[st
5858
self.reference_pattern = reference_pattern
5959

6060
@component.output_types(answers=List[GeneratedAnswer])
61-
def run(
61+
def run( # pylint: disable=too-many-positional-arguments
6262
self,
6363
query: str,
6464
replies: Union[List[str], List[ChatMessage]],
@@ -111,10 +111,13 @@ def run(
111111
pattern = pattern or self.pattern
112112
reference_pattern = reference_pattern or self.reference_pattern
113113
all_answers = []
114-
for reply, metadata in zip(replies, meta):
114+
for reply, given_metadata in zip(replies, meta):
115115
# Extract content from ChatMessage objects if reply is a ChatMessages, else use the string as is
116-
extracted_reply: str = reply.content if isinstance(reply, ChatMessage) else reply # type: ignore
117-
extracted_metadata = reply.meta if isinstance(reply, ChatMessage) else metadata
116+
extracted_reply = reply.content if isinstance(reply, ChatMessage) else str(reply)
117+
extracted_metadata = reply.meta if isinstance(reply, ChatMessage) else {}
118+
119+
extracted_metadata = {**extracted_metadata, **given_metadata}
120+
118121
referenced_docs = []
119122
if documents:
120123
if reference_pattern:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
fixes:
3+
- |
4+
When meta is passed into AnswerBuilder.run(), it is now merged into GeneratedAnswer meta

test/components/builders/test_answer_builder.py

+52
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ def test_run_meta_is_an_empty_list(self):
3636
assert answers[0].documents == []
3737
assert isinstance(answers[0], GeneratedAnswer)
3838

39+
def test_run_with_meta(self):
40+
component = AnswerBuilder()
41+
output = component.run(query="query", replies=["reply1"], meta=[{"test": "meta"}])
42+
answers = output["answers"]
43+
assert answers[0].data == "reply1"
44+
assert answers[0].meta == {"test": "meta"}
45+
assert answers[0].query == "query"
46+
assert answers[0].documents == []
47+
assert isinstance(answers[0], GeneratedAnswer)
48+
3949
def test_run_without_pattern(self):
4050
component = AnswerBuilder()
4151
output = component.run(query="test query", replies=["Answer: AnswerString"], meta=[{}])
@@ -272,3 +282,45 @@ def test_run_with_chat_message_replies_with_pattern_set_at_runtime(self):
272282
assert answers[0].query == "test query"
273283
assert answers[0].documents == []
274284
assert isinstance(answers[0], GeneratedAnswer)
285+
286+
def test_run_with_chat_message_replies_with_meta_set_at_run_time(self):
287+
component = AnswerBuilder()
288+
replies = [
289+
ChatMessage(
290+
content="AnswerString",
291+
role=ChatRole.ASSISTANT,
292+
name=None,
293+
meta={
294+
"model": "gpt-4o-mini",
295+
"index": 0,
296+
"finish_reason": "stop",
297+
"usage": {"prompt_tokens": 32, "completion_tokens": 153, "total_tokens": 185},
298+
},
299+
)
300+
]
301+
output = component.run(query="test query", replies=replies, meta=[{"test": "meta"}])
302+
answers = output["answers"]
303+
assert len(answers) == 1
304+
assert answers[0].data == "AnswerString"
305+
assert answers[0].meta == {
306+
"model": "gpt-4o-mini",
307+
"index": 0,
308+
"finish_reason": "stop",
309+
"usage": {"prompt_tokens": 32, "completion_tokens": 153, "total_tokens": 185},
310+
"test": "meta",
311+
}
312+
assert answers[0].query == "test query"
313+
assert answers[0].documents == []
314+
assert isinstance(answers[0], GeneratedAnswer)
315+
316+
def test_run_with_chat_message_no_meta_with_meta_set_at_run_time(self):
317+
component = AnswerBuilder()
318+
replies = [ChatMessage(content="AnswerString", role=ChatRole.ASSISTANT, name=None, meta={})]
319+
output = component.run(query="test query", replies=replies, meta=[{"test": "meta"}])
320+
answers = output["answers"]
321+
assert len(answers) == 1
322+
assert answers[0].data == "AnswerString"
323+
assert answers[0].meta == {"test": "meta"}
324+
assert answers[0].query == "test query"
325+
assert answers[0].documents == []
326+
assert isinstance(answers[0], GeneratedAnswer)

0 commit comments

Comments
 (0)