Files
openai--openai-agents-python/examples/web_search_utils.py
T
2026-07-13 12:39:17 +08:00

80 lines
2.2 KiB
Python

from __future__ import annotations
from collections.abc import Mapping, Sequence
from dataclasses import dataclass
from typing import Any
@dataclass(frozen=True)
class URLCitation:
title: str
url: str
def get_field(obj: Any, key: str) -> Any:
if isinstance(obj, Mapping):
return obj.get(key)
return getattr(obj, key, None)
def extract_url_citations(items: Sequence[Any]) -> list[URLCitation]:
citations: list[URLCitation] = []
seen: set[str] = set()
for item in items:
raw_item = get_field(item, "raw_item")
if get_field(raw_item, "type") != "message":
continue
content = get_field(raw_item, "content")
if not isinstance(content, list):
continue
for part in content:
if get_field(part, "type") != "output_text":
continue
annotations = get_field(part, "annotations")
if not isinstance(annotations, list):
continue
for annotation in annotations:
if get_field(annotation, "type") != "url_citation":
continue
url = get_field(annotation, "url")
title = get_field(annotation, "title")
if not isinstance(url, str) or url in seen:
continue
seen.add(url)
citations.append(
URLCitation(
title=title if isinstance(title, str) else url,
url=url,
)
)
return citations
def extract_web_search_source_urls(items: Sequence[Any]) -> list[str]:
urls: list[str] = []
seen: set[str] = set()
for item in items:
raw_item = get_field(item, "raw_item")
if get_field(raw_item, "type") != "web_search_call":
continue
action = get_field(raw_item, "action")
sources = get_field(action, "sources") if action else None
if not isinstance(sources, list):
continue
for source in sources:
url = get_field(source, "url")
if not isinstance(url, str) or url in seen:
continue
seen.add(url)
urls.append(url)
return urls