| """Load and validate pinned application metadata used by Orienter prompts.""" |
|
|
| import json |
| from collections.abc import Mapping |
| from pathlib import Path |
|
|
|
|
| def _reject_duplicate_keys(pairs): |
| result = {} |
| for key, value in pairs: |
| if key in result: |
| raise ValueError(f"Duplicate key in metadata cache: {key}") |
| result[key] = value |
| return result |
|
|
|
|
| def _loads_json(text: str): |
| return json.loads(text, object_pairs_hook=_reject_duplicate_keys) |
|
|
|
|
| def _validated_record(app_id, record): |
| normalized_id = str(app_id) |
| if not isinstance(record, Mapping): |
| raise ValueError( |
| f"metadata cache record for app_id {normalized_id} must be a JSON object" |
| ) |
| if "app_id" in record and str(record["app_id"]) != normalized_id: |
| raise ValueError( |
| f"metadata cache key {normalized_id} conflicts with record app_id {record['app_id']}" |
| ) |
| app_name = record.get("app_name") or record.get("name") or record.get("title") |
| app_description = record.get("app_description") or record.get("description") |
| if not isinstance(app_name, str) or not app_name.strip(): |
| raise ValueError(f"metadata cache record for app_id {normalized_id} is missing app_name") |
| if not isinstance(app_description, str) or not app_description.strip(): |
| raise ValueError( |
| f"metadata cache record for app_id {normalized_id} is missing app_description" |
| ) |
| return dict(record) |
|
|
|
|
| def _add_record(cache, app_id, record): |
| normalized_id = str(app_id) |
| if normalized_id in cache: |
| raise ValueError(f"Duplicate app_id in metadata cache: {normalized_id}") |
| cache[normalized_id] = _validated_record(normalized_id, record) |
|
|
|
|
| def load_app_metadata_cache(path): |
| """Return a validated app-id mapping from JSON, JSON-list, or JSONL input.""" |
| if path is None: |
| return None |
|
|
| path = Path(path) |
| if path.suffix.lower() == ".jsonl": |
| cache = {} |
| with path.open(encoding="utf-8") as file: |
| for line_number, line in enumerate(file, start=1): |
| if not line.strip(): |
| continue |
| record = _loads_json(line) |
| if not isinstance(record, Mapping) or "app_id" not in record: |
| raise ValueError( |
| f"metadata JSONL record on line {line_number} must include app_id" |
| ) |
| _add_record(cache, record["app_id"], record) |
| return cache |
|
|
| loaded = _loads_json(path.read_text(encoding="utf-8")) |
| if isinstance(loaded, list): |
| cache = {} |
| for index, record in enumerate(loaded): |
| if not isinstance(record, Mapping) or "app_id" not in record: |
| raise ValueError(f"metadata JSON list record {index} must include app_id") |
| _add_record(cache, record["app_id"], record) |
| return cache |
| if not isinstance(loaded, Mapping): |
| raise ValueError(f"Metadata cache must be a JSON object, list, or JSONL: {path}") |
|
|
| cache = {} |
| for app_id, record in loaded.items(): |
| _add_record(cache, app_id, record) |
| return cache |
|
|
|
|
| def get_app_metadata(app_id, metadata_cache): |
| """Return the validated app name and description for one app ID.""" |
| normalized_id = str(app_id) |
| record = metadata_cache.get(normalized_id) |
| if record is None: |
| raise KeyError(f"app_id {normalized_id} is missing from the app metadata cache") |
| record = _validated_record(normalized_id, record) |
| app_name = record.get("app_name") or record.get("name") or record.get("title") |
| app_description = record.get("app_description") or record.get("description") |
| return app_name, app_description |
|
|