91e75e620b
CI: cua-driver distro-compat matrix / debian:12 (glibc 2.36) (push) Has been cancelled
CI: SPDX Headers / Check SPDX headers (warn-only) (push) Has been cancelled
CD: Docs MCP Server / build (linux/amd64) (push) Has been cancelled
CD: Docs MCP Server / build (linux/arm64) (push) Has been cancelled
CD: Docs MCP Server / merge (push) Has been cancelled
CI: cua-driver distro-compat matrix / Resolve release version (push) Has been cancelled
CI: cua-driver distro-compat matrix / fedora:41 (glibc 2.40) (push) Has been cancelled
CI: cua-driver distro-compat matrix / rockylinux:9 (glibc 2.34) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:22.04 (glibc 2.35) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:24.04 (glibc 2.39) (push) Has been cancelled
CI: cua-driver distro-compat matrix / Distro compat summary (push) Has been cancelled
CI: Rust Linux unit / Rust Linux unit and compile (push) Has been cancelled
CI: Rust Windows unit / Rust Windows unit and compile (push) Has been cancelled
CI: Nix Linux Rust source / Nix / compositor build (push) Has been cancelled
CI: Nix Linux Rust source / Nix / driver package (push) Has been cancelled
CI: Nix Linux Rust source / Nix / Rust unit tests (push) Has been cancelled
100 lines
3.1 KiB
Python
100 lines
3.1 KiB
Python
"""
|
|
PII anonymization callback handler using Microsoft Presidio for text and image redaction.
|
|
"""
|
|
|
|
import base64
|
|
import io
|
|
import logging
|
|
from typing import Any, Dict, List, Optional, Tuple
|
|
|
|
from .base import AsyncCallbackHandler
|
|
|
|
try:
|
|
# TODO: Add Presidio dependencies
|
|
from PIL import Image
|
|
|
|
PRESIDIO_AVAILABLE = True
|
|
except ImportError:
|
|
PRESIDIO_AVAILABLE = False
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class PIIAnonymizationCallback(AsyncCallbackHandler):
|
|
"""
|
|
Callback handler that anonymizes PII in text and images using Microsoft Presidio.
|
|
|
|
This handler:
|
|
1. Anonymizes PII in messages before sending to the agent loop
|
|
2. Deanonymizes PII in tool calls and message outputs after the agent loop
|
|
3. Redacts PII from images in computer_call_output messages
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
# TODO: Any extra kwargs if needed
|
|
):
|
|
"""
|
|
Initialize the PII anonymization callback.
|
|
|
|
Args:
|
|
anonymize_text: Whether to anonymize text content
|
|
anonymize_images: Whether to redact images
|
|
entities_to_anonymize: List of entity types to anonymize (None for all)
|
|
anonymization_operator: Presidio operator to use ("replace", "mask", "redact", etc.)
|
|
image_redaction_color: RGB color for image redaction
|
|
"""
|
|
if not PRESIDIO_AVAILABLE:
|
|
raise ImportError(
|
|
"Presidio is not available. Install with: "
|
|
"pip install cua-agent[pii-anonymization]"
|
|
)
|
|
|
|
# TODO: Implement __init__
|
|
|
|
async def on_llm_start(self, messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
|
"""
|
|
Anonymize PII in messages before sending to agent loop.
|
|
|
|
Args:
|
|
messages: List of message dictionaries
|
|
|
|
Returns:
|
|
List of messages with PII anonymized
|
|
"""
|
|
anonymized_messages = []
|
|
for msg in messages:
|
|
anonymized_msg = await self._anonymize_message(msg)
|
|
anonymized_messages.append(anonymized_msg)
|
|
|
|
return anonymized_messages
|
|
|
|
async def on_llm_end(self, output: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
|
"""
|
|
Deanonymize PII in tool calls and message outputs after agent loop.
|
|
|
|
Args:
|
|
output: List of output dictionaries
|
|
|
|
Returns:
|
|
List of output with PII deanonymized for tool calls
|
|
"""
|
|
deanonymized_output = []
|
|
for item in output:
|
|
# Only deanonymize tool calls and computer_call messages
|
|
if item.get("type") in ["computer_call", "computer_call_output"]:
|
|
deanonymized_item = await self._deanonymize_item(item)
|
|
deanonymized_output.append(deanonymized_item)
|
|
else:
|
|
deanonymized_output.append(item)
|
|
|
|
return deanonymized_output
|
|
|
|
async def _anonymize_message(self, message: Dict[str, Any]) -> Dict[str, Any]:
|
|
# TODO: Implement _anonymize_message
|
|
return message
|
|
|
|
async def _deanonymize_item(self, item: Dict[str, Any]) -> Dict[str, Any]:
|
|
# TODO: Implement _deanonymize_item
|
|
return item
|