Skip to content

Python: Add FoundryAgent conversation session helper#6623

Open
eavanvalkenburg wants to merge 5 commits into
microsoft:mainfrom
eavanvalkenburg:eavanvalkenburg/foundry-agent-conversation-session
Open

Python: Add FoundryAgent conversation session helper#6623
eavanvalkenburg wants to merge 5 commits into
microsoft:mainfrom
eavanvalkenburg:eavanvalkenburg/foundry-agent-conversation-session

Conversation

@eavanvalkenburg

@eavanvalkenburg eavanvalkenburg commented Jun 19, 2026

Copy link
Copy Markdown
Member

Motivation & Context

Foundry users can create project conversations through the underlying OpenAI client, but doing so requires application code to reach through the Foundry project client just to create a conversation ID before using FoundryAgent. This adds provider-specific boilerplate for a common server-side conversation/session setup path.

This change adds a Python FoundryAgent helper that mirrors the existing .NET FoundryAgent conversation-session convenience API for the Foundry-specific scenario. Broader provider-agnostic conversation creation APIs are intentionally left for a separate cross-language design discussion tracked by #6622.

Description & Review Guide

  • What are the major changes?
    • Added FoundryAgent.create_conversation(...) via the shared Foundry agent base implementation.
    • The method creates a Foundry project conversation through the project OpenAI client and returns an AgentSession with service_session_id set to the created conversation ID.
    • Added unit tests for success and caller-supplied local session IDs.
    • Documented the new helper in the Foundry package README.
  • What is the impact of these changes?
    • Foundry users can create a server-side project conversation without directly using the raw OpenAI client.
    • Existing hosted-agent isolation_key session behavior remains separate and unchanged.
  • What do you want reviewers to focus on?
    • Whether the method name/signature is the right Python shape for the Foundry-specific parity fix.
    • Whether returning a normal AgentSession with service_session_id is the right fit for project conversations.

Related Issue

Fixes #2931

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 19, 2026 11:29
@moonbox3 moonbox3 added documentation Improvements or additions to documentation python Issues related to the Python codebase labels Jun 19, 2026
@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/foundry/agent_framework_foundry
   _agent.py2495677%119, 122, 244–245, 249–251, 256–259, 352, 430–431, 443–444, 456–458, 460–461, 463–469, 471–472, 474, 476, 482–494, 498–499, 697–698, 701, 727, 737, 753, 841, 846, 850
TOTAL40093448388% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
8028 34 💤 0 ❌ 0 🔥 2m 7s ⏱️

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated Code Review

Reviewers: 5 | Confidence: 92%

✓ Correctness

The implementation is correct and well-defended. The create_conversation_session method properly validates inputs, handles edge cases (missing conversations client, empty conversation ID), and correctly delegates to the existing get_session method. The test coverage is thorough. No correctness issues found.

✓ Security Reliability

The implementation is defensively written with proper type checking (isinstance check for client type), safe attribute access (getattr with None defaults), and input validation (non-empty conversation ID check). Error paths are clearly defined with appropriate exception types. No injection risks, resource leaks, or unhandled failure modes were identified. The await call on create_conversation() will naturally propagate network/auth errors to the caller, which is the expected pattern.

✓ Test Coverage

The test coverage for the new create_conversation_session method is comprehensive. Tests cover the happy path, caller-supplied session IDs, and all practically-reachable error conditions (RuntimeError for missing conversations client, ValueError for empty/missing conversation ID). Assertions are meaningful—they verify return types, specific attribute values, and mock interactions. The only untested error path is the TypeError guard (line 776-777), but this is a defensive check that is unreachable through normal construction since the constructor already validates client_type at line 679.

✓ Failure Modes

The create_conversation_session implementation is well-structured for failure handling. It validates preconditions (client type check, SDK capability check via getattr chain), validates postconditions (non-empty conversation ID), and does not swallow exceptions from the underlying network call. The getattr chain correctly handles None conversations (getattr(None, 'create', None) returns None, caught by the subsequent check). No silent failures, lost errors, partial writes, or missing cleanup paths were identified.

✗ Design Approach

I found one design issue in the new helper: it creates a fresh project OpenAI client for conversation creation instead of reusing the configured client path that FoundryAgent was constructed with. That means constructor-level OpenAI settings like default_headers and timeout are applied to run(...) requests but silently skipped for create_conversation_session(...), so the new API can behave differently from the rest of the agent in setups that depend on those options.

Flagged Issues

  • create_conversation_session() bypasses the configured OpenAI client settings. The constructor documents default_headers as applying to "requests made through the OpenAI client" and applies both default_headers and timeout when it first builds the client (python/packages/foundry/agent_framework_foundry/_agent.py:208-216, 261-268), but the new helper recreates a client with self.client.project_client.get_openai_client() and no kwargs (python/packages/foundry/agent_framework_foundry/_agent.py:779-785). In any deployment that relies on custom headers or a non-default timeout, agent.run(...) and agent.create_conversation_session() will now hit the service with different client configuration.

Automated review by eavanvalkenburg's agents

@github-actions

Copy link
Copy Markdown
Contributor

Flagged issue

create_conversation_session() bypasses the configured OpenAI client settings. The constructor documents default_headers as applying to "requests made through the OpenAI client" and applies both default_headers and timeout when it first builds the client (python/packages/foundry/agent_framework_foundry/_agent.py:208-216, 261-268), but the new helper recreates a client with self.client.project_client.get_openai_client() and no kwargs (python/packages/foundry/agent_framework_foundry/_agent.py:779-785). In any deployment that relies on custom headers or a non-default timeout, agent.run(...) and agent.create_conversation_session() will now hit the service with different client configuration.


Source: automated DevFlow PR review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a Python convenience API on FoundryAgent/RawFoundryAgent to create a Foundry project conversation and return an AgentSession wired up with the resulting server-side conversation ID, reducing the need for application code to directly use the underlying OpenAI client.

Changes:

  • Added create_conversation_session(session_id: str | None = None) to create a project conversation via the Foundry project OpenAI client and return an AgentSession with service_session_id set.
  • Added unit tests covering success, caller-provided local session_id, missing conversations support, and missing/invalid conversation ID.
  • Documented the helper usage and how it relates to hosted-agent isolation_key sessions in the Foundry package README.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
python/packages/foundry/agent_framework_foundry/_agent.py Implements create_conversation_session() on the Foundry agent base.
python/packages/foundry/tests/foundry/test_foundry_agent.py Adds unit tests for the new conversation-session helper and error paths.
python/packages/foundry/README.md Documents the new helper and clarifies session ID semantics.
Comments suppressed due to low confidence (1)

python/packages/foundry/agent_framework_foundry/_agent.py:783

  • create_conversation_session() calls project_client.get_openai_client() without carrying over any agent-configured default_headers. If callers rely on default_headers (e.g., isolation-related headers) for all OpenAI traffic, conversation creation will behave differently from agent.run() and can fail in environments that require those headers.
        messages: AgentRunInputs | None,
        session: AgentSession | None,
        tools: ToolTypes | Callable[..., Any] | Sequence[ToolTypes | Callable[..., Any]] | None,
        options: Mapping[str, Any] | None,
        compaction_strategy: CompactionStrategy | None,

eavanvalkenburg and others added 2 commits June 19, 2026 13:34
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@eavanvalkenburg eavanvalkenburg marked this pull request as ready for review June 19, 2026 11:35

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated Code Review

Reviewers: 5 | Confidence: 88%

✓ Correctness

The PR adds a simple create_conversation helper on RawFoundryAgent that creates a project-level Foundry conversation via the OpenAI client and wraps the result in an AgentSession. The implementation is correct: the cast to RawFoundryAgentChatClient is safe (enforced by RawFoundryAgent.__init__ type check at line 678), get_openai_client() is correctly called synchronously (matching the pattern at line 266), and get_session is invoked with the right positional/keyword arguments matching its signature at BaseAgent line 434. Tests adequately cover the success path and caller-supplied session ID. No correctness issues found.

✓ Security Reliability

The PR adds a create_conversation helper that delegates to the Foundry project OpenAI client. The implementation is straightforward and the class hierarchy guarantees self.client is always a RawFoundryAgentChatClient. One reliability concern: unlike the sibling _create_service_session_id method which validates the returned session ID is a non-empty string (lines 751-753), create_conversation passes conversation.id directly to get_session without validation, which could silently produce an AgentSession with a None or empty service_session_id if the API behaves unexpectedly.

✓ Test Coverage

The test coverage for the new create_conversation method is adequate. The two tests cover the primary happy-path behaviors: creating a conversation session with auto-generated session ID and with a caller-supplied session ID. Both tests properly verify mock interactions and assert the correct values on the returned AgentSession. The implementation is a simple 3-line method, and the tests cover both parameter variants. No significant test coverage gaps identified.

✓ Failure Modes

The PR adds a create_conversation helper that creates a Foundry project conversation and wraps it in an AgentSession. The implementation is straightforward and correct. The cast on line 771 is safe because the _FoundryAgentBase.__init__ (line 679) already validates that the client type is a subclass of RawFoundryAgentChatClient. The get_openai_client() call pattern matches existing usage (line 266). No silent failures, lost errors, or partial-success paths are introduced — any API failure in conversations.create() will propagate as an exception to the caller.

✗ Design Approach

I found two design-level issues in the new helper. It recreates an unconfigured OpenAI client for conversation creation instead of reusing the agent's already-configured client, and it does not validate that the service actually returned a usable conversation ID before building an AgentSession. Both can silently produce behavior that diverges from the rest of FoundryAgent.

Flagged Issues

  • python/packages/foundry/agent_framework_foundry/_agent.py:772 bypasses the agent's configured OpenAI client. The constructor applies default_headers, agent_name, and timeout at _agent.py:261-268, and tests assert those settings matter (test_foundry_agent.py:721-735, 779-795). create_conversation() issues its request through a fresh bare client instead, silently dropping those settings.
  • python/packages/foundry/agent_framework_foundry/_agent.py:773 never validates that conversation creation returned a non-empty id. The sibling _create_service_session_id() explicitly rejects empty ids (_agent.py:750-755), but this path passes the raw value into get_session(), which forwards it unchanged into AgentSession. Callers can receive a session not actually bound to the created conversation.

Automated review by eavanvalkenburg's agents

Comment thread python/packages/foundry/agent_framework_foundry/_agent.py
@github-actions

Copy link
Copy Markdown
Contributor

Flagged issue

python/packages/foundry/agent_framework_foundry/_agent.py:772 bypasses the agent's configured OpenAI client. The constructor applies default_headers, agent_name, and timeout at _agent.py:261-268, and tests assert those settings matter (test_foundry_agent.py:721-735, 779-795). create_conversation() issues its request through a fresh bare client instead, silently dropping those settings.


Source: automated DevFlow PR review

@github-actions

Copy link
Copy Markdown
Contributor

Flagged issue

python/packages/foundry/agent_framework_foundry/_agent.py:773 never validates that conversation creation returned a non-empty id. The sibling _create_service_session_id() explicitly rejects empty ids (_agent.py:750-755), but this path passes the raw value into get_session(), which forwards it unchanged into AgentSession. Callers can receive a session not actually bound to the created conversation.


Source: automated DevFlow PR review


return agent_session_id

async def create_conversation(self, *, session_id: str | None = None) -> AgentSession:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shall we align the method name with the .NET one for consistency? — create_conversation_session

public async Task<ChatClientAgentSession> CreateConversationSessionAsync(CancellationToken cancellationToken = default)
?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation python Issues related to the Python codebase

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: Feature Request: Built‑in abstraction for conversation creation / IDs (remove need to directly use OpenAI client)

5 participants