openai-agents 0.2.0__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of openai-agents might be problematic. Click here for more details.
- {openai_agents-0.2.0 → openai_agents-0.2.1}/PKG-INFO +3 -3
- openai_agents-0.2.1/docs/realtime/guide.md +143 -0
- openai_agents-0.2.1/docs/realtime/quickstart.md +175 -0
- openai_agents-0.2.1/docs/ref/realtime/agent.md +3 -0
- openai_agents-0.2.1/docs/ref/realtime/config.md +41 -0
- openai_agents-0.2.1/docs/ref/realtime/events.md +36 -0
- openai_agents-0.2.1/docs/ref/realtime/runner.md +3 -0
- openai_agents-0.2.1/docs/ref/realtime/session.md +3 -0
- openai_agents-0.2.1/examples/realtime/app/README.md +40 -0
- openai_agents-0.2.1/examples/realtime/app/server.py +172 -0
- openai_agents-0.2.1/examples/realtime/app/static/app.js +467 -0
- openai_agents-0.2.1/examples/realtime/app/static/index.html +295 -0
- openai_agents-0.2.1/examples/realtime/cli/demo.py +253 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/mkdocs.yml +12 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/pyproject.toml +3 -3
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/agent.py +1 -1
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/agent_output.py +2 -2
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/guardrail.py +1 -1
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/handoffs.py +32 -14
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/mcp/server.py +39 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/mcp/util.py +11 -3
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/models/chatcmpl_converter.py +1 -1
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/models/chatcmpl_stream_handler.py +134 -43
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/models/openai_responses.py +1 -1
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/realtime/__init__.py +3 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/realtime/agent.py +10 -1
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/realtime/config.py +60 -0
- openai_agents-0.2.1/src/agents/realtime/handoffs.py +165 -0
- openai_agents-0.2.1/src/agents/realtime/items.py +184 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/realtime/openai_realtime.py +186 -100
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/realtime/session.py +38 -5
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/mcp/helpers.py +15 -1
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/mcp/test_mcp_tracing.py +3 -3
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/mcp/test_mcp_util.py +54 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/models/test_litellm_chatcompletions_stream.py +131 -17
- openai_agents-0.2.1/tests/realtime/test_conversion_helpers.py +375 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/realtime/test_openai_realtime.py +1 -0
- openai_agents-0.2.1/tests/realtime/test_realtime_handoffs.py +96 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/realtime/test_session.py +27 -29
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/realtime/test_tracing.py +28 -38
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_handoff_tool.py +5 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_openai_chatcompletions_stream.py +154 -17
- {openai_agents-0.2.0 → openai_agents-0.2.1}/uv.lock +36 -9
- openai_agents-0.2.0/examples/realtime/demo.py +0 -115
- openai_agents-0.2.0/src/agents/realtime/items.py +0 -91
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.github/ISSUE_TEMPLATE/model_provider.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.github/workflows/docs.yml +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.github/workflows/issues.yml +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.github/workflows/publish.yml +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.github/workflows/tests.yml +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.gitignore +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.prettierrc +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.vscode/launch.json +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/.vscode/settings.json +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/AGENTS.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/CLAUDE.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/LICENSE +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/Makefile +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/agents.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/assets/images/favicon-platform.svg +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/assets/images/graph.png +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/assets/images/mcp-tracing.jpg +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/assets/images/orchestration.png +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/assets/logo.svg +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/config.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/context.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/examples.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/guardrails.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/handoffs.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/index.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/agents.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/config.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/context.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/examples.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/guardrails.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/handoffs.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/index.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/mcp.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/models/index.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/models/litellm.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/multi_agent.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/quickstart.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/repl.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/results.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/running_agents.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/streaming.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/tools.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/tracing.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/visualization.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/voice/pipeline.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/voice/quickstart.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ja/voice/tracing.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/mcp.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/models/index.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/models/litellm.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/multi_agent.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/quickstart.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/agent.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/agent_output.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/exceptions.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/extensions/handoff_filters.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/extensions/handoff_prompt.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/extensions/litellm.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/function_schema.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/guardrail.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/handoffs.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/index.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/items.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/lifecycle.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/mcp/server.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/mcp/util.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/memory.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/model_settings.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/models/interface.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/models/openai_chatcompletions.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/models/openai_responses.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/repl.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/result.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/run.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/run_context.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/stream_events.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/tool.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/tracing/create.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/tracing/index.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/tracing/processor_interface.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/tracing/processors.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/tracing/scope.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/tracing/setup.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/tracing/span_data.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/tracing/spans.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/tracing/traces.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/tracing/util.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/usage.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/voice/events.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/voice/exceptions.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/voice/input.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/voice/model.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/voice/models/openai_provider.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/voice/models/openai_stt.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/voice/models/openai_tts.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/voice/pipeline.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/voice/pipeline_config.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/voice/result.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/voice/utils.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/ref/voice/workflow.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/release.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/repl.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/results.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/running_agents.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/scripts/translate_docs.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/sessions.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/streaming.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/stylesheets/extra.css +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/tools.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/tracing.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/visualization.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/voice/pipeline.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/voice/quickstart.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/docs/voice/tracing.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/agent_patterns/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/agent_patterns/agents_as_tools.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/agent_patterns/deterministic.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/agent_patterns/forcing_tool_use.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/agent_patterns/input_guardrails.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/agent_patterns/llm_as_a_judge.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/agent_patterns/output_guardrails.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/agent_patterns/parallelization.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/agent_patterns/routing.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/agent_patterns/streaming_guardrails.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/agent_lifecycle_example.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/dynamic_system_prompt.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/hello_world.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/hello_world_jupyter.ipynb +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/lifecycle_example.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/local_image.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/media/image_bison.jpg +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/non_strict_output_type.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/previous_response_id.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/prompt_template.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/remote_image.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/session_example.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/stream_items.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/stream_text.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/basic/tools.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/customer_service/main.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/financial_research_agent/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/financial_research_agent/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/financial_research_agent/agents/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/financial_research_agent/agents/financials_agent.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/financial_research_agent/agents/planner_agent.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/financial_research_agent/agents/risk_agent.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/financial_research_agent/agents/search_agent.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/financial_research_agent/agents/verifier_agent.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/financial_research_agent/agents/writer_agent.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/financial_research_agent/main.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/financial_research_agent/manager.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/financial_research_agent/printer.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/handoffs/message_filter.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/handoffs/message_filter_streaming.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/hosted_mcp/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/hosted_mcp/approvals.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/hosted_mcp/simple.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/filesystem_example/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/filesystem_example/main.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/filesystem_example/sample_files/favorite_books.txt +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/filesystem_example/sample_files/favorite_cities.txt +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/filesystem_example/sample_files/favorite_songs.txt +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/git_example/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/git_example/main.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/prompt_server/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/prompt_server/main.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/prompt_server/server.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/sse_example/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/sse_example/main.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/sse_example/server.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/streamablehttp_example/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/streamablehttp_example/main.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/mcp/streamablehttp_example/server.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/model_providers/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/model_providers/custom_example_agent.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/model_providers/custom_example_global.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/model_providers/custom_example_provider.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/model_providers/litellm_auto.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/model_providers/litellm_provider.py +0 -0
- {openai_agents-0.2.0/examples/realtime → openai_agents-0.2.1/examples/realtime/cli}/ui.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/reasoning_content/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/reasoning_content/main.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/reasoning_content/runner_example.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/agents/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/agents/planner_agent.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/agents/search_agent.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/agents/writer_agent.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/main.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/manager.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/printer.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/sample_outputs/product_recs.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/sample_outputs/product_recs.txt +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/sample_outputs/vacation.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/research_bot/sample_outputs/vacation.txt +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/tools/code_interpreter.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/tools/computer_use.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/tools/file_search.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/tools/image_generator.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/tools/web_search.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/voice/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/voice/static/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/voice/static/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/voice/static/main.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/voice/static/util.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/voice/streamed/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/voice/streamed/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/voice/streamed/main.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/examples/voice/streamed/my_workflow.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/_config.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/_debug.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/_run_impl.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/computer.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/exceptions.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/extensions/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/extensions/handoff_filters.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/extensions/handoff_prompt.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/extensions/models/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/extensions/models/litellm_model.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/extensions/models/litellm_provider.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/extensions/visualization.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/function_schema.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/items.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/lifecycle.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/logger.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/mcp/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/memory/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/memory/session.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/model_settings.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/models/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/models/_openai_shared.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/models/chatcmpl_helpers.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/models/fake_id.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/models/interface.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/models/multi_provider.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/models/openai_chatcompletions.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/models/openai_provider.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/prompts.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/py.typed +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/realtime/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/realtime/events.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/realtime/model.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/realtime/model_events.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/realtime/model_inputs.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/realtime/runner.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/repl.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/result.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/run.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/run_context.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/stream_events.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/strict_schema.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tool.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tool_context.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tracing/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tracing/create.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tracing/logger.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tracing/processor_interface.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tracing/processors.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tracing/provider.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tracing/scope.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tracing/setup.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tracing/span_data.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tracing/spans.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tracing/traces.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/tracing/util.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/usage.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/util/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/util/_coro.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/util/_error_tracing.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/util/_json.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/util/_pretty_print.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/util/_transforms.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/util/_types.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/version.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/events.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/exceptions.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/imports.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/input.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/model.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/models/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/models/openai_model_provider.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/models/openai_stt.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/models/openai_tts.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/pipeline.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/pipeline_config.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/result.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/utils.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/src/agents/voice/workflow.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/README.md +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/conftest.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/fake_model.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/fastapi/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/fastapi/streaming_app.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/fastapi/test_streaming_context.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/mcp/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/mcp/conftest.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/mcp/test_caching.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/mcp/test_connect_disconnect.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/mcp/test_prompt_server.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/mcp/test_runner_calls_mcp.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/mcp/test_server_errors.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/mcp/test_tool_filtering.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/model_settings/test_serialization.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/models/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/models/conftest.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/models/test_kwargs_functionality.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/models/test_litellm_extra_body.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/models/test_map.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/realtime/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/realtime/test_agent.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/realtime/test_item_parsing.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/realtime/test_model_events.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/realtime/test_runner.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_agent_config.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_agent_hooks.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_agent_prompt.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_agent_runner.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_agent_runner_streamed.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_agent_tracing.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_cancel_streaming.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_computer_action.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_config.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_doc_parsing.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_extension_filters.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_extra_headers.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_function_schema.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_function_tool.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_function_tool_decorator.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_global_hooks.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_guardrails.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_items_helpers.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_max_turns.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_openai_chatcompletions.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_openai_chatcompletions_converter.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_openai_responses_converter.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_output_tool.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_pretty_print.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_reasoning_content.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_repl.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_responses.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_responses_tracing.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_result_cast.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_run.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_run_config.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_run_error_details.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_run_step_execution.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_run_step_processing.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_session.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_session_exceptions.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_strict_schema.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_tool_choice_reset.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_tool_converter.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_tool_use_behavior.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_trace_processor.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_tracing.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_tracing_errors.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_tracing_errors_streamed.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_usage.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/test_visualization.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/testing_processor.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/tracing/test_processor_api_key.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/voice/__init__.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/voice/conftest.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/voice/fake_models.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/voice/helpers.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/voice/test_input.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/voice/test_openai_stt.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/voice/test_openai_tts.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/voice/test_pipeline.py +0 -0
- {openai_agents-0.2.0 → openai_agents-0.2.1}/tests/voice/test_workflow.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openai-agents
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: OpenAI Agents SDK
|
|
5
5
|
Project-URL: Homepage, https://openai.github.io/openai-agents-python/
|
|
6
6
|
Project-URL: Repository, https://github.com/openai/openai-agents-python
|
|
@@ -20,8 +20,8 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
20
20
|
Classifier: Typing :: Typed
|
|
21
21
|
Requires-Python: >=3.9
|
|
22
22
|
Requires-Dist: griffe<2,>=1.5.6
|
|
23
|
-
Requires-Dist: mcp<2,>=1.
|
|
24
|
-
Requires-Dist: openai<2,>=1.
|
|
23
|
+
Requires-Dist: mcp<2,>=1.11.0; python_version >= '3.10'
|
|
24
|
+
Requires-Dist: openai<2,>=1.96.1
|
|
25
25
|
Requires-Dist: pydantic<3,>=2.10
|
|
26
26
|
Requires-Dist: requests<3,>=2.0
|
|
27
27
|
Requires-Dist: types-requests<3,>=2.0
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Guide
|
|
2
|
+
|
|
3
|
+
This guide provides an in-depth look at building voice-enabled AI agents using the OpenAI Agents SDK's realtime capabilities.
|
|
4
|
+
|
|
5
|
+
!!! warning "Beta feature"
|
|
6
|
+
Realtime agents are in beta. Expect some breaking changes as we improve the implementation.
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Realtime agents allow for conversational flows, processing audio and text inputs in real time and responding with realtime audio. They maintain persistent connections with OpenAI's Realtime API, enabling natural voice conversations with low latency and the ability to handle interruptions gracefully.
|
|
11
|
+
|
|
12
|
+
## Architecture
|
|
13
|
+
|
|
14
|
+
### Core Components
|
|
15
|
+
|
|
16
|
+
The realtime system consists of several key components:
|
|
17
|
+
|
|
18
|
+
- **RealtimeAgent**: An agent, configured wiht instructions, tools and handoffs.
|
|
19
|
+
- **RealtimeRunner**: Manages configuration. You can call `runner.run()` to get a session.
|
|
20
|
+
- **RealtimeSession**: A single interaction session. You typically create one each time a user starts a conversation, and keep it alive until the conversation is done.
|
|
21
|
+
- **RealtimeModel**: The underlying model interface (typically OpenAI's WebSocket implementation)
|
|
22
|
+
|
|
23
|
+
### Session flow
|
|
24
|
+
|
|
25
|
+
A typical realtime session follows this flow:
|
|
26
|
+
|
|
27
|
+
1. **Create your RealtimeAgent(s)** with instructions, tools and handoffs.
|
|
28
|
+
2. **Set up a RealtimeRunner** with the agent and configuration options
|
|
29
|
+
3. **Start the session** using `await runner.run()` which returns a RealtimeSession.
|
|
30
|
+
4. **Send audio or text messages** to the session using `send_audio()` or `send_message()`
|
|
31
|
+
5. **Listen for events** by iterating over the session - events include audio output, transcripts, tool calls, handoffs, and errors
|
|
32
|
+
6. **Handle interruptions** when users speak over the agent, which automatically stops current audio generation
|
|
33
|
+
|
|
34
|
+
The session maintains the conversation history and manages the persistent connection with the realtime model.
|
|
35
|
+
|
|
36
|
+
## Agent configuration
|
|
37
|
+
|
|
38
|
+
RealtimeAgent works similarly to the regular Agent class with some key differences. For full API details, see the [`RealtimeAgent`][agents.realtime.agent.RealtimeAgent] API reference.
|
|
39
|
+
|
|
40
|
+
Key differences from regular agents:
|
|
41
|
+
|
|
42
|
+
- Model choice is configured at the session level, not the agent level.
|
|
43
|
+
- No structured output support (`outputType` is not supported).
|
|
44
|
+
- Voice can be configured per agent but cannot be changed after the first agent speaks.
|
|
45
|
+
- All other features like tools, handoffs, and instructions work the same way.
|
|
46
|
+
|
|
47
|
+
## Session configuration
|
|
48
|
+
|
|
49
|
+
### Model settings
|
|
50
|
+
|
|
51
|
+
The session configuration allows you to control the underlying realtime model behavior. You can configure the model name (such as `gpt-4o-realtime-preview`), voice selection (alloy, echo, fable, onyx, nova, shimmer), and supported modalities (text and/or audio). Audio formats can be set for both input and output, with PCM16 being the default.
|
|
52
|
+
|
|
53
|
+
### Audio configuration
|
|
54
|
+
|
|
55
|
+
Audio settings control how the session handles voice input and output. You can configure input audio transcription using models like Whisper, set language preferences, and provide transcription prompts to improve accuracy for domain-specific terms. Turn detection settings control when the agent should start and stop responding, with options for voice activity detection thresholds, silence duration, and padding around detected speech.
|
|
56
|
+
|
|
57
|
+
## Tools and Functions
|
|
58
|
+
|
|
59
|
+
### Adding Tools
|
|
60
|
+
|
|
61
|
+
Just like regular agents, realtime agents support function tools that execute during conversations:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from agents import function_tool
|
|
65
|
+
|
|
66
|
+
@function_tool
|
|
67
|
+
def get_weather(city: str) -> str:
|
|
68
|
+
"""Get current weather for a city."""
|
|
69
|
+
# Your weather API logic here
|
|
70
|
+
return f"The weather in {city} is sunny, 72°F"
|
|
71
|
+
|
|
72
|
+
@function_tool
|
|
73
|
+
def book_appointment(date: str, time: str, service: str) -> str:
|
|
74
|
+
"""Book an appointment."""
|
|
75
|
+
# Your booking logic here
|
|
76
|
+
return f"Appointment booked for {service} on {date} at {time}"
|
|
77
|
+
|
|
78
|
+
agent = RealtimeAgent(
|
|
79
|
+
name="Assistant",
|
|
80
|
+
instructions="You can help with weather and appointments.",
|
|
81
|
+
tools=[get_weather, book_appointment],
|
|
82
|
+
)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Handoffs
|
|
86
|
+
|
|
87
|
+
### Creating Handoffs
|
|
88
|
+
|
|
89
|
+
Handoffs allow transferring conversations between specialized agents.
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from agents.realtime import realtime_handoff
|
|
93
|
+
|
|
94
|
+
# Specialized agents
|
|
95
|
+
billing_agent = RealtimeAgent(
|
|
96
|
+
name="Billing Support",
|
|
97
|
+
instructions="You specialize in billing and payment issues.",
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
technical_agent = RealtimeAgent(
|
|
101
|
+
name="Technical Support",
|
|
102
|
+
instructions="You handle technical troubleshooting.",
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
# Main agent with handoffs
|
|
106
|
+
main_agent = RealtimeAgent(
|
|
107
|
+
name="Customer Service",
|
|
108
|
+
instructions="You are the main customer service agent. Hand off to specialists when needed.",
|
|
109
|
+
handoffs=[
|
|
110
|
+
realtime_handoff(billing_agent, tool_description="Transfer to billing support"),
|
|
111
|
+
realtime_handoff(technical_agent, tool_description="Transfer to technical support"),
|
|
112
|
+
]
|
|
113
|
+
)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Event handling
|
|
117
|
+
|
|
118
|
+
The session streams events that you can listen to by iterating over the session object. Events include audio output chunks, transcription results, tool execution start and end, agent handoffs, and errors. Key events to handle include:
|
|
119
|
+
|
|
120
|
+
- **audio**: Raw audio data from the agent's response
|
|
121
|
+
- **audio_end**: Agent finished speaking
|
|
122
|
+
- **audio_interrupted**: User interrupted the agent
|
|
123
|
+
- **tool_start/tool_end**: Tool execution lifecycle
|
|
124
|
+
- **handoff**: Agent handoff occurred
|
|
125
|
+
- **error**: Error occurred during processing
|
|
126
|
+
|
|
127
|
+
For complete event details, see [`RealtimeSessionEvent`][agents.realtime.events.RealtimeSessionEvent].
|
|
128
|
+
|
|
129
|
+
## Guardrails
|
|
130
|
+
|
|
131
|
+
Only output guardrails are supported for realtime agents. These guardrails are debounced and run periodically (not on every word) to avoid performance issues during real-time generation. The default debounce length is 100 characters, but this is configurable.
|
|
132
|
+
|
|
133
|
+
When a guardrail is triggered, it generates a `guardrail_tripped` event and can interrupt the agent's current response. The debounce behavior helps balance safety with real-time performance requirements. Unlike text agents, realtime agents do **not** raise an Exception when guardrails are tripped.
|
|
134
|
+
|
|
135
|
+
## Audio processing
|
|
136
|
+
|
|
137
|
+
Send audio to the session using [`session.send_audio(audio_bytes)`][agents.realtime.session.RealtimeSession.send_audio] or send text using [`session.send_message()`][agents.realtime.session.RealtimeSession.send_message].
|
|
138
|
+
|
|
139
|
+
For audio output, listen for `audio` events and play the audio data through your preferred audio library. Make sure to listen for `audio_interrupted` events to stop playback immediately and clear any queued audio when the user interrupts the agent.
|
|
140
|
+
|
|
141
|
+
## Examples
|
|
142
|
+
|
|
143
|
+
For complete working examples, check out the [examples/realtime directory](https://github.com/openai/openai-agents-python/tree/main/examples/realtime) which includes demos with and without UI components.
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Quickstart
|
|
2
|
+
|
|
3
|
+
Realtime agents enable voice conversations with your AI agents using OpenAI's Realtime API. This guide walks you through creating your first realtime voice agent.
|
|
4
|
+
|
|
5
|
+
!!! warning "Beta feature"
|
|
6
|
+
Realtime agents are in beta. Expect some breaking changes as we improve the implementation.
|
|
7
|
+
|
|
8
|
+
## Prerequisites
|
|
9
|
+
|
|
10
|
+
- Python 3.9 or higher
|
|
11
|
+
- OpenAI API key
|
|
12
|
+
- Basic familiarity with the OpenAI Agents SDK
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
If you haven't already, install the OpenAI Agents SDK:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install openai-agents
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Creating your first realtime agent
|
|
23
|
+
|
|
24
|
+
### 1. Import required components
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
import asyncio
|
|
28
|
+
from agents.realtime import RealtimeAgent, RealtimeRunner
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 2. Create a realtime agent
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
agent = RealtimeAgent(
|
|
35
|
+
name="Assistant",
|
|
36
|
+
instructions="You are a helpful voice assistant. Keep your responses conversational and friendly.",
|
|
37
|
+
)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 3. Set up the runner
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
runner = RealtimeRunner(
|
|
44
|
+
starting_agent=agent,
|
|
45
|
+
config={
|
|
46
|
+
"model_settings": {
|
|
47
|
+
"model_name": "gpt-4o-realtime-preview",
|
|
48
|
+
"voice": "alloy",
|
|
49
|
+
"modalities": ["text", "audio"],
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 4. Start a session
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
async def main():
|
|
59
|
+
# Start the realtime session
|
|
60
|
+
session = await runner.run()
|
|
61
|
+
|
|
62
|
+
async with session:
|
|
63
|
+
# Send a text message to start the conversation
|
|
64
|
+
await session.send_message("Hello! How are you today?")
|
|
65
|
+
|
|
66
|
+
# The agent will stream back audio in real-time (not shown in this example)
|
|
67
|
+
# Listen for events from the session
|
|
68
|
+
async for event in session:
|
|
69
|
+
if event.type == "response.audio_transcript.done":
|
|
70
|
+
print(f"Assistant: {event.transcript}")
|
|
71
|
+
elif event.type == "conversation.item.input_audio_transcription.completed":
|
|
72
|
+
print(f"User: {event.transcript}")
|
|
73
|
+
|
|
74
|
+
# Run the session
|
|
75
|
+
asyncio.run(main())
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Complete example
|
|
79
|
+
|
|
80
|
+
Here's a complete working example:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
import asyncio
|
|
84
|
+
from agents.realtime import RealtimeAgent, RealtimeRunner
|
|
85
|
+
|
|
86
|
+
async def main():
|
|
87
|
+
# Create the agent
|
|
88
|
+
agent = RealtimeAgent(
|
|
89
|
+
name="Assistant",
|
|
90
|
+
instructions="You are a helpful voice assistant. Keep responses brief and conversational.",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Set up the runner with configuration
|
|
94
|
+
runner = RealtimeRunner(
|
|
95
|
+
starting_agent=agent,
|
|
96
|
+
config={
|
|
97
|
+
"model_settings": {
|
|
98
|
+
"model_name": "gpt-4o-realtime-preview",
|
|
99
|
+
"voice": "alloy",
|
|
100
|
+
"modalities": ["text", "audio"],
|
|
101
|
+
"input_audio_transcription": {
|
|
102
|
+
"model": "whisper-1"
|
|
103
|
+
},
|
|
104
|
+
"turn_detection": {
|
|
105
|
+
"type": "server_vad",
|
|
106
|
+
"threshold": 0.5,
|
|
107
|
+
"prefix_padding_ms": 300,
|
|
108
|
+
"silence_duration_ms": 200
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Start the session
|
|
115
|
+
session = await runner.run()
|
|
116
|
+
|
|
117
|
+
async with session:
|
|
118
|
+
print("Session started! The agent will stream audio responses in real-time.")
|
|
119
|
+
|
|
120
|
+
# Process events
|
|
121
|
+
async for event in session:
|
|
122
|
+
if event.type == "response.audio_transcript.done":
|
|
123
|
+
print(f"Assistant: {event.transcript}")
|
|
124
|
+
elif event.type == "conversation.item.input_audio_transcription.completed":
|
|
125
|
+
print(f"User: {event.transcript}")
|
|
126
|
+
elif event.type == "error":
|
|
127
|
+
print(f"Error: {event.error}")
|
|
128
|
+
break
|
|
129
|
+
|
|
130
|
+
if __name__ == "__main__":
|
|
131
|
+
asyncio.run(main())
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Configuration options
|
|
135
|
+
|
|
136
|
+
### Model settings
|
|
137
|
+
|
|
138
|
+
- `model_name`: Choose from available realtime models (e.g., `gpt-4o-realtime-preview`)
|
|
139
|
+
- `voice`: Select voice (`alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer`)
|
|
140
|
+
- `modalities`: Enable text and/or audio (`["text", "audio"]`)
|
|
141
|
+
|
|
142
|
+
### Audio settings
|
|
143
|
+
|
|
144
|
+
- `input_audio_format`: Format for input audio (`pcm16`, `g711_ulaw`, `g711_alaw`)
|
|
145
|
+
- `output_audio_format`: Format for output audio
|
|
146
|
+
- `input_audio_transcription`: Transcription configuration
|
|
147
|
+
|
|
148
|
+
### Turn detection
|
|
149
|
+
|
|
150
|
+
- `type`: Detection method (`server_vad`, `semantic_vad`)
|
|
151
|
+
- `threshold`: Voice activity threshold (0.0-1.0)
|
|
152
|
+
- `silence_duration_ms`: Silence duration to detect turn end
|
|
153
|
+
- `prefix_padding_ms`: Audio padding before speech
|
|
154
|
+
|
|
155
|
+
## Next steps
|
|
156
|
+
|
|
157
|
+
- [Learn more about realtime agents](guide.md)
|
|
158
|
+
- Check out working examples in the [examples/realtime](https://github.com/openai/openai-agents-python/tree/main/examples/realtime) folder
|
|
159
|
+
- Add tools to your agent
|
|
160
|
+
- Implement handoffs between agents
|
|
161
|
+
- Set up guardrails for safety
|
|
162
|
+
|
|
163
|
+
## Authentication
|
|
164
|
+
|
|
165
|
+
Make sure your OpenAI API key is set in your environment:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
export OPENAI_API_KEY="your-api-key-here"
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Or pass it directly when creating the session:
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
session = await runner.run(model_config={"api_key": "your-api-key"})
|
|
175
|
+
```
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Realtime Configuration
|
|
2
|
+
|
|
3
|
+
## Run Configuration
|
|
4
|
+
|
|
5
|
+
::: agents.realtime.config.RealtimeRunConfig
|
|
6
|
+
|
|
7
|
+
## Model Settings
|
|
8
|
+
|
|
9
|
+
::: agents.realtime.config.RealtimeSessionModelSettings
|
|
10
|
+
|
|
11
|
+
## Audio Configuration
|
|
12
|
+
|
|
13
|
+
::: agents.realtime.config.RealtimeInputAudioTranscriptionConfig
|
|
14
|
+
::: agents.realtime.config.RealtimeTurnDetectionConfig
|
|
15
|
+
|
|
16
|
+
## Guardrails Settings
|
|
17
|
+
|
|
18
|
+
::: agents.realtime.config.RealtimeGuardrailsSettings
|
|
19
|
+
|
|
20
|
+
## Model Configuration
|
|
21
|
+
|
|
22
|
+
::: agents.realtime.model.RealtimeModelConfig
|
|
23
|
+
|
|
24
|
+
## Tracing Configuration
|
|
25
|
+
|
|
26
|
+
::: agents.realtime.config.RealtimeModelTracingConfig
|
|
27
|
+
|
|
28
|
+
## User Input Types
|
|
29
|
+
|
|
30
|
+
::: agents.realtime.config.RealtimeUserInput
|
|
31
|
+
::: agents.realtime.config.RealtimeUserInputText
|
|
32
|
+
::: agents.realtime.config.RealtimeUserInputMessage
|
|
33
|
+
|
|
34
|
+
## Client Messages
|
|
35
|
+
|
|
36
|
+
::: agents.realtime.config.RealtimeClientMessage
|
|
37
|
+
|
|
38
|
+
## Type Aliases
|
|
39
|
+
|
|
40
|
+
::: agents.realtime.config.RealtimeModelName
|
|
41
|
+
::: agents.realtime.config.RealtimeAudioFormat
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Realtime Events
|
|
2
|
+
|
|
3
|
+
## Session Events
|
|
4
|
+
|
|
5
|
+
::: agents.realtime.events.RealtimeSessionEvent
|
|
6
|
+
|
|
7
|
+
## Event Types
|
|
8
|
+
|
|
9
|
+
### Agent Events
|
|
10
|
+
::: agents.realtime.events.RealtimeAgentStartEvent
|
|
11
|
+
::: agents.realtime.events.RealtimeAgentEndEvent
|
|
12
|
+
|
|
13
|
+
### Audio Events
|
|
14
|
+
::: agents.realtime.events.RealtimeAudio
|
|
15
|
+
::: agents.realtime.events.RealtimeAudioEnd
|
|
16
|
+
::: agents.realtime.events.RealtimeAudioInterrupted
|
|
17
|
+
|
|
18
|
+
### Tool Events
|
|
19
|
+
::: agents.realtime.events.RealtimeToolStart
|
|
20
|
+
::: agents.realtime.events.RealtimeToolEnd
|
|
21
|
+
|
|
22
|
+
### Handoff Events
|
|
23
|
+
::: agents.realtime.events.RealtimeHandoffEvent
|
|
24
|
+
|
|
25
|
+
### Guardrail Events
|
|
26
|
+
::: agents.realtime.events.RealtimeGuardrailTripped
|
|
27
|
+
|
|
28
|
+
### History Events
|
|
29
|
+
::: agents.realtime.events.RealtimeHistoryAdded
|
|
30
|
+
::: agents.realtime.events.RealtimeHistoryUpdated
|
|
31
|
+
|
|
32
|
+
### Error Events
|
|
33
|
+
::: agents.realtime.events.RealtimeError
|
|
34
|
+
|
|
35
|
+
### Raw Model Events
|
|
36
|
+
::: agents.realtime.events.RealtimeRawModelEvent
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Realtime Demo App
|
|
2
|
+
|
|
3
|
+
A web-based realtime voice assistant demo with a FastAPI backend and HTML/JS frontend.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install the required dependencies:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
uv add fastapi uvicorn websockets
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
Start the application with a single command:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd examples/realtime/app && uv run python server.py
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Then open your browser to: http://localhost:8000
|
|
22
|
+
|
|
23
|
+
## How to Use
|
|
24
|
+
|
|
25
|
+
1. Click **Connect** to establish a realtime session
|
|
26
|
+
2. Audio capture starts automatically - just speak naturally
|
|
27
|
+
3. Click the **Mic On/Off** button to mute/unmute your microphone
|
|
28
|
+
4. Watch the conversation unfold in the left pane
|
|
29
|
+
5. Monitor raw events in the right pane (click to expand/collapse)
|
|
30
|
+
6. Click **Disconnect** when done
|
|
31
|
+
|
|
32
|
+
## Architecture
|
|
33
|
+
|
|
34
|
+
- **Backend**: FastAPI server with WebSocket connections for real-time communication
|
|
35
|
+
- **Session Management**: Each connection gets a unique session with the OpenAI Realtime API
|
|
36
|
+
- **Audio Processing**: 24kHz mono audio capture and playback
|
|
37
|
+
- **Event Handling**: Full event stream processing with transcript generation
|
|
38
|
+
- **Frontend**: Vanilla JavaScript with clean, responsive CSS
|
|
39
|
+
|
|
40
|
+
The demo showcases the core patterns for building realtime voice applications with the OpenAI Agents SDK.
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import base64
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
import struct
|
|
6
|
+
from contextlib import asynccontextmanager
|
|
7
|
+
from typing import Any, assert_never
|
|
8
|
+
|
|
9
|
+
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
|
|
10
|
+
from fastapi.responses import FileResponse
|
|
11
|
+
from fastapi.staticfiles import StaticFiles
|
|
12
|
+
|
|
13
|
+
from agents import function_tool
|
|
14
|
+
from agents.realtime import RealtimeAgent, RealtimeRunner, RealtimeSession, RealtimeSessionEvent
|
|
15
|
+
|
|
16
|
+
logging.basicConfig(level=logging.INFO)
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@function_tool
|
|
21
|
+
def get_weather(city: str) -> str:
|
|
22
|
+
"""Get the weather in a city."""
|
|
23
|
+
return f"The weather in {city} is sunny."
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@function_tool
|
|
27
|
+
def get_secret_number() -> int:
|
|
28
|
+
"""Returns the secret number, if the user asks for it."""
|
|
29
|
+
return 71
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
haiku_agent = RealtimeAgent(
|
|
33
|
+
name="Haiku Agent",
|
|
34
|
+
instructions="You are a haiku poet. You must respond ONLY in traditional haiku format (5-7-5 syllables). Every response should be a proper haiku about the topic. Do not break character.",
|
|
35
|
+
tools=[],
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
agent = RealtimeAgent(
|
|
39
|
+
name="Assistant",
|
|
40
|
+
instructions="If the user wants poetry or haikus, you can hand them off to the haiku agent via the transfer_to_haiku_agent tool.",
|
|
41
|
+
tools=[get_weather, get_secret_number],
|
|
42
|
+
handoffs=[haiku_agent],
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class RealtimeWebSocketManager:
|
|
47
|
+
def __init__(self):
|
|
48
|
+
self.active_sessions: dict[str, RealtimeSession] = {}
|
|
49
|
+
self.session_contexts: dict[str, Any] = {}
|
|
50
|
+
self.websockets: dict[str, WebSocket] = {}
|
|
51
|
+
|
|
52
|
+
async def connect(self, websocket: WebSocket, session_id: str):
|
|
53
|
+
await websocket.accept()
|
|
54
|
+
self.websockets[session_id] = websocket
|
|
55
|
+
|
|
56
|
+
runner = RealtimeRunner(agent)
|
|
57
|
+
session_context = await runner.run()
|
|
58
|
+
session = await session_context.__aenter__()
|
|
59
|
+
self.active_sessions[session_id] = session
|
|
60
|
+
self.session_contexts[session_id] = session_context
|
|
61
|
+
|
|
62
|
+
# Start event processing task
|
|
63
|
+
asyncio.create_task(self._process_events(session_id))
|
|
64
|
+
|
|
65
|
+
async def disconnect(self, session_id: str):
|
|
66
|
+
if session_id in self.session_contexts:
|
|
67
|
+
await self.session_contexts[session_id].__aexit__(None, None, None)
|
|
68
|
+
del self.session_contexts[session_id]
|
|
69
|
+
if session_id in self.active_sessions:
|
|
70
|
+
del self.active_sessions[session_id]
|
|
71
|
+
if session_id in self.websockets:
|
|
72
|
+
del self.websockets[session_id]
|
|
73
|
+
|
|
74
|
+
async def send_audio(self, session_id: str, audio_bytes: bytes):
|
|
75
|
+
if session_id in self.active_sessions:
|
|
76
|
+
await self.active_sessions[session_id].send_audio(audio_bytes)
|
|
77
|
+
|
|
78
|
+
async def _process_events(self, session_id: str):
|
|
79
|
+
try:
|
|
80
|
+
session = self.active_sessions[session_id]
|
|
81
|
+
websocket = self.websockets[session_id]
|
|
82
|
+
|
|
83
|
+
async for event in session:
|
|
84
|
+
event_data = await self._serialize_event(event)
|
|
85
|
+
await websocket.send_text(json.dumps(event_data))
|
|
86
|
+
except Exception as e:
|
|
87
|
+
logger.error(f"Error processing events for session {session_id}: {e}")
|
|
88
|
+
|
|
89
|
+
async def _serialize_event(self, event: RealtimeSessionEvent) -> dict[str, Any]:
|
|
90
|
+
base_event: dict[str, Any] = {
|
|
91
|
+
"type": event.type,
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if event.type == "agent_start":
|
|
95
|
+
base_event["agent"] = event.agent.name
|
|
96
|
+
elif event.type == "agent_end":
|
|
97
|
+
base_event["agent"] = event.agent.name
|
|
98
|
+
elif event.type == "handoff":
|
|
99
|
+
base_event["from"] = event.from_agent.name
|
|
100
|
+
base_event["to"] = event.to_agent.name
|
|
101
|
+
elif event.type == "tool_start":
|
|
102
|
+
base_event["tool"] = event.tool.name
|
|
103
|
+
elif event.type == "tool_end":
|
|
104
|
+
base_event["tool"] = event.tool.name
|
|
105
|
+
base_event["output"] = str(event.output)
|
|
106
|
+
elif event.type == "audio":
|
|
107
|
+
base_event["audio"] = base64.b64encode(event.audio.data).decode("utf-8")
|
|
108
|
+
elif event.type == "audio_interrupted":
|
|
109
|
+
pass
|
|
110
|
+
elif event.type == "audio_end":
|
|
111
|
+
pass
|
|
112
|
+
elif event.type == "history_updated":
|
|
113
|
+
base_event["history"] = [item.model_dump(mode="json") for item in event.history]
|
|
114
|
+
elif event.type == "history_added":
|
|
115
|
+
pass
|
|
116
|
+
elif event.type == "guardrail_tripped":
|
|
117
|
+
base_event["guardrail_results"] = [
|
|
118
|
+
{"name": result.guardrail.name} for result in event.guardrail_results
|
|
119
|
+
]
|
|
120
|
+
elif event.type == "raw_model_event":
|
|
121
|
+
base_event["raw_model_event"] = {
|
|
122
|
+
"type": event.data.type,
|
|
123
|
+
}
|
|
124
|
+
elif event.type == "error":
|
|
125
|
+
base_event["error"] = str(event.error) if hasattr(event, "error") else "Unknown error"
|
|
126
|
+
else:
|
|
127
|
+
assert_never(event)
|
|
128
|
+
|
|
129
|
+
return base_event
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
manager = RealtimeWebSocketManager()
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@asynccontextmanager
|
|
136
|
+
async def lifespan(app: FastAPI):
|
|
137
|
+
yield
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
app = FastAPI(lifespan=lifespan)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@app.websocket("/ws/{session_id}")
|
|
144
|
+
async def websocket_endpoint(websocket: WebSocket, session_id: str):
|
|
145
|
+
await manager.connect(websocket, session_id)
|
|
146
|
+
try:
|
|
147
|
+
while True:
|
|
148
|
+
data = await websocket.receive_text()
|
|
149
|
+
message = json.loads(data)
|
|
150
|
+
|
|
151
|
+
if message["type"] == "audio":
|
|
152
|
+
# Convert int16 array to bytes
|
|
153
|
+
int16_data = message["data"]
|
|
154
|
+
audio_bytes = struct.pack(f"{len(int16_data)}h", *int16_data)
|
|
155
|
+
await manager.send_audio(session_id, audio_bytes)
|
|
156
|
+
|
|
157
|
+
except WebSocketDisconnect:
|
|
158
|
+
await manager.disconnect(session_id)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
app.mount("/", StaticFiles(directory="static", html=True), name="static")
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@app.get("/")
|
|
165
|
+
async def read_index():
|
|
166
|
+
return FileResponse("static/index.html")
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
if __name__ == "__main__":
|
|
170
|
+
import uvicorn
|
|
171
|
+
|
|
172
|
+
uvicorn.run(app, host="0.0.0.0", port=8000)
|