Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions .github/workflows/e2e-orchestrator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,34 @@ jobs:

# ===========================================================================
# Summary - Posts test results to PR
# This is the ONLY check you need to mark as "Required" in branch protection
# ===========================================================================
summary:
name: Test Summary
e2e-status:
name: E2E Status
runs-on: ubuntu-latest
needs: [python-openai, nodejs-openai, nodejs-langchain, dotnet-sk, dotnet-af]
if: always()

steps:
- name: Check E2E Status
run: |
echo "Checking E2E test results..."

# Get all job results (skipped jobs are fine, failed jobs are not)
results="${{ needs.python-openai.result }} ${{ needs.nodejs-openai.result }} ${{ needs.nodejs-langchain.result }} ${{ needs.dotnet-sk.result }} ${{ needs.dotnet-af.result }}"

echo "Job results: $results"

# Check if any job failed or was cancelled
if echo "$results" | grep -qE "failure|cancelled"; then
echo "❌ One or more E2E tests failed or were cancelled"
exit 1
fi

echo "✅ All E2E tests passed (or were skipped)"

- name: Generate Summary
if: always()
id: summary
run: |
# Determine overall status
Expand Down
5 changes: 0 additions & 5 deletions python/openai/sample-agent/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ AGENT_ID=
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID=
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET=
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID=
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__ALT_BLUEPRINT_NAME=AGENTBLUEPRINT

CONNECTIONS__AGENTBLUEPRINT__SETTINGS__CLIENTID=
CONNECTIONS__AGENTBLUEPRINT__SETTINGS__CLIENTSECRET=
CONNECTIONS__AGENTBLUEPRINT__SETTINGS__TENANTID=

AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__AGENTIC__SETTINGS__TYPE=AgenticUserAuthorization
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__AGENTIC__SETTINGS__ALT_BLUEPRINT_NAME=AGENTBLUEPRINT
Expand Down
34 changes: 25 additions & 9 deletions python/openai/sample-agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from token_cache import get_cached_agentic_token

# Load environment variables
load_dotenv()
load_dotenv(override=True)
Comment thread
rahuldevikar761 marked this conversation as resolved.

# Configure logging
logging.basicConfig(level=logging.INFO)
Expand Down Expand Up @@ -239,25 +239,41 @@ async def setup_mcp_servers(self, auth: Authorization, auth_handler_name: str, c
"""Set up MCP server connections based on authentication configuration.

Authentication priority:
1. Bearer token from config (BEARER_TOKEN) - for local development/testing
2. Auth handler (auth_handler_name) - for production agentic auth
1. Agentic auth (USE_AGENTIC_AUTH=true) - for production/Teams authentication
2. Bearer token from config (BEARER_TOKEN) - for local development/testing
3. No auth - gracefully skip MCP and run in bare LLM mode

Comment thread
rahuldevikar761 marked this conversation as resolved.
If MCP connection fails for any reason, the agent will gracefully fall back
to bare LLM mode without MCP tools.
"""
try:
# Priority 1: Bearer token provided in config (for local dev/testing)
if self.auth_options.bearer_token:
logger.info("🔑 Using bearer token from config for MCP servers")
# Check if agentic auth is enabled
use_agentic_auth = os.getenv("USE_AGENTIC_AUTH", "false").lower() == "true"

# Priority 1: Agentic auth enabled (production/Teams authentication)
# When USE_AGENTIC_AUTH=true, always use agentic auth - never fall back to bearer token
if use_agentic_auth:
if auth_handler_name:
logger.info(f"🔒 Using agentic auth handler '{auth_handler_name}' for MCP servers (USE_AGENTIC_AUTH=true)")
else:
logger.info("🔒 Using agentic auth for MCP servers (USE_AGENTIC_AUTH=true, no explicit handler)")
self.agent = await self.tool_service.add_tool_servers_to_agent(
agent=self.agent,
auth=auth,
auth_handler_name=auth_handler_name,
context=context,
)
# Priority 2: Bearer token provided in config (for local dev/testing when agentic auth is disabled)
elif self.auth_options.bearer_token:
logger.info("🔑 Using bearer token from config for MCP servers (USE_AGENTIC_AUTH=false)")
self.agent = await self.tool_service.add_tool_servers_to_agent(
agent=self.agent,
auth=auth,
auth_handler_name=auth_handler_name,
context=context,
auth_token=self.auth_options.bearer_token,
)
# Priority 2: Auth handler configured (production agentic auth)
# Priority 3: Auth handler configured without USE_AGENTIC_AUTH flag
elif auth_handler_name:
logger.info(f"🔒 Using auth handler '{auth_handler_name}' for MCP servers")
self.agent = await self.tool_service.add_tool_servers_to_agent(
Expand All @@ -266,10 +282,10 @@ async def setup_mcp_servers(self, auth: Authorization, auth_handler_name: str, c
auth_handler_name=auth_handler_name,
context=context,
)
# Priority 3: No auth configured - skip MCP and run bare LLM
# Priority 4: No auth configured - skip MCP and run bare LLM
else:
logger.warning("⚠️ No authentication configured - running in bare LLM mode without MCP tools")
logger.info("💡 To enable MCP: provide BEARER_TOKEN or configure AUTH_HANDLER_NAME")
logger.info("💡 To enable MCP: set USE_AGENTIC_AUTH=true, provide BEARER_TOKEN, or configure AUTH_HANDLER_NAME")
# Agent already initialized without MCP tools

except Exception as e:
Expand Down
17 changes: 11 additions & 6 deletions python/openai/sample-agent/host_agent_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
logger = logging.getLogger(__name__)

# Load configuration
load_dotenv()
load_dotenv(override=True)
Comment thread
rahuldevikar761 marked this conversation as resolved.
Comment thread
rahuldevikar761 marked this conversation as resolved.
agents_sdk_config = load_configuration_from_env(environ)


Expand Down Expand Up @@ -196,6 +196,7 @@ async def initialize_agent(self):

def create_auth_configuration(self) -> AgentAuthConfiguration | None:
"""Create authentication configuration based on available environment variables."""
# Check for direct CLIENT_ID/TENANT_ID/CLIENT_SECRET env vars first
client_id = environ.get("CLIENT_ID")
tenant_id = environ.get("TENANT_ID")
client_secret = environ.get("CLIENT_SECRET")
Expand Down Expand Up @@ -250,7 +251,7 @@ async def health(_req: Request) -> Response:
if auth_configuration:
middlewares.append(jwt_authorization_middleware)

# Anonymous claims middleware
# Anonymous claims middleware - provides claims for unauthenticated requests
@web_middleware
async def anonymous_claims(request, handler):
if not auth_configuration:
Expand Down Expand Up @@ -298,6 +299,10 @@ async def anonymous_claims(request, handler):
)
port = desired_port + 1

# For Azure App Service, bind to 0.0.0.0 to accept external connections
host = environ.get("WEBSITE_HOSTNAME", None)
bind_host = "0.0.0.0" if host else "localhost"

Comment thread
rahuldevikar761 marked this conversation as resolved.
Comment thread
rahuldevikar761 marked this conversation as resolved.
print("=" * 80)
print(f"🏢 Generic Agent Host - {self.agent_class.__name__}")
print("=" * 80)
Expand All @@ -306,13 +311,13 @@ async def anonymous_claims(request, handler):
print("🎯 Compatible with Agents Playground")
if port != desired_port:
print(f"⚠️ Requested port {desired_port} busy; using fallback {port}")
print(f"\n🚀 Starting server on localhost:{port}")
print(f"📚 Bot Framework endpoint: http://localhost:{port}/api/messages")
print(f"❤️ Health: http://localhost:{port}/api/health")
print(f"\n🚀 Starting server on {bind_host}:{port}")
print(f"📚 Bot Framework endpoint: http://{bind_host}:{port}/api/messages")
print(f"❤️ Health: http://{bind_host}:{port}/api/health")
print("🎯 Ready for testing!\n")

try:
run_app(app, host="localhost", port=port)
run_app(app, host=bind_host, port=port)
except KeyboardInterrupt:
print("\n👋 Server stopped")
except Exception as error:
Expand Down
Loading