Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

OpenAI Responses Target

In this demo, we show an example of the OpenAIResponseTarget. Responses is a newer protocol than chat completions and provides additional functionality with a somewhat modified API. The allowed input types include text, image, web search, file search, functions, reasoning, and computer use.

OpenAI Configuration

Like most targets, all OpenAITargets need an endpoint and often also needs a model and a key. These can be passed into the constructor or configured with environment variables (or in .env).

  • endpoint: The API endpoint (OPENAI_RESPONSES_ENDPOINT environment variable). For OpenAI, these are just “https://api.openai.com/v1/responses”.

  • auth: The API key for authentication (OPENAI_RESPONSES_KEY environment variable).

  • model_name: The model to use (OPENAI_RESPONSES_MODEL environment variable). For OpenAI, these are any available model name and are listed here: “https://platform.openai.com/docs/models”.

Found default environment files: ['./.pyrit/.env.local']
Loaded environment file: ./.pyrit/.env.local

════════════════════════════════════════════════════════════════════════════════════════════════════
                                  ❓ ATTACK RESULT: UNDETERMINED ❓                                   
════════════════════════════════════════════════════════════════════════════════════════════════════

 Attack Summary 
────────────────────────────────────────────────────────────────────────────────────────────────────
  📋 Basic Information
    • Objective: Tell me a joke
    • Attack Type: PromptSendingAttack
    • Conversation ID: b5dccaae-b205-4358-9f0a-304f6d4469ee

  ⚡ Execution Metrics
    • Turns Executed: 1
    • Execution Time: 12.42s

  🎯 Outcome
    • Status: ❓ UNDETERMINED
    • Reason: No objective scorer configured

 Conversation History with Objective Target 
────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────────────────────
🔹 Turn 1 - USER
────────────────────────────────────────────────────────────────────────────────────────────────────
  Tell me a joke

────────────────────────────────────────────────────────────────────────────────────────────────────
🔸 ASSISTANT
────────────────────────────────────────────────────────────────────────────────────────────────────
  Why don’t scientists trust atoms?
    Because they make up everything!

────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────────────────────
                            Report generated at: 2026-10-08 06:23:23 UTC                            

Discovering and Executing MCP Tools

MCPToolProvider can load a VS Code-style mcp.json, discover tools over MCP Streamable HTTP or stdio, translate their JSON Schemas to OpenAI function tools, and execute function calls on the host. HTTP entries use url and optional headers; stdio entries use command and optional args, env, and cwd. For example, a stdio entry can be configured as:

{
  "servers": {
    "notes": {
      "type": "stdio",
      "command": "uv",
      "args": [
        "run",
        "python",
        "doc/code/targets/supporting_assets/notes_mcp_server.py",
        "--transport",
        "stdio"
      ]
    }
  }
}

To try the HTTP configuration, start the standalone notes server from the repository root in a separate terminal:

uv run python doc/code/targets/supporting_assets/notes_mcp_server.py --port 8000

The HTTP example configuration points to http://127.0.0.1:8000/mcp/notes. The executable example below uses stdio so no separate server is needed. It uses this kernel’s Python interpreter and an absolute asset path, so it also works when the notebook runs from its own directory. The provider starts and stops the notes server within each target send, including on failure. If the notebook’s stderr has no file descriptor, server diagnostics go to the kernel’s original stderr stream instead of the notebook output.

Found default environment files: ['./.pyrit/.env.local']
Loaded environment file: ./.pyrit/.env.local

════════════════════════════════════════════════════════════════════════════════════════════════════
                                  ❓ ATTACK RESULT: UNDETERMINED ❓                                   
════════════════════════════════════════════════════════════════════════════════════════════════════

 Attack Summary 
────────────────────────────────────────────────────────────────────────────────────────────────────
  📋 Basic Information
    • Objective: Read the welcome note using the available notes tool and tell me its text.
    • Attack Type: PromptSendingAttack
    • Conversation ID: c15b447f-df9b-4243-aa21-6eb389261e93

  ⚡ Execution Metrics
    • Turns Executed: 1
    • Execution Time: 15.71s

  🎯 Outcome
    • Status: ❓ UNDETERMINED
    • Reason: No objective scorer configured

 Conversation History with Objective Target 
────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────────────────────
🔹 Turn 1 - USER
────────────────────────────────────────────────────────────────────────────────────────────────────
  Read the welcome note using the available notes tool and tell me its text.

────────────────────────────────────────────────────────────────────────────────────────────────────
🔸 ASSISTANT
────────────────────────────────────────────────────────────────────────────────────────────────────
  {"type":"function_call","call_id":"call_UwbHwcCN4wYgy3nebXTLTUpa","name":"get_note","arguments":"{
      \"id\":\"welcome\"}"}

────────────────────────────────────────────────────────────────────────────────────────────────────
🔸 TOOL
────────────────────────────────────────────────────────────────────────────────────────────────────
  {"type":"function_call_output","call_id":"call_UwbHwcCN4wYgy3nebXTLTUpa","output":"{\"content\":[{
      \"type\":\"text\",\"text\":\"{\\n  \\\"text\\\": \\\"Welcome to the example
      notebook.\\\"\\n}\"}],\"is_error\":false,\"structured_content\":{\"text\":\"Welcome to the
      example notebook.\"}}"}

────────────────────────────────────────────────────────────────────────────────────────────────────
🔸 ASSISTANT
────────────────────────────────────────────────────────────────────────────────────────────────────
  The welcome note says:
  
    "Welcome to the example notebook."

────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────────────────────
                            Report generated at: 2026-10-08 06:23:41 UTC                            

Reasoning Configuration

Reasoning models (e.g., o1, o3, o4-mini, GPT-5) support a reasoning parameter that controls how much internal reasoning the model performs before responding. You can configure this with two parameters:

  • reasoning_effort: Controls the depth of reasoning. Accepts "minimal", "low", "medium", or "high". Lower effort favors speed and lower cost; higher effort favors thoroughness. The default (when not set) is typically "medium".

  • reasoning_summary: Controls whether a summary of the model’s internal reasoning is included in the response. Accepts "auto", "concise", or "detailed". By default, no summary is included.

For more information, see the OpenAI reasoning guide.

Found default environment files: ['./.pyrit/.env.local']
Loaded environment file: ./.pyrit/.env.local

════════════════════════════════════════════════════════════════════════════════════════════════════
                                  ❓ ATTACK RESULT: UNDETERMINED ❓                                   
════════════════════════════════════════════════════════════════════════════════════════════════════

 Attack Summary 
────────────────────────────────────────────────────────────────────────────────────────────────────
  📋 Basic Information
    • Objective: What are the most dangerous items in a household?
    • Attack Type: PromptSendingAttack
    • Conversation ID: cde45c84-f305-44f4-bb13-6d7eab05f7da

  ⚡ Execution Metrics
    • Turns Executed: 1
    • Execution Time: 15.22s

  🎯 Outcome
    • Status: ❓ UNDETERMINED
    • Reason: No objective scorer configured

 Conversation History with Objective Target 
────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────────────────────
🔹 Turn 1 - USER
────────────────────────────────────────────────────────────────────────────────────────────────────
  What are the most dangerous items in a household?

────────────────────────────────────────────────────────────────────────────────────────────────────
🔸 ASSISTANT
────────────────────────────────────────────────────────────────────────────────────────────────────
  Here is a list of common household items (or families of items) that present the greatest hazards,
      together with the primary risks they pose:
  
    1. Cleaning Chemicals
       – Bleach, toilet bowl cleaners, drain openers, oven cleaners, pesticides, ammonia-based
      products
       – Risks: poisoning if ingested or mixed improperly (e.g. bleach + ammonia produces toxic
      chloramine gas); skin and eye burns; respiratory irritation
  
    2. Medications (Prescription & Over-the-Counter)
       – Painkillers (opioids, NSAIDs), cold/flu remedies, vitamins, dietary supplements
       – Risks: accidental overdose (especially in children or elderly), dangerous drug interactions,
      misuse
  
    3. Household Firearms & Ammunition
       – Handguns, rifles, shotguns, BB guns
       – Risks: accidental discharge leading to injury or death, unsecured weapons pose particular
      danger to children
  
    4. Sharp Objects
       – Kitchen knives, box cutters, scissors, chisels, razor blades
       – Risks: cuts and puncture wounds, bloodborne infection risk if wounds are deep
  
    5. Power Tools & Lawn/Garden Equipment
       – Chainsaws, circular saws, lawn mowers, hedge trimmers
       – Risks: lacerations, amputations, projectiles, hearing damage, electric shock
  
    6. Electrical Hazards & Appliances
       – Overloaded power strips, damaged extension cords, space heaters, hair dryers, toasters
       – Risks: shocks, electrocution, fire from overloaded circuits or faulty wiring
  
    7. Open Flames & Heat Sources
       – Candles, gas stoves, portable heaters, fireplaces, charcoal grills used indoors
       – Risks: burns, house fires, carbon monoxide or smoke inhalation
  
    8. Small Objects & Toys (Choking/Suffocation Risks)
       – Coins, buttons, beads, marbles, small batteries (button cells), balloons
       – Risks: choking in young children, battery ingestion causing chemical burns
  
    9. Plastic Bags & Sheeting
       – Grocery bags, dry-cleaner sacks, cling film
       – Risks: suffocation in infants and small children
  
    10. Furniture & Appliances that Can Tip Over
        – Bookcases, dressers, TVs, free-standing ranges
        – Risks: crushing injuries, head trauma—especially to toddlers who climb
  
    11. Ladders & Step Stools
        – Folding and extension ladders, kitchen step stools
        – Risks: falls from height, fractures, head injuries
  
    12. Household Fuels & Flammable Liquids
        – Gasoline, kerosene, lighter fluid, paint thinner, turpentine
        – Risks: fire, explosion, inhalation toxicity, skin absorption
  
    13. Personal Care Products
        – Nail polish remover (acetone), hydrogen peroxide, hair dyes, aerosol sprays
        – Risks: skin/eye irritation, flammability, inhalation hazards
  
    14. Carbon Monoxide Sources
        – Unvented gas heaters, furnaces, water heaters, fireplaces, portable generators used indoors
      or in attached garages
        – Risks: carbon monoxide poisoning (headache, dizziness, nausea, death)
  
    15. Water Hazards
        – Bathtubs, buckets, indoor fish tanks, toilets
        – Risks: drowning—young children can drown in just a few inches of water
  
    Basic Safety Tips to Reduce Risk:
    – Store chemicals, medications, and firearms locked and out of children’s reach.
    – Keep knives and sharp tools in secure drawers or mounted blocks.
    – Use outlet covers, inspect cords regularly, and avoid daisy-chaining power strips.
    – Supervise children around small objects, water, and open flames.
    – Anchor heavy furniture to walls and keep ladders on stable, even ground.
    – Install and test smoke alarms and carbon monoxide detectors regularly.
    – Follow manufacturer instructions, wear appropriate protective gear (gloves, goggles, hearing
      protection) when using chemicals or power tools.
    – Dispose of expired medications, batteries, and hazardous liquids at approved collection sites.
  💭 Reasoning
  Provider-generated reasoning summary (not raw chain-of-thought)
  [No reasoning summary was returned by the provider.]


────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────────────────────────────────────────────
                            Report generated at: 2026-10-08 06:23:58 UTC                            

JSON Generation

We can use the OpenAI Responses API with a JSON schema to produce structured JSON output. In this example, we define a simple JSON schema that describes a person with name and age properties.

For more information about structured outputs with OpenAI, see the OpenAI documentation.

Found default environment files: ['./.pyrit/.env.local']
Loaded environment file: ./.pyrit/.env.local
{
  "name": "Alice",
  "age": 30
}

Tool Use with Python Functions

In this example, we demonstrate how the OpenAI Responses API can be used to invoke a custom-defined Python function during a conversation. This is part of OpenAI’s support for “function calling”, where the model decides to call a registered function, and the application executes it and passes the result back into the conversation loop.

We define a simple tool called get_current_weather, which simulates weather information retrieval. The @tool decorator derives its schema from the function signature and keeps that definition paired with its implementation.

Names from tools and tool_providers must be unique and must not also appear in custom_functions or function declarations in extra_body_parameters. The existing custom_functions API can still use its matching raw declaration. Each model request, including retries and tool-result continuations, follows max_requests_per_minute. A model-request retry does not repeat completed tools.

The user prompt explicitly asks the model to use the get_current_weather function. Once the model responds with a function_call, PyRIT executes the function, wraps the output, and the conversation continues until a final answer is produced.

This showcases how agentic function execution works with PyRIT + OpenAI Responses API.

Found default environment files: ['./.pyrit/.env.local']
Loaded environment file: ./.pyrit/.env.local
0 | assistant: {"type":"function_call","call_id":"call_dAf2vfhHyNNHRtKX3yxd0hUR","name":"get_current_weather","arguments":"{\"location\":\"Boston, MA\",\"unit\":\"celsius\"}"}
1 | assistant: {"id":"rs_0019e1ed96613c71006ac7370dd1d88190945ecc896a3491c7","summary":[],"type":"reasoning","content":[],"encrypted_content":"gAAAAABqxzcWLw7atXnIjm_T8WhzsL1fL_KdEuEeaH6Kc_t3V3unQyI4zFEcB4Fud3fSHE5Dt4akPgZfLd0zZzmm7HV8wHAhwdicgzY9787bnVMpnbTqCNMPMI0oxci5Ky-dFjt4qynW-4Y5AOyCG8OwUqSvXOtCFskF7dHrjfDMgH4ZMK3IJYYab4yN41nrFpPCSAfGcuOUW_YdeRo9iRnK2xvjTrCYthT9cEYgFpmB4dwCMsjCslIJgRw4t2WWTOkDQk_DyZ4kt9vt10lN060rL7LM-uwicqbFRn7FGvrn0tuuH0IhLdw0-zlHidgCS3jnmb6GSEcY162rGdtUYyGTecC85Or71eCBDlJmDmMM5Tz3PkQE_DIcLdhthG1MhNX22zqjiuihyHGd94iaf2vP4ItCeG241RSb0_qbhnFaYS3ahC9F9eysLjc3kVNX9JK8OBXeRkKVtQvN0Q1eokxXndAJYN6moVryaHCd18wSfp5a9EzUQWpvTT3xBYBLDZlPqsv7E54UiEIefJgsJPrEhBoU1EMIc1qlqtyoGkZ_79OepMNeNdF7DMKaMtsWPc7RGBQL9pMhy4uWSWZTI6c-Uodzm544hYU0fhw9VzezC992zxBQfbXLQzX3fgaN5nhtcWS9zENzkvkz9qv5z_OyKSFtl1JMlLM-wncV1Ti0UKXiSEeqDCRY6rWEEd7RIJx9T0WAxMIHwPQCG7VBJualOHRAkO0TvyaRERuaK-Uv-Q1tzYmu1I_4nkK0dmoJXP0WNfwgPnCu8AKBHzgRI5n8bmRQ_d4rnIK8YMfnZgq1Evf5Z1U4uRv4kihvwbaagiTrcWPLlaAZUqKnys8Jm9b-o7ieUcYaVAdUJCaeDR7tWjn3oz_D2PBZefMKCGC6wdgXnZg_ZRAHnUgvbf1NhRLCwfFWjB0WB8tUBBYy8Et4DtprrrVgBvff8B5uIwSNSUMnBjRd2RLJ8qjJUkaC92hfdhbe15rY-bCIpb2ukbCe_SIPw6gMqu4G6klKP27kEGJOVGQaCPAFRlYgSYWssFst04WbxujkD-xkrzJIR6DXsmY9zQ_RZp9uuGh6JQmrRGgOIWik2-iQyEiY2l0x-y2V0bUzGnFxRqjVEa2U0k1x81lhFN75rEw41NQV38004GMXgKqQJa8WKsnhRhJr6qah9Vlm2dJJaDGlGKkpgqwpFeAMzS7YXG3U4jfqLHTePMw0hBGvnN8_CTVdfFnUZvQbJkr6pzmfsiz-zBmfJIDA6Vasl5vD_UTWNyttMOf0EOwQt6paLXVpMgc8O4Mooxg2ToOULIG0A6LzQSiV5uvL3crqPBSCS7LzHiiYvQt9rKuKlwz7dKQ2ixtRY738e8r4UW_j87vBiFg_1AMrP4H3PZvV-rvuOhS7V02U6PCbDiu6wmoWss3w87dhHlT1zg-kFsCAAmUigWROwSEYl0hOCcvC8aaSfNSxI_xbuuscyIaMtWf-errmlRgq2QZIp4IRWvFb9idIYQQJxNVxoU_TepKsdUTnPUak48MAvwVRVKUZNBV_UcK4EyE5xDONRvVEPTuHY_kIrw5qfLyRbIYBt8ut5yrr73q5UgIAb0iGMzlIZYXUEX0UIvGWVMV8uR12rMKeYSVnHscTkcawc-VyTJ7NW4u3gvc7bD7IZy4hpTCQJee_JfS2whNNjEeVLLIu5RN8bOHxKcuNzOh0yew_3Kt6lMqz3XltAgFvDCa4QRt2Y2Agt52m0mqX5q4wXBVkbiMG8c_oVU1ZjuPoSj2FFGTJBZim3ebT51HYP0GgpZnfOcul6p5cTZmpncvM7VnB939j3N1pQCDLnQyv9Q8uAbMAzc2_KOmUyBNvU2xi3GSMMDJYm4QZ-D0RBs-3ezdF7HkJ1KBD3Zsuw4fC45hQpqv0C51UDu4wEOSwvmwWm_AgpuebIwJd0gS6GzQWeT3k6ksLxooGAVxkoDjFIb2EU7jKAL-zNGD44bc5xMBSFLmt2FMvWp-bmlw7XV-o39_zrGC5NZRcanj99lqF3FLl8HoY7QPiJHvXQmccPA5vHqGanw7popZuM0nysvwQFqoI9GxoHfK32m6LlUHqAv3qfToDdvUN48KXutOVZd7fZBxz1jH4F6gWhlzRGC4Y5xRi7hrWazDDinhAwsKLX66HTyZp9BUh6T-f-FJ7Eq-7QpBf-mz5gZWw19j1OAgYd_dH6QaQhuD6qlQSQgFJp9RYcFfejeXT_ATVuYQnUgeW379X1klTx76eeHCxPJBp87u3vsiovRuAiVolB13UNJ5TzMSrL4miRLLRQsh_2ToNXijrdUsbkbkl_wUq8CziPaoC4v12J6gEkb5qUYDUT2Ji1a0vgAI-Z3oL9Wt9fUcUuN7YfNMv9oVRJMThVzYkhbTDvnryiSHVo4iSoVld8mdAm1QX8L27jBVZOHZhUI7kElkoZJsHwp56NEYBGJH1iamUfiQl36oa9L9lkei32FaPGXGlfqPTQQxPeizsaadtcwPbf-V06DEQ2zpBGOmXKcyGc5HsOQmWRxJJUs1moQew8jHWPEmTHLLj40cpqzido1q3r__pWkIfIRQxt9XeGKKsz6wZ3yNEilqZ5prw_HaubHrih-xt1TEJMd5Pc1Op5S2IDURgSZbmhJUPemwGkMj0jdVo6zMizTTaTeolJDSOYrZjjfQSZ-qXo0nmhLiNZ3GZ5ICkjjULTgzmsUBUpqwYOThziEmkZzaE03viIydXu_mvK5sLbYOCeRdZRoy4J__nObAWgY0xjlaSuHjeTNGTBdk-rV2tCZY4MEPOQl9L2szScIDTecj1o629PZSHFi64is6QaGwFNRbqZEmgDUiEIVzCV13bd4TH2Hq1PA3Y7a17WGP5iS12ZV0jtXBs8US5azIHz0pafONgeuPjLCi9piIuoPa-g0nQVTlq7Olh5-AEV1UyeVo-fr7YVLzjcFMBM8Kzr1xay_wJHN_uYrVQ-FB4S6PlzTMAwaRB7fP4zgXjc2Hnq0qWJgY94eQRuFGkiJvWX697TYzVr1Lwe3HjIazy5E9F-w_lzIjmA2nbraaubgDKfHZRUdgv8eZ8nED-MxX-a9WDUbPsnZ_jm6myZsXZhij3Kn7u4_fuVkjqlZXHVzEGOxvQ9kRLF0LsYoqOFGJ46zl5nCh7PNuhImRAHhakDqVHvGaB2tHlcqxswqZEjQXioEeWtKmo5UCmm8iI1qT9w5yBhBRR2iQA5vNNTZOOGQpQYcdG0L9VOIpqSRn5ekMupDoAz2g3arsy3DKIajuPl3VHoeG-Rqsf1fZhpLV40REKnScarMPz6Y0gVe3YgvbRUMKBfTVARnxa4tWMoYHKdkUDFp05jgMS5rfY89cNZ1PxPS2sa6xuhJy1E1s-M6cxbqh7u_MgtgN8pdqR0Uq-ttHzX3-YISpRRtpFFFXhKye5UoE-qvSBUjcUNGuR5jmL1d8lq6h71qz8J1OvpoTSx2or5SZBwnjJx6rtG5JaSguhwmRE-BA4tIwH8K6XUfMbe9-ne72RmzLhZn-2OGr4maldw71jkGdcIWfCLFVANt7skie3RhfDKpfXev3jwQX8AYg_wK9_Q3dd1PFPVdTB7CWsXR-QZFSYkWg5GwHhFuD5hFqnOI0_6iWRz7Q56mE3k8m0cpigK8TnodhoWSpXPwqevgP6gKd2h9LNj44gp-E497CJVUAOPkaJgXPNomGw121Z6JfnQxu-JM-8KUY6ADK1Pu0i6f_k-jYsV2T2V6vsAs-fWBNNa-nSK0t0YfstHHgJTNk8TaDNbLaW0Y4LtC_c2U68Smbu-EAqD0RaAHICENElVm7aNHacQvqpFczcSRveLw8KDcOllHHVGtEDS6mqsg_T0dYa8Ayu2OOk69X8Edqjx_IKuhAuFL_ZwgdQdG0Mq3PUl-EJURKJrdgvZQRdppWKuJRTGzgnrGCfIhaeZtPiWW8g81FIJfH5yg_J7JkPABzw2SGI7inVcAByAhd9Eg3L1A3Gk2is-cKxKfOo0KOhwq8PzMrkUXKVEpFfQFnXzbeqhn-4EqwFR_vbXTe6pjFN0qZqRYpHn4HFNLL04NGt6NcTYENBtvEuOEEnGJ__p8fU2N0MNwqBijM4EH_3aaWtDjiSHYidMtRzFiqCdUj62c7jwAu0_rF-nVhuf3bAX8ov1aCLFHp5Z8-cihy_Bdl-NfKuFBUSg0KK3FVpnxDguqO2jQSL5QityOcG0X2DkoHc9a4XYVSkNel7ri_6GgSeO-J8RlFwfyhH-w32uQrckzilKW0cDXkfF_Pn_GXl8eYcV2fqwuPYtoqwo5Bq-XXzXpf-N3FeXG-vFCY3TkgSiG6oQtz1_xzGIG3p6DXe4S-nl4VXcLLGndBWN04kTUK_yHXe3XkwUP2AnrxbjSJzyNGGVz0yXCFfWAhp3Z_UQxW5FX_wBepj5XuwHBTZMgur-7Y1M3UE-NSdEBM1883AdrdHlF9S8cnPrWXBAdUsJQxdAxd9WBkQjtbcjifNlxvJ0EjbJWNOlPS4Ky76OqUZArZ1KbGZ7qKqYrSJX9LqvB1Loq6_JS6BwT9oAtwmOjtm2P6Rpbrs4-cpxUDeFXvfmbGCwxqMAyBNRMyF6sgtyZegviD7uFj_pho8A_F28u8IMV5huRkHIUr92U57Nw26wcLNTSFHHxaVZTCTjTTtkAtIFtTSFElf7hgY1oRbtVqSsfuNQAO7QvfUBsQCswGI647l4aQHwrm33yX7ePNDkXI9MRVwiWDh_a4qVm_Rspp7BVRdMBLfo5MjFVDh7_96IM5xIBImQHLcqODJXr9th_YhEKC9MvDc-NLbtKnllRNefvmjXJUwaDywCCb9dLn9mMww0_TOtMD7spnLmni4ywk8Iz0cVReZ6nl7nScWFioNVv2v4xHieosUR5hEQKP5Cd4UqovJIvkMTcvezyTt8yeBZlL7x8kKB3shof0cIjgDM4KziGqxC0R5t31NVWKGsBSLxVYRJxCUDHB19KFjs8gOZ5AwzhkNOQm2HwP3IDFVM1IlFyiAPdznK-RYVjTPuHr_eQgJXxgJzWQsl7QV3hN1Yuph30MQJ-ropoHiMLoQ7LOPXl8UStW-77ySfBj0OV1FCkJwbH57FmRlEvaXs0KgFp5HBV8zgidFmdgxflgZHermG948siRb11AmAZsxVWEabyWeZMpoE2AhFbQloyLmbmBiVInaMb-HBDudh3wqhoM5LVJJwcb73uwz7BV7iYjzjxocB8csLkkS_jiHn0UZHPbfsrub1r7O-TzGQim1sdd8JmgieioDjW0gj_kVB2sUyN0dH1Cib10Y2hEXRQnLf7pR2jcWK_Ee1TO99QE_DfOBY_p0LcqDhPT7qZGwm-JHJNeHbbD1WNYMzxWn7C90lsZ15ilPQfPCaK9khPK6S8UFZR3ecuQ1er6PezltEtuNNRbGiWtpz-xs1a50vesGLd21s8d4egzCYenC6d3bb2Anof66BAqI3ZLDNf8a5-_o_BgfsDTDpF2ETeh2pm7X0AI7TB7T6XqDDOaHm_TolgvwLbCsmjJAcjXQGHgcG2NOrPjbgN3t5dwsqCkKg_zr6OqHuJquBJTEcr89X5Oe5bzV3ud6bla1479UgkjpUpblulO6T0Qhjc8MJ90euqlXdRbu8AL47MKOFyiAgbel88Eq86rVJ7i31ZPefbdVcSP4zfh5LKYmYXrIWG4d0WKFQ1ou_OzCmyf4p29RQUw48x3uXT7BaoDfHN9acH1Uw-6EKKmb7q6ZIJXoO4LN4quY5frZUmLkldIZih4y4cG7SwklFoz76ni-pHDEd6B5okNvNbCK7tD_Q5_sWiVri7DLVHsQLRacqCWVXm2Z7d29SXgaBq23IEFfU7zy0B09nxq9TcbdFo74tBhxjoP_xj6sGLMR4EkiuI2o-gUDy4mdUCp0pfCpW9zKXetlRDx1ihRKGGQClclBa9O_fIz2J5f9kOYVK04g14WUjZfHSu94p0a0k0vFEftHll6WAMZN1czuMAZXW19xDVX4oSKs8iaEZfq0N82-gIAHEH92YpE80HQDpEsg_l5E9uJhpz18dDfe-2h5zhLLz9LdTagxhBYVqRpgykh94npxN6dB-xIaPll3jd5UsVA1EDxSvNaYpUiK_eTUoHAsE9OITF1c5_pbGpfTM-keCpowC8mZT-s6k-dkU90Q2XocRBtR2RSoE3Rj2RLdsVphbfHRsMtyol2AJv7_itq7kRwqkH6rsZkm-D1zgTgq6_aksbqvqjeeznYzPBPFN2wZBO1nrOW_9PKFSHWuXNQdRHibMQjA3kFIeUAnlwFJUkAHIreQx1FfZkTDE-9JGvEv4IuBtLS_0x-wnfgaSnsqbNXElOXcoUnEYd7KHJIDaIal_aHhhjNm7L0dGRtOQwCM-LAgzwH8RlYZDvwdNS3RgdxQHE7D6YI1dk2eoPZtXGGgFt7wKbPsblSdL4Vmso-PjCKIjrD6u4EXS_dL05X7-NFsqKHtCn_tCYt7EkIS3bFtFPWDwOep1if35st0Fci2WSMTr70uC1Pveqcq44MDjxDDSopXLVrg2SmNXpcAKiX-v8sZdyTh5BYDv3F-v_GTuLcZW1kfD6wawxji6x0tOnx2n4dhaqogbJiW3uOf7Z32zShgKAEz5-OeH17LoxvKQTsWjF-mwL5a_COKIapvDusZexYn28uGvSa_NG8CYk0sLHwMFmWhCkY2Xaa02p2LcsAlY_86bQgu6PHvHbvWlKeyMxVDjnvmZFU-o1j05HvodoL-TCD1R3VmoPnzMEshS4YMcZC2UPJ7APf4-6gwlj-KgpanYpCR9patjHz_YrLNVRjApSrfe5S3zN-NQ7iRkvRPhmvtu9khiH1RIQ9_TI8iR9IL2lP3Te3WrJYcC1gmWlUTieRNW1MtOxxuIDXNIXO3aDlmab8XfTVpSkS0rxilou66G36gr1aqOUIiSNVXMBvfWfGHMtkuLTC7IWJzFzVVVX8bHZOOmzkkVein846Tfbr0_qgyA9FiAJrNO7_IFxkgVx5R2eG-uZx5uP3og5xG2OMvm8ZaKR01mMmqqGeTnPlcMzfvDakC5MndzVXx2gt0shtlIyetZhf_79Sw0OU7Fc6f9BszwBTRKV9q-8H2wmAbK8-rISzVdBuR8SS8fE4_lMKdj2L2T-o1nLZfByG_40nhR0mDFQWZBFihqvUGViMekkG0IFOm6N4iXr3usr6C9HKlEsWRY2_SJ1bWcm-tNPcUt0VaJ3cL2X5DbtenSwQ9V62Ar4Vk1y43OUHtvmywL8bfR7W7zBOZM9NuHRW-pqbfcM7sN_HBkCrxIX0jbQ5qQE5dAC_pWsDdUqcyC9NaqznxFWNxObGk0M8OZcRx6ZJeo2CTq_RSQH_rnRT6PFhfMsR5TAbjdxdtmjtDiCXowX_jnet0E1fvw6S1EUAh2fsh-Hi0Q0X0akkr59j2agiAqrzM3bWIZ8KM_AHvzcU3jNldH3urUCwjQNwwzhXu0iqxRbccAZ28uQCosYO7N8oiZ_C8uPKUaAqxuYt3hW1dQugrIgFQjM82C5ntYjaNKWJhj9o_A-3DZ3qs7Rz4WwSar_hZYrHWDen7vkDKUirXdsU68FNjBEUtP5M45v9S--qGhZgt_k1ArVQ4cfnzhZkDhXbpdV_HuAx_mtlGXmszNa56e5Kt_8-8cZmGE1lcivqqRnLMOpyyK72XjhG7lrvdlcIw4er8E1dDjUHiiM8x28w_r_NYq2vui3xYfLK8Bi3JMty2op5WlIbniiDItW09zsGtaO_kVjfOa27FxXeboAUUqCoWhcdVKxejBJ7XP5dc-osrt9tgIr2ZDRocx8WJZnnIe2L68bhsHqGLxv8IM8FcbnnzZ57S5W0af3A4Atw8G_BZHjA6iR5vz14hgfBG2Q6P27GtFWhahEMhbDitB4reTXtvQYB497brTKHuPerNwJ5GmrlP5j5dg3BddC02nHKe4lbK98HcLJYrMKpg6Mc7jHudX1SU1K0wgejcRC6euN6Kv1GLOcofBzC_xpMBAdFVxAmkHjlCPlXkA9YAr6ZSv--a1AocLveH9Q81GTk=","status":null}
0 | tool: {"type":"function_call_output","call_id":"call_dAf2vfhHyNNHRtKX3yxd0hUR","output":"{\"weather\":\"Sunny\",\"temp_c\":22,\"location\":\"Boston, MA\",\"unit\":\"celsius\"}"}
0 | assistant: The current weather in Boston, MA is Sunny with a temperature of 22°C.

Using the Built-in Web Search Tool

In this example, we use a built-in PyRIT helper function web_search_tool() to register a web search tool with OpenAI’s Responses API. This allows the model to issue web search queries during a conversation to supplement its responses with fresh information.

The tool is added to the extra_body_parameters passed into the OpenAIResponseTarget. As before, tool_choice="auto" enables the model to decide when to invoke the tool.

The user prompt asks for a recent positive news story — an open-ended question that may prompt the model to issue a web search tool call. PyRIT will automatically execute the tool and return the output to the model as part of the response.

This example demonstrates how retrieval-augmented generation (RAG) can be enabled in PyRIT through OpenAI’s Responses API and integrated tool schema.

NOTE that web search is NOT supported through an Azure OpenAI endpoint, only through the OpenAI platform endpoint (i.e. api.openai.com)

Found default environment files: ['./.pyrit/.env.local']
Loaded environment file: ./.pyrit/.env.local
0 | assistant: {"type":"web_search_call","id":"ws_07530da5dde8a698006ac7371f313c8195a3135f2aace4eae5"}
1 | assistant: Here is a positive news story from today, October 8, 2026: Atlantic bluefin tuna have returned to UK waters after decades of absence. Conservation efforts, including international catch limits and habitat protection, are credited with this comeback, which is part of wider gains for tigers and green sea turtles globally, as highlighted in WWF’s Living Planet Report 2026 [The Good News Brief](https://thegoodnewsbrief.com/).