> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gp.scale.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI Agents Integration

> Automatically trace openai-agents workflows with the SGP processor.

The SGP Tracing SDK provides an integration for the `openai-agents` library via the `OpenAITracingSGPProcessor`. This processor automatically captures detailed traces from your AI agent runs, translating events from the agent's lifecycle into SGP traces and spans.

This provides deep visibility into your agent's execution, including tool calls and model invocations, without requiring manual instrumentation.

<Warning>
  This integration requires the [`openai-agents`](https://pypi.org/project/openai-agents/) package. The processor will raise an `ImportError` if the package is not installed.
</Warning>

***

## How it Works

The `OpenAITracingSGPProcessor` hooks into the `openai-agents` tracing system. You register it once, and it listens for lifecycle events, handling the translation to SGP tracing objects automatically.

* **Trace Management**:
  * When an agent run starts, `on_trace_start` creates a corresponding SGP trace with the type `AGENT_WORKFLOW`. The root span of this trace is stored internally.
  * When the run ends, `on_trace_end` finds the stored root span and marks it as complete.

* **Span Management**:
  * As the agent executes, `on_span_start` fires for each new operation. It creates a new SGP span, linking it to the correct parent (either another span or the root trace).
  * It uses the `openai_span_type_map` helper to convert the agent's span type (e.g., "function", "generation") into an SGP `SpanType` (e.g., "CODE\_EXECUTION", "COMPLETION").
  * When the operation finishes, `on_span_end` populates the span's `input`, `output`, and `metadata` using helper functions that parse the data from the agent. If the agent reports an error, it's recorded on the span.

***

## Usage Example

To use the processor, you must initialize SGP tracing and then register an instance of `OpenAITracingSGPProcessor` with the `openai-agents` library.

```python theme={null}
import os
import asyncio
import requests
from bs4 import BeautifulSoup
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from agents import Agent, Runner, function_tool, set_trace_processors
from datetime import date

import scale_gp_beta.lib.tracing as tracing
from scale_gp_beta import SGPClient
from scale_gp_beta.lib.tracing.integrations import OpenAITracingSGPProcessor


@function_tool
def google_search(query: str) -> list[str]:
    scoped_span = tracing.current_span()
    try:
        api_key, cse_id = os.environ["GOOGLE_API_KEY"], os.environ["GOOGLE_CSE_ID"]
        with tracing.create_span("build_custom_search"):
            service = build("customsearch", "v1", developerKey=api_key)

        with tracing.create_span("execute_custom_search", input={"query": query}) as span:
            res = service.cse().list(q=query, cx=cse_id, num=5).execute()
            span.output = {"response": res}
        urls = [item['link'] for item in res.get('items', [])]

        return urls
    except HttpError as e:
        error_message = f"An error occurred with Google Search: {e}"
        scoped_span.set_error(error_message) if scoped_span else None
        return [error_message]
    except Exception as e:
        error_message = f"An unexpected error occurred: {e}"
        scoped_span.set_error(error_message) if scoped_span else None
        return [error_message]


@function_tool
def get_article_content(url: str) -> str:
    scoped_span = tracing.current_span()
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
        }
        with tracing.create_span("GET_article_content", input={"url": url}, span_type="FILE_RETRIEVAL") as span:
            response = requests.get(url, headers=headers, timeout=10)
            response.raise_for_status()
            span.output = {"text": response.text, "code": response.status_code}

        with tracing.create_span("parse_article_content", span_type="DATA_MANIPULATION", input={"text": response.text}) as span:
            soup = BeautifulSoup(response.text, 'html.parser')
            paragraphs = soup.find_all('p')
            article_text = "\n".join([p.get_text() for p in paragraphs])
            truncated_text = (article_text[:4000] + '...') if len(article_text) > 4000 else article_text
            span.output = {"truncated_text": truncated_text}
        return truncated_text

    except requests.RequestException as e:
        error_message = f"An error occurred while fetching the URL: {e}"
        scoped_span.set_error(error_message) if scoped_span else None
        return error_message
    except Exception as e:
        error_message = f"An unexpected error occurred during content extraction: {e}"
        scoped_span.set_error(error_message) if scoped_span else None
        return error_message


async def main() -> None:
    today_str = f"Today's date is {date.today().strftime("%A, %B %d, %Y")}."

    news_agent = Agent(
        name="Personalized News Digest Agent",
        instructions=(
            f"{today_str}. You are a research assistant. Your goal is to provide a concise summary of recent news based on the user's request. "
            "First, use the `Google Search` tool to find relevant articles. "
            "Next, use the `get_article_content` tool on the most promising URLs to read them. "
            "Finally, synthesize the information from the articles into a coherent summary for the user."
        ),
        model="gpt-4-turbo",
        tools=[google_search, get_article_content],
    )

    user_prompt = input("Please enter your news request: ")
    result = await Runner.run(news_agent, user_prompt)
    print(result.final_output)

if __name__ == "__main__":
    SGP_API_KEY, SGP_ACCOUNT_ID = "XXX", "XXX"
    os.environ["OPENAI_API_KEY"], os.environ["GOOGLE_API_KEY"], os.environ["GOOGLE_CSE_ID"] = "XXX", "XXX", "XXX"

    client = SGPClient(api_key=SGP_API_KEY, account_id=SGP_ACCOUNT_ID)

    tracing.init(client)
    set_trace_processors([OpenAITracingSGPProcessor()])

    asyncio.run(main())
```
