Python: Add OpenAI Codex SDK integration (agent-framework-codex)#4375
Python: Add OpenAI Codex SDK integration (agent-framework-codex)#4375LEDazzio01 wants to merge 8 commits intomicrosoft:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new Python managed-agent integration package, agent-framework-codex, that wraps the Codex SDK to provide an Agent Framework BaseAgent implementation with streaming, sessions, tool bridging (via MCP), and structured-output propagation.
Changes:
- Introduces
CodexAgent,CodexAgentOptions, andCodexAgentSettingsplus supporting implementation to run Codex viaCodexSDKClientwith streaming updates and session resume support. - Adds a full unit-test suite for initialization, streaming/non-streaming runs, sessions, tool conversion, runtime options, and structured output.
- Adds package scaffolding (
pyproject.toml, README, LICENSE, AGENTS.md).
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| python/packages/codex/agent_framework_codex/_agent.py | Implements the Codex managed agent (client lifecycle, sessions, tool→MCP conversion, streaming). |
| python/packages/codex/tests/test_codex_agent.py | Adds mocked unit tests covering key agent behaviors. |
| python/packages/codex/pyproject.toml | Defines the new package metadata, dependencies, and tooling config. |
| python/packages/codex/agent_framework_codex/init.py | Exposes the package public API + version. |
| python/packages/codex/README.md | Minimal install/get-started documentation. |
| python/packages/codex/LICENSE | Adds MIT license text for the package. |
| python/packages/codex/AGENTS.md | Agent discovery metadata for the new package. |
| session_id: The session ID to use, or None for a new session. | ||
| """ | ||
| needs_new_client = ( | ||
| not self._started or self._client is None or (session_id and session_id != self._current_session_id) |
There was a problem hiding this comment.
_ensure_session() only recreates the client when (session_id and session_id != self._current_session_id). If the agent previously resumed a session (self._current_session_id is set) and a caller later runs with a fresh AgentSession (service_session_id is None), this condition evaluates false and the existing client/session will be reused, so the "new" session is not actually isolated. Consider treating None as a valid session change (e.g., recreate whenever session_id != self._current_session_id) and add a test that runs once with a resumed session_id then again with a new session (None) to ensure a new session is started.
| not self._started or self._client is None or (session_id and session_id != self._current_session_id) | |
| not self._started | |
| or self._client is None | |
| or session_id != self._current_session_id |
python/packages/codex/AGENTS.md
Outdated
|
|
||
| - **`CodexAgent`** - Agent using Codex's native agent capabilities | ||
| - **`CodexAgentOptions`** - Options for Codex agent configuration | ||
| - **`CodexAgentSettings`** - Pydantic settings for configuration |
There was a problem hiding this comment.
AGENTS.md says CodexAgentSettings are "Pydantic settings", but this package uses the framework’s load_settings() helper which populates a TypedDict (and the settings loader explicitly notes it replaces the previous pydantic-settings approach). Update this description to avoid misleading consumers about configuration behavior and dependencies.
| - **`CodexAgentSettings`** - Pydantic settings for configuration | |
| - **`CodexAgentSettings`** - TypedDict-based settings populated via the framework's `load_settings()` helper |
LEDazzio01
left a comment
There was a problem hiding this comment.
Thanks for the thorough review! All 3 comments addressed in the latest commits:
-
_ensure_sessionsession isolation (_agent.py) — Fixed. Removed the extrasession_id andguard soNoneis now treated as a distinct session identity. Added a dedicated regression test (test_ensure_session_recreates_when_resumed_then_fresh) that verifies switching from a resumed session back toNonecorrectly creates a new client. (commit8df3a83,3b95a7d) -
pyproject.tomldependency — Alignedagent-framework-core>=1.0.0rc2→>=1.0.0rc1to match the other managed-agent integrations. (commit850cb45) -
AGENTS.mddescription — Updated "Pydantic settings" → "TypedDict-based settings populated via the framework'sload_settings()helper". (commitebdcb5e)
python/packages/codex/pyproject.toml
Outdated
| "Typing :: Typed", | ||
| ] | ||
| dependencies = [ | ||
| "agent-framework-core>=1.0.0rc1", |
There was a problem hiding this comment.
make sure you rebase to the latest and then update this to rc2
| response = await agent.run("Greet Alice") | ||
| """ | ||
|
|
||
| AGENT_PROVIDER_NAME: ClassVar[str] = "openai.codex" |
There was a problem hiding this comment.
is this a value defined in the Otel genAI spec? or should we just have openai in here?
| ) | ||
|
|
||
|
|
||
| class CodexAgent(BaseAgent, Generic[OptionsT]): |
There was a problem hiding this comment.
we have a PR open to add Telemetry to the ClaudeAgent, splitting it into a RawClaudeAgent and then ClaudeAgent is built from RawClaudeAgent and AgentTelemetryLayer, let's do the same here.
| *, | ||
| stream: bool = False, | ||
| session: AgentSession | None = None, | ||
| options: OptionsT | MutableMapping[str, Any] | None = None, |
There was a problem hiding this comment.
is the MutableMapping needed here? I think it should be able to just be OptionsT
| **kwargs: Any, | ||
| ) -> AgentResponse[Any]: ... | ||
|
|
||
| def run( |
There was a problem hiding this comment.
would it make sense to also support background: bool = False here? check OpenAIResponses and A2A for how that works now.
Adds LICENSE, README.md, AGENTS.md, and pyproject.toml for the new agent-framework-codex package. Closes microsoft#4370.
Core implementation of the agent-framework-codex package with: - CodexAgentSettings for env-based configuration - CodexAgentOptions for per-request options - CodexAgent wrapping CodexSDKClient with streaming, tools, sessions
Tests cover settings, initialization, lifecycle, run (streaming and non-streaming), session management, tool conversion, permissions, error handling, format prompt, options preparation, and structured output.
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Previously, _ensure_session() only recreated the client when (session_id and session_id != self._current_session_id), which meant switching from a resumed session back to a fresh session (None) would incorrectly reuse the existing client. Now we compare session_id != self._current_session_id directly, so None is treated as a valid, distinct session identity. Co-authored-by: Copilot <copilot@github.com>
Verifies that _ensure_session creates a new client when switching from a resumed session (non-None) back to a fresh session (None). Co-authored-by: Copilot <copilot@github.com>
- Rebase onto latest main - Bump agent-framework-core dependency to >=1.0.0rc2 - Split CodexAgent into RawCodexAgent + CodexAgent(AgentTelemetryLayer) following A2AAgent pattern as requested - Remove MutableMapping from run() options parameter type - Export RawCodexAgent from __init__.py
3b95a7d to
b752405
Compare
|
Thanks for the thorough review @eavanvalkenburg! I've addressed all feedback in the latest force-push (rebased onto latest main): ✅ Changes made:
Ready for another look! 🙏 |
Motivation and Context
Closes #4370
The Microsoft Agent Framework currently supports managed agent SDK integrations for Claude (
agent-framework-claude) and GitHub Copilot (agent-framework-github-copilot), but not for OpenAI Codex. This PR addsagent-framework-codexto provide parity across the three major agentic coding SDKs.Description
Adds a new Python package
agent-framework-codexthat wraps thecodex-sdkas a managed agent, following the same conventions as the existing Claude and GitHub Copilot packages.New Files
python/packages/codex/pyproject.tomlpython/packages/codex/README.mdpython/packages/codex/LICENSEpython/packages/codex/AGENTS.mdpython/packages/codex/agent_framework_codex/__init__.pyCodexAgent,CodexAgentOptions,CodexAgentSettingspython/packages/codex/agent_framework_codex/_agent.pyCodexSDKClientpython/packages/codex/tests/test_codex_agent.pyKey Classes
CodexAgentSettings— TypedDict for env-based config (CODEX_AGENT_prefix)CodexAgentOptions— TypedDict for per-request options (model, system_prompt, etc.)CodexAgent—BaseAgentsubclass with full support for:service_session_id)async with CodexAgent() as agent)Usage
Contribution Checklist