Python: Add samples syntax checking with pyright (#3710)

* Add samples syntax checking with pyright

- Add pyrightconfig.samples.json with relaxed type checking but import validation
- Add samples-syntax poe task to check samples for syntax and import errors
- Add samples-syntax to check and pre-commit-check tasks
- Fix 78 sample errors:
  - Update workflow builder imports to use agent_framework_orchestrations
  - Change content type isinstance checks to content.type comparisons
  - Use Content factory methods instead of removed content type classes
  - Fix TypedDict access patterns for Annotation
  - Fix various API mismatches (normalize_messages, ChatMessage.text, role)

* fixed a bunch of samples and tweaks to pre-commit

* updated lock

* updated lock

* fixes

* added lint to samples
This commit is contained in:
Eduard van Valkenburg
2026-02-07 08:10:47 +01:00
committed by GitHub
Unverified
parent 74ac470a56
commit 390f93344c
83 changed files with 606 additions and 498 deletions
@@ -21,7 +21,7 @@ def search_hotels(
guests: Annotated[int, Field(description="Number of guests.")] = 2,
) -> str:
"""Search for available hotels based on location and dates.
Returns:
JSON string containing search results with hotel details including name, rating,
price, distance to landmarks, amenities, and availability.
@@ -88,7 +88,7 @@ def get_hotel_details(
hotel_name: Annotated[str, Field(description="Name of the hotel to get details for.")],
) -> str:
"""Get detailed information about a specific hotel.
Returns:
JSON string containing detailed hotel information including description,
check-in/out times, cancellation policy, reviews, and nearby attractions.
@@ -167,7 +167,7 @@ def search_flights(
passengers: Annotated[int, Field(description="Number of passengers.")] = 1,
) -> str:
"""Search for available flights between two locations.
Returns:
JSON string containing flight search results with details including flight numbers,
airlines, departure/arrival times, prices, durations, and baggage allowances.
@@ -289,7 +289,7 @@ def get_flight_details(
flight_number: Annotated[str, Field(description="Flight number (e.g., 'AF007' or 'DL264').")],
) -> str:
"""Get detailed information about a specific flight.
Returns:
JSON string containing detailed flight information including airline, aircraft type,
departure/arrival airports and times, gates, terminals, duration, and amenities.
@@ -331,7 +331,7 @@ def search_activities(
category: Annotated[str | None, Field(description="Activity category (e.g., 'Sightseeing', 'Culture', 'Culinary').")] = None,
) -> str:
"""Search for available activities and attractions at a destination.
Returns:
JSON string containing activity search results with details including name, category,
duration, price, rating, description, availability, and booking requirements.
@@ -440,10 +440,7 @@ def search_activities(
}
]
if category:
activities = [act for act in all_activities if act["category"] == category]
else:
activities = all_activities
activities = [act for act in all_activities if act["category"] == category] if category else all_activities
else:
activities = [
{
@@ -473,7 +470,7 @@ def get_activity_details(
activity_name: Annotated[str, Field(description="Name of the activity to get details for.")],
) -> str:
"""Get detailed information about a specific activity.
Returns:
JSON string containing detailed activity information including description, duration,
price, included items, meeting point, what to bring, cancellation policy, and reviews.
@@ -552,7 +549,7 @@ def confirm_booking(
customer_info: Annotated[dict, Field(description="Customer information including name and email.")],
) -> str:
"""Confirm a booking reservation.
Returns:
JSON string containing confirmation details including confirmation number,
booking status, customer information, and next steps.
@@ -587,9 +584,9 @@ def check_hotel_availability(
rooms: Annotated[int, Field(description="Number of rooms needed.")] = 1,
) -> str:
"""Check availability for hotel rooms.
Sample Date format: "December 15, 2025"
Returns:
JSON string containing availability status, available rooms count, price per night,
and last checked timestamp.
@@ -621,9 +618,9 @@ def check_flight_availability(
passengers: Annotated[int, Field(description="Number of passengers.")] = 1,
) -> str:
"""Check availability for flight seats.
Sample Date format: "December 15, 2025"
Returns:
JSON string containing availability status, available seats count, price per passenger,
and last checked timestamp.
@@ -654,9 +651,9 @@ def check_activity_availability(
participants: Annotated[int, Field(description="Number of participants.")] = 1,
) -> str:
"""Check availability for activity bookings.
Sample Date format: "December 16, 2025"
Returns:
JSON string containing availability status, available spots count, price per person,
and last checked timestamp.
@@ -688,7 +685,7 @@ def process_payment(
booking_reference: Annotated[str, Field(description="Booking reference number for the payment.")],
) -> str:
"""Process payment for a booking.
Returns:
JSON string containing payment result with transaction ID, status, amount, currency,
payment method details, and receipt URL.
@@ -718,7 +715,7 @@ def validate_payment_method(
payment_method: Annotated[dict, Field(description="Payment method to validate (type, number, expiry, cvv).")],
) -> str:
"""Validate payment method details.
Returns:
JSON string containing validation result with is_valid flag, payment method type,
validation messages, supported currencies, and processing fee information.
@@ -154,19 +154,19 @@ async def run_workflow_with_response_tracking(query: str, chat_client: AzureAICl
"""
if chat_client is None:
try:
# Create AIProjectClient with the correct API version for V2 prompt agents
project_client = AIProjectClient(
endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
credential=credential,
api_version="2025-11-15-preview",
)
async with DefaultAzureCredential() as credential:
# Create AIProjectClient with the correct API version for V2 prompt agents
project_client = AIProjectClient(
endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
credential=credential,
api_version="2025-11-15-preview",
)
async with (
DefaultAzureCredential() as credential,
project_client,
AzureAIClient(project_client=project_client, credential=credential) as client,
):
return await _run_workflow_with_client(query, client)
async with (
project_client,
AzureAIClient(project_client=project_client, credential=credential) as client,
):
return await _run_workflow_with_client(query, client)
except Exception as e:
print(f"Error during workflow execution: {e}")
raise
@@ -369,27 +369,36 @@ async def _process_workflow_events(events, conversation_ids, response_ids):
def _track_agent_ids(event, agent, response_ids, conversation_ids):
"""Track agent response and conversation IDs - supporting multiple responses per agent."""
if isinstance(event.data, AgentResponseUpdate):
if (
isinstance(event.data, AgentResponseUpdate)
and hasattr(event.data, "raw_representation")
and event.data.raw_representation
):
# Check for conversation_id and response_id from raw_representation
# V2 API stores conversation_id directly on raw_representation (ChatResponseUpdate)
if hasattr(event.data, "raw_representation") and event.data.raw_representation:
raw = event.data.raw_representation
raw = event.data.raw_representation
# Try conversation_id directly on raw representation
if hasattr(raw, "conversation_id") and raw.conversation_id:
# Try conversation_id directly on raw representation
if (
hasattr(raw, "conversation_id")
and raw.conversation_id # type: ignore[union-attr]
and raw.conversation_id not in conversation_ids[agent] # type: ignore[union-attr]
):
# Only add if not already in the list
conversation_ids[agent].append(raw.conversation_id) # type: ignore[union-attr]
# Extract response_id from the OpenAI event (available from first event)
if hasattr(raw, "raw_representation") and raw.raw_representation: # type: ignore[union-attr]
openai_event = raw.raw_representation # type: ignore[union-attr]
# Check if event has response object with id
if (
hasattr(openai_event, "response")
and hasattr(openai_event.response, "id")
and openai_event.response.id not in response_ids[agent]
):
# Only add if not already in the list
if raw.conversation_id not in conversation_ids[agent]:
conversation_ids[agent].append(raw.conversation_id)
# Extract response_id from the OpenAI event (available from first event)
if hasattr(raw, "raw_representation") and raw.raw_representation:
openai_event = raw.raw_representation
# Check if event has response object with id
if hasattr(openai_event, "response") and hasattr(openai_event.response, "id"):
# Only add if not already in the list
if openai_event.response.id not in response_ids[agent]:
response_ids[agent].append(openai_event.response.id)
response_ids[agent].append(openai_event.response.id)
async def create_and_run_workflow():
@@ -29,7 +29,7 @@ def print_section(title: str):
async def run_workflow():
"""Execute the multi-agent travel planning workflow.
Returns:
Dictionary containing workflow data with agent response IDs
"""