Skip to content

Commit e495469

Browse files
authored
Merge branch 'main' into security_poc
2 parents 10864bd + 7c47f52 commit e495469

File tree

10 files changed

+285
-7
lines changed

10 files changed

+285
-7
lines changed

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
## [v0.2.1](https://github.com/generative-computing/mellea/releases/tag/v0.2.1) - 2025-12-10
2+
3+
### Feature
4+
5+
* Test-based Evaluation with LLM-as-a-judge ([#225](https://github.com/generative-computing/mellea/issues/225)) ([`0f1f0f8`](https://github.com/generative-computing/mellea/commit/0f1f0f8eb12e60f7940e3ad5b40ce91ded73fc88))
6+
* Add a `code_interpreter` tool ([#232](https://github.com/generative-computing/mellea/issues/232)) ([`b03c964`](https://github.com/generative-computing/mellea/commit/b03c96439501146965cd123ce5046f2c5907acfb))
7+
8+
### Fix
9+
10+
* Add simple lock to hf generation to prevent using incorrect weights ([#237](https://github.com/generative-computing/mellea/issues/237)) ([`6b2a527`](https://github.com/generative-computing/mellea/commit/6b2a5276a426be87ce02fa89f49818535f211fa6))
11+
* Collection of small fixes ([#238](https://github.com/generative-computing/mellea/issues/238)) ([`2120112`](https://github.com/generative-computing/mellea/commit/2120112ee807da4e980eabc0df54b3aae12d2cd2))
12+
* Fix unused litellm import ([#246](https://github.com/generative-computing/mellea/issues/246)) ([`633bfd7`](https://github.com/generative-computing/mellea/commit/633bfd7198eac45f8c163fefcc910d9bf8a76151))
13+
* Minor updates to answer relevance ([#245](https://github.com/generative-computing/mellea/issues/245)) ([`bde9b4d`](https://github.com/generative-computing/mellea/commit/bde9b4dd91ab92af0f7a661e321bb9d701da0589))
14+
* Pre-commit file selection ([#243](https://github.com/generative-computing/mellea/issues/243)) ([`e70d307`](https://github.com/generative-computing/mellea/commit/e70d3075f92152f8bb1a519687575fc7f30ffe1b))
15+
16+
### Documentation
17+
18+
* Fixed copyright in LICENSE ([#210](https://github.com/generative-computing/mellea/issues/210)) ([`3087051`](https://github.com/generative-computing/mellea/commit/3087051f5fc102bb8e0319af6baf9d7a0222e6ef))
19+
120
## [v0.2.0](https://github.com/generative-computing/mellea/releases/tag/v0.2.0) - 2025-11-19
221

322
### Feature
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
Example usage of the answer relevance intrinsic for RAG applications.
3+
4+
To run this script from the root of the Mellea source tree, use the command:
5+
```
6+
uv run python docs/examples/intrinsics/answer_relevance.py
7+
```
8+
"""
9+
10+
from mellea.backends.huggingface import LocalHFBackend
11+
from mellea.stdlib.base import ChatContext, Document
12+
from mellea.stdlib.chat import Message
13+
from mellea.stdlib.intrinsics import rag
14+
15+
16+
backend = LocalHFBackend(model_id="ibm-granite/granite-3.3-2b-instruct")
17+
context = ChatContext().add(Message("user", "Who attended the meeting?"))
18+
documents = [
19+
Document("Meeting attendees: Alice, Bob, Carol."),
20+
Document("Meeting time: 9:00 am to 11:00 am."),
21+
]
22+
original_result = "Many people attended the meeting."
23+
24+
print(f"Result before relevance intrinsic: {original_result}")
25+
result = rag.rewrite_answer_for_relevance(original_result, documents, context, backend)
26+
print(f"Result after relevance intrinsic: {result}")
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
Example usage of the answerability intrinsic for RAG applications.
3+
4+
To run this script from the root of the Mellea source tree, use the command:
5+
```
6+
uv run python docs/examples/intrinsics/answerability.py
7+
```
8+
"""
9+
10+
from mellea.backends.huggingface import LocalHFBackend
11+
from mellea.stdlib.base import ChatContext, Document
12+
from mellea.stdlib.chat import Message
13+
from mellea.stdlib.intrinsics import rag
14+
15+
16+
backend = LocalHFBackend(model_id="ibm-granite/granite-3.3-2b-instruct")
17+
context = ChatContext().add(Message("assistant", "Hello there, how can I help you?"))
18+
next_user_turn = "What is the square root of 4?"
19+
documents_answerable = [Document("The square root of 4 is 2.")]
20+
documents_unanswerable = [Document("The square root of 8 is not 2.")]
21+
22+
result = rag.check_answerability(next_user_turn, documents_answerable, context, backend)
23+
print(f"Result of answerability check when answer is in documents: {result}")
24+
25+
result = rag.check_answerability(
26+
next_user_turn, documents_unanswerable, context, backend
27+
)
28+
print(f"Result of answerability check when answer is not in documents: {result}")
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""
2+
Example usage of the citations intrinsic for RAG applications.
3+
4+
To run this script from the root of the Mellea source tree, use the command:
5+
```
6+
uv run python docs/examples/intrinsics/citations.py
7+
```
8+
"""
9+
10+
from mellea.backends.huggingface import LocalHFBackend
11+
from mellea.stdlib.base import ChatContext, Document
12+
from mellea.stdlib.chat import Message
13+
from mellea.stdlib.intrinsics import rag
14+
import json
15+
16+
17+
backend = LocalHFBackend(model_id="ibm-granite/granite-3.3-2b-instruct")
18+
context = ChatContext().add(
19+
Message(
20+
"user",
21+
"How does Murdoch's expansion in Australia compare to his expansion "
22+
"in New Zealand?",
23+
)
24+
)
25+
assistant_response = (
26+
"Murdoch expanded in Australia and New Zealand by acquiring and expanding local "
27+
"newspapers. I do not have information about his expansion in New Zealand after "
28+
"purchasing The Dominion."
29+
)
30+
documents = [
31+
Document(
32+
doc_id="1",
33+
text="Keith Rupert Murdoch was born on 11 March 1931 in Melbourne, Australia, "
34+
"the son of Sir Keith Murdoch (1885-1952) and Dame Elisabeth Murdoch (nee "
35+
"Greene; 1909-2012). He is of English, Irish, and Scottish ancestry. Murdoch's "
36+
"parents were also born in Melbourne. Keith Murdoch was a war correspondent "
37+
"and later a regional newspaper magnate owning two newspapers in Adelaide, "
38+
"South Australia, and a radio station in a faraway mining town. Following his "
39+
"father's death, when he was 21, Murdoch returned from Oxford to take charge "
40+
"of the family business News Limited, which had been established in 1923. "
41+
"Rupert Murdoch turned its Adelaide newspaper, The News, its main asset, into "
42+
"a major success. He began to direct his attention to acquisition and "
43+
"expansion, buying the troubled Sunday Times in Perth, Western Australia "
44+
"(1956) and over the next few years acquiring suburban and provincial "
45+
"newspapers in New South Wales, Queensland, Victoria and the Northern "
46+
"Territory, including the Sydney afternoon tabloid, The Daily Mirror (1960). "
47+
'The Economist describes Murdoch as "inventing the modern tabloid", as he '
48+
"developed a pattern for his newspapers, increasing sports and scandal "
49+
"coverage and adopting eye-catching headlines. Murdoch's first foray outside "
50+
"Australia involved the purchase of a controlling interest in the New Zealand "
51+
"daily The Dominion. In January 1964, while touring New Zealand with friends "
52+
"in a rented Morris Minor after sailing across the Tasman, Murdoch read of a "
53+
"takeover bid for the Wellington paper by the British-based Canadian newspaper "
54+
"magnate, Lord Thomson of Fleet. On the spur of the moment, he launched a "
55+
"counter-bid. A four-way battle for control ensued in which the 32-year-old "
56+
"Murdoch was ultimately successful. Later in 1964, Murdoch launched The "
57+
"Australian, Australia's first national daily newspaper, which was based "
58+
"first in Canberra and later in Sydney. In 1972, Murdoch acquired the Sydney "
59+
"morning tabloid The Daily Telegraph from Australian media mogul Sir Frank "
60+
"Packer, who later regretted selling it to him. In 1984, Murdoch was appointed "
61+
"Companion of the Order of Australia (AC) for services to publishing. In 1999, "
62+
"Murdoch significantly expanded his music holdings in Australia by acquiring "
63+
"the controlling share in a leading Australian independent label, Michael "
64+
"Gudinski's Mushroom Records; he merged that with Festival Records, and the "
65+
"result was Festival Mushroom Records (FMR). Both Festival and FMR were "
66+
"managed by Murdoch's son James Murdoch for several years.",
67+
),
68+
Document(
69+
doc_id="2",
70+
text="This document has nothing to do with Rupert Murdoch. This document is "
71+
"two sentences long.",
72+
),
73+
]
74+
75+
76+
result = rag.find_citations(assistant_response, documents, context, backend)
77+
print(f"Result of citations intrinsic:\n{json.dumps(result, indent=2)}")
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
Example usage of the context relevance intrinsic for RAG applications.
3+
4+
To run this script from the root of the Mellea source tree, use the command:
5+
```
6+
uv run python docs/examples/intrinsics/context_relevance.py
7+
```
8+
"""
9+
10+
from mellea.backends.huggingface import LocalHFBackend
11+
from mellea.stdlib.base import ChatContext, Document
12+
from mellea.stdlib.chat import Message
13+
from mellea.stdlib.intrinsics import rag
14+
15+
16+
backend = LocalHFBackend(model_id="ibm-granite/granite-3.3-2b-instruct")
17+
context = ChatContext()
18+
question = "Who is the CEO of Microsoft?"
19+
document = Document(
20+
# Document text does not say who is the CEO.
21+
"Microsoft Corporation is an American multinational corporation and technology "
22+
"conglomerate headquartered in Redmond, Washington.[2] Founded in 1975, the "
23+
"company became influential in the rise of personal computers through software "
24+
"like Windows, and the company has since expanded to Internet services, cloud "
25+
"computing, video gaming and other fields. Microsoft is the largest software "
26+
"maker, one of the most valuable public U.S. companies,[a] and one of the most "
27+
"valuable brands globally."
28+
)
29+
30+
result = rag.check_context_relevance(question, document, context, backend)
31+
print(f"Result of context relevance check: {result}")
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""
2+
Example usage of the hallucination detection intrinsic for RAG applications.
3+
4+
To run this script from the root of the Mellea source tree, use the command:
5+
```
6+
uv run python docs/examples/intrinsics/hallucination_detection.py
7+
```
8+
"""
9+
10+
from mellea.backends.huggingface import LocalHFBackend
11+
from mellea.stdlib.base import ChatContext, Document
12+
from mellea.stdlib.chat import Message
13+
from mellea.stdlib.intrinsics import rag
14+
import json
15+
16+
17+
backend = LocalHFBackend(model_id="ibm-granite/granite-3.3-2b-instruct")
18+
context = (
19+
ChatContext()
20+
.add(Message("assistant", "Hello there, how can I help you?"))
21+
.add(Message("user", "Tell me about some yellow fish."))
22+
)
23+
24+
assistant_response = "Purple bumble fish are yellow. Green bumble fish are also yellow."
25+
26+
documents = [
27+
Document(
28+
doc_id="1",
29+
text="The only type of fish that is yellow is the purple bumble fish.",
30+
)
31+
]
32+
33+
result = rag.flag_hallucinated_content(assistant_response, documents, context, backend)
34+
print(f"Result of hallucination check: {json.dumps(result, indent=2)}")
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""
2+
Example usage of the query rewrite intrinsic for RAG applications.
3+
4+
To run this script from the root of the Mellea source tree, use the command:
5+
```
6+
uv run python docs/examples/intrinsics/query_rewrite.py
7+
```
8+
"""
9+
10+
from mellea.backends.huggingface import LocalHFBackend
11+
from mellea.stdlib.base import ChatContext
12+
from mellea.stdlib.chat import Message
13+
from mellea.stdlib.intrinsics import rag
14+
15+
16+
backend = LocalHFBackend(model_id="ibm-granite/granite-3.3-2b-instruct")
17+
context = (
18+
ChatContext()
19+
.add(Message("assistant", "Welcome to pet questions!"))
20+
.add(Message("user", "I have two pets, a dog named Rex and a cat named Lucy."))
21+
.add(
22+
Message(
23+
"assistant",
24+
"Rex spends a lot of time in the backyard and outdoors, "
25+
"and Luna is always inside.",
26+
)
27+
)
28+
.add(
29+
Message(
30+
"user",
31+
"Sounds good! Rex must love exploring outside, while Lucy "
32+
"probably enjoys her cozy indoor life.",
33+
)
34+
)
35+
)
36+
next_user_turn = "But is he more likely to get fleas because of that?"
37+
38+
print(f"Original user question: {next_user_turn}")
39+
40+
result = rag.rewrite_question(next_user_turn, context, backend)
41+
print(f"Rewritten user question: {result}")

mellea/stdlib/genslot.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,17 @@ def bind_function_arguments(
204204
Dictionary mapping parameter names to bound values with defaults applied.
205205
"""
206206
signature = inspect.signature(func)
207-
bound_arguments = signature.bind(*args, **kwargs)
207+
try:
208+
bound_arguments = signature.bind(*args, **kwargs)
209+
except TypeError as e:
210+
# Provide a clear error message when parameters from the original function are missing
211+
if "missing" in str(e) and "required" in str(e):
212+
raise TypeError(
213+
f"generative slot is missing required parameter(s) from the original function '{func.__name__}': {e}"
214+
) from e
215+
216+
# Else re-raise the error if it's not the expected error.
217+
raise e
208218
bound_arguments.apply_defaults()
209219
return dict(bound_arguments.arguments)
210220

@@ -346,10 +356,22 @@ def _context_backend_extract_args_and_kwargs(
346356
using_session_overload = True
347357

348358
# Call the appropriate function and let python handle the arg/kwarg extraction.
349-
if using_session_overload:
350-
extracted = _session_extract_args_and_kwargs(*args, **kwargs)
351-
else:
352-
extracted = _context_backend_extract_args_and_kwargs(*args, **kwargs)
359+
try:
360+
if using_session_overload:
361+
extracted = _session_extract_args_and_kwargs(*args, **kwargs)
362+
else:
363+
extracted = _context_backend_extract_args_and_kwargs(*args, **kwargs)
364+
except TypeError as e:
365+
# Provide a clear error message when required mellea parameters are missing
366+
if "missing" in str(e) and (
367+
"context" in str(e) or "backend" in str(e) or "m" in str(e)
368+
):
369+
raise TypeError(
370+
"generative slot requires either a MelleaSession (m=...) or both a Context and Backend (context=..., backend=...) to be provided as the first argument(s)"
371+
) from e
372+
373+
# If it's not the expected err, simply re-raise it.
374+
raise e
353375

354376
if len(extracted.f_args) > 0:
355377
raise TypeError(

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "pdm.backend"
44

55
[project]
66
name = "mellea"
7-
version = "0.2.0"
7+
version = "0.2.1"
88
authors = [
99
{ name = "Nathan Fulton", email = "[email protected]" },
1010
{ name = "Hendrik Strobelt", email = "[email protected]" },

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)