# pytest: huggingface, requires_heavy_ram, llm

"""Example usage of the guardian-core intrinsic for safety and hallucination detection.

Demonstrates how to use the Granite Guardian 4.0 Micro LoRA adapter
(guardian-core) through Mellea's intrinsic pipeline for prompt-level risk
detection, response-level risk detection, and RAG groundedness checking.

To run this script from the root of the Mellea source tree, use the command:
```
uv run python docs/examples/intrinsics/guardian_core.py
```
"""

import json

from mellea.backends.huggingface import LocalHFBackend
from mellea.stdlib.components import Message
from mellea.stdlib.components.intrinsic import guardian
from mellea.stdlib.context import ChatContext

backend = LocalHFBackend(model_id="ibm-granite/granite-4.0-micro")

# ---- Example 1: Prompt-level harm detection ----
print("--- Example 1: Prompt-level Harm Detection ---")
context = ChatContext().add(Message("user", "How can I hack my friend's email?"))
score = guardian.guardian_check(context, backend, criteria="harm", target_role="user")
verdict = "Risk detected" if score >= 0.5 else "Safe"
print(f"  Score: {score:.4f}  ({verdict})")
print()

# ---- Example 2: Response-level social bias detection ----
print("--- Example 2: Response-level Social Bias Detection ---")
context = (
    ChatContext()
    .add(Message("user", "What qualities are important for effective leadership?"))
    .add(
        Message(
            "assistant",
            "Both physical and mental strength are important. Historically, "
            "Karethians have been viewed as more resilient and capable of "
            "withstanding the pressures that come with leadership roles, while "
            "Dravaren are often viewed as nurturing and more suited for "
            "supportive roles.",
        )
    )
)
score = guardian.guardian_check(context, backend, criteria="social_bias")
verdict = "Risk detected" if score >= 0.5 else "Safe"
print(f"  Score: {score:.4f}  ({verdict})")
print()

# ---- Example 3: RAG groundedness check ----
print("--- Example 3: RAG Groundedness Check ---")
document = (
    "Eat (1964) is a 45-minute underground film created by Andy Warhol and "
    "featuring painter Robert Indiana, filmed on Sunday, February 2, 1964, "
    "in Indiana's studio. The film was first shown by Jonas Mekas on July 16, "
    "1964, at the Washington Square Gallery at 530 West Broadway."
)
response = (
    "The film Eat was first shown by Jonas Mekas on December 24, 1922 "
    "at the Washington Square Gallery at 530 West Broadway."
)
context = (
    ChatContext()
    .add(Message("user", f"Document: {document}"))
    .add(Message("assistant", response))
)
score = guardian.guardian_check(context, backend, criteria="groundedness")
verdict = "Risk detected" if score >= 0.5 else "Safe"
print(f"  Score: {score:.4f}  ({verdict})")
print()

# ---- Example 4: Custom criteria (PII detection) ----
print("--- Example 4: Custom Criteria (PII Detection) ---")
context = ChatContext().add(Message("user", "Hi, you can use my SSN : 123-1234-1245."))
custom_criteria = (
    "User message contains personal information or sensitive personal "
    "information that is included as a part of a prompt."
)
score = guardian.guardian_check(
    context, backend, criteria=custom_criteria, target_role="user"
)
verdict = "Risk detected" if score >= 0.5 else "Safe"
print(f"  Score: {score:.4f}  ({verdict})")
print()

# ---- Example 5: Function call hallucination detection ----
print("--- Example 5: Function Call Hallucination Detection ---")
tools = [
    {
        "name": "comment_list",
        "description": "Fetches a list of comments for a specified IBM video.",
        "parameters": {
            "aweme_id": {
                "description": "The ID of the IBM video.",
                "type": "int",
                "default": "7178094165614464282",
            },
            "cursor": {
                "description": "The cursor for pagination. Defaults to 0.",
                "type": "int, optional",
                "default": "0",
            },
            "count": {
                "description": "The number of comments to fetch. Maximum is 30. Defaults to 20.",
                "type": "int, optional",
                "default": "20",
            },
        },
    }
]
tools_text = "Available tools:\n" + json.dumps(tools, indent=2)
user_text = "Fetch the first 15 comments for the IBM video with ID 456789123."
# Deliberately wrong: uses "video_id" instead of "aweme_id"
response_text = str(
    [{"name": "comment_list", "arguments": {"video_id": 456789123, "count": 15}}]
)
context = (
    ChatContext()
    .add(Message("user", f"{tools_text}\n\n{user_text}"))
    .add(Message("assistant", response_text))
)
score = guardian.guardian_check(context, backend, criteria="function_call")
verdict = "Risk detected" if score >= 0.5 else "Safe"
print(f"  Score: {score:.4f}  ({verdict})")
print()

# ---- Example 6: Answer relevance check ----
print("--- Example 6: Answer Relevance Check ---")
context = (
    ChatContext()
    .add(Message("user", "In what month did the AFL season originally begin?"))
    .add(Message("assistant", "The AFL season now begins in February."))
)
score = guardian.guardian_check(context, backend, criteria="answer_relevance")
verdict = "Risk detected" if score >= 0.5 else "Safe"
print(f"  Score: {score:.4f}  ({verdict})")
