aileen3-core / demo /slide_utils.py
ndurner's picture
add comments
0c163b8
from __future__ import annotations
import base64
from typing import Any, Iterable
def _data_uri_from(value: Any) -> str | None:
"""Convert raw slide/image representations into a data URI string.
This accepts several shapes that can appear in MCP tool responses:
- plain bytes
- dicts or objects with ``data``/``mimeType`` fields
- already-encoded ``data:...`` URIs
"""
if not value:
return None
if isinstance(value, str):
if value.startswith("data:"):
return value
return None
if isinstance(value, bytes):
b64 = base64.b64encode(value).decode("ascii")
return f"data:image/png;base64,{b64}"
# Handle ImageContent-like objects or dicts
data = getattr(value, "data", None)
mime = getattr(value, "mimeType", None) or getattr(value, "mime_type", None)
if isinstance(value, dict):
data = value.get("data", data)
mime = value.get("mimeType") or value.get("mime_type") or mime
if data is None:
return None
if isinstance(data, bytes):
b64 = base64.b64encode(data).decode("ascii")
else:
if isinstance(data, str) and data.startswith("data:"):
return data
if not isinstance(data, str):
return None
b64 = data
if not mime:
mime = "image/png"
return f"data:{mime};base64,{b64}"
def normalize_slide_entries(slides_result: Any) -> list[dict]:
"""Return a list of slide dicts with `image_data_uri` populated."""
if not isinstance(slides_result, dict):
return []
candidates: Iterable[Any] | None = slides_result.get("slides")
if isinstance(candidates, dict):
candidates = candidates.get("slides")
elif candidates is None:
maybe_nested = slides_result.get("result")
if isinstance(maybe_nested, dict):
candidates = maybe_nested.get("slides")
if isinstance(candidates, dict):
candidates = candidates.get("slides")
if not isinstance(candidates, list):
return []
normalized: list[dict] = []
for idx, raw in enumerate(candidates):
entry: dict | None = None
if isinstance(raw, dict):
entry = dict(raw)
data_uri = entry.get("image_data_uri")
if not data_uri:
for key in ("image", "image_content", "content"):
if key in entry:
data_uri = _data_uri_from(entry[key])
if data_uri:
entry["image_data_uri"] = data_uri
break
entry.setdefault("index", idx)
else:
data_uri = _data_uri_from(raw)
if data_uri:
entry = {"index": idx, "image_data_uri": data_uri}
if entry and entry.get("image_data_uri"):
normalized.append(entry)
return normalized
__all__ = ["normalize_slide_entries"]