Skip to content

feat: Microsoft Agent Framework compatibility and bypass mode#44

Closed
CaddyGlow wants to merge 2 commits intofeat/codex-v0.114.0-integrationfrom
feat/codex-msaf-compatibility
Closed

feat: Microsoft Agent Framework compatibility and bypass mode#44
CaddyGlow wants to merge 2 commits intofeat/codex-v0.114.0-integrationfrom
feat/codex-msaf-compatibility

Conversation

@CaddyGlow
Copy link
Copy Markdown
Owner

Summary

  • Added OpenAI Responses format support to mock handler with proper SSE event sequences
  • Added format-aware mock adapter with target format detection from route context
  • Added bypass mode to plugin factory with MockAdapter fallback for testing
  • Added inject_detection_payload config toggle for generic OpenAI-compatible API usage
  • Added openai_thinking_xml streaming configuration support

PR Stack

This is PR 2 of 3 split from #41. Stacked on #43. Merge in order:

  1. feat: Codex v0.114.0 integration with gpt-5.4 support #43 - Core Codex v0.114.0 integration
  2. This PR - MSAF compatibility and bypass mode
  3. feat/codex-websocket-hardening - WebSocket auth hardening and e2e tests

Test plan

  • All pre-commit checks pass (ruff, mypy, format)
  • 1101 unit/plugin tests pass (+20 over PR1)
  • MSAF integration and real library tests pass
  • Mock handler Responses format streaming emits valid OpenAI events
  • Bypass mode factory tests verify adapter creation and error handling

Copilot AI review requested due to automatic review settings March 20, 2026 14:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends ccproxy’s Codex/OpenAI compatibility layer to better support Microsoft Agent Framework (MSAF) style traffic by making bypass/mock behavior format-aware (OpenAI Chat vs OpenAI Responses vs Anthropic), adding a bypass-mode adapter fallback at plugin factory level, and propagating openai_thinking_xml streaming behavior through the formatter pipeline.

Changes:

  • Add OpenAI Responses-format support to the mock handler (including SSE event sequencing) and make the mock adapter resolve target format from request.state.context.format_chain / route endpoint.
  • Add plugin factory bypass-mode support that returns a MockAdapter (with clear logging/error behavior).
  • Add inject_detection_payload toggle to Codex config/adapter to prevent Codex CLI detection/template injection for generic OpenAI-compatible clients; propagate openai_thinking_xml via formatter context.

Reviewed changes

Copilot reviewed 19 out of 20 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
uv.lock Dependency lock updates (notably mcp bump and additional wheels).
ccproxy/services/mocking/mock_handler.py Adds OpenAI Responses mock conversion + Responses SSE streaming event sequence; prompt text extraction.
ccproxy/services/adapters/mock_adapter.py Format-aware mock routing (prefers format_chain, falls back to endpoint detection); passes prompt text through.
ccproxy/services/adapters/format_adapter.py Adds streaming configuration and propagates openai_thinking_xml via formatter contextvar.
ccproxy/services/factories.py Wires openai_thinking_xml config into core adapters and mock handler adapters (chat + responses).
ccproxy/plugins/codex/config.py Introduces inject_detection_payload Codex setting.
ccproxy/plugins/codex/adapter.py Skips detection/template injection when configured; preserves user reasoning; removes additional unsupported keys.
ccproxy/llms/formatters/context.py Adds ContextVar helpers for openai_thinking_xml propagation.
ccproxy/llms/formatters/openai_to_openai/streams.py Respects openai_thinking_xml when emitting wrapped thinking blocks in streaming conversions.
ccproxy/llms/formatters/openai_to_openai/responses.py Respects openai_thinking_xml when wrapping thinking blocks in non-streaming conversions.
ccproxy/core/plugins/factories.py Adds bypass-mode factory path that returns MockAdapter + warning log.
.ccproxy.codex.msaf.toml.example Example config for MSAF clients (disables detection payload injection, disables thinking XML).
tests/unit/services/test_mock_adapter.py Verifies target format resolution via format_chain and endpoint fallback.
tests/unit/services/mocking/test_mock_handler.py Adds tests for prompt extraction and validates Responses SSE event schema/order.
tests/unit/llms/test_llms_streaming_settings.py Tests openai_thinking_xml propagation + ContextVar task isolation.
tests/unit/core/test_provider_factory_bypass.py Tests bypass-mode factory behavior (warning + clear error without service container).
tests/plugins/codex/unit/test_adapter.py Tests inject_detection_payload=False behavior and reasoning preservation.
tests/plugins/codex/integration/test_msaf_real_library.py Integration coverage for sequential agent-style MSAF flows without CLI injection.
tests/plugins/codex/integration/test_msaf_compat.py Integration coverage for MSAF chat completions compatibility + thinking XML disabled behavior.
tests/plugins/codex/integration/test_codex_basic.py Adds bypass streaming test validating OpenAI Responses SSE events.
Comments suppressed due to low confidence (1)

ccproxy/services/adapters/mock_adapter.py:116

  • RequestContext is created with a fixed request_id="mock-request". Now that mock streaming for OpenAI Chat/Responses derives event IDs (chatcmpl-*, resp_*, msg_*) and X-Request-ID from ctx.request_id, this makes IDs collide across requests in bypass/mock mode and can break clients that expect uniqueness. Consider deriving the request id from an incoming header (e.g., X-Request-ID) when present, otherwise generate a unique value (uuid4), and use it consistently for both handle_request and handle_streaming.
        ctx = RequestContext(
            request_id="mock-request",
            start_time=time.perf_counter(),
            logger=structlog.get_logger(__name__),
        )

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@CaddyGlow CaddyGlow force-pushed the feat/codex-v0.114.0-integration branch from ee8fb9d to fcca265 Compare March 20, 2026 14:19
@CaddyGlow CaddyGlow force-pushed the feat/codex-msaf-compatibility branch from a06adec to 9c34087 Compare March 20, 2026 14:19
Add MSAF-compatible mock response handling and bypass mode infrastructure:
- Add OpenAI Responses format support to mock handler with proper SSE events
- Add prompt text extraction for context-aware mock responses
- Add format-aware mock adapter with target format detection
- Add bypass mode to plugin factory with MockAdapter fallback
- Add inject_detection_payload config toggle for generic API usage
- Add openai_thinking_xml streaming configuration
- Add format adapter streaming configuration support
- Add MSAF integration and real library tests
- Add bypass mode factory tests
@CaddyGlow CaddyGlow force-pushed the feat/codex-v0.114.0-integration branch from fcca265 to 4f9e496 Compare March 20, 2026 14:25
@CaddyGlow CaddyGlow force-pushed the feat/codex-msaf-compatibility branch from 9c34087 to 40f264e Compare March 20, 2026 14:25
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants