From 195ec998c9eac70cc0d778bddaaeb50f120c869e Mon Sep 17 00:00:00 2001 From: Varshitha Bachu Date: Wed, 15 Oct 2025 18:05:32 -0700 Subject: [PATCH 1/2] initial commit --- samples-v2/openai_agents/ORDER_RETURNS.md | 148 ++++++++++++++++++ .../basic/order_return_validation.py | 138 ++++++++++++++++ .../openai_agents/basic/refund_processing.py | 111 +++++++++++++ .../order_return_orchestrators.py | 111 +++++++++++++ 4 files changed, 508 insertions(+) create mode 100644 samples-v2/openai_agents/ORDER_RETURNS.md create mode 100644 samples-v2/openai_agents/basic/order_return_validation.py create mode 100644 samples-v2/openai_agents/basic/refund_processing.py create mode 100644 samples-v2/openai_agents/order_return_orchestrators.py diff --git a/samples-v2/openai_agents/ORDER_RETURNS.md b/samples-v2/openai_agents/ORDER_RETURNS.md new file mode 100644 index 00000000..1e80dabb --- /dev/null +++ b/samples-v2/openai_agents/ORDER_RETURNS.md @@ -0,0 +1,148 @@ +# Order Return Processing System + +An order return processing system built with Azure Functions and OpenAI Agents, demonstrating advanced orchestration patterns and multi-agent workflows. + +## Overview + +This system automatically processes customer return requests using AI agents to validate return reasons, process refunds, and route edge cases to human review. It showcases real-world business logic implementation with Azure Durable Functions. + +## Quick Start + +### Submit a Return Request +```bash +curl -X POST http://localhost:7071/api/order_return_processor \ + -H "Content-Type: application/json" \ + -d '{ + "order_id": "ORD-12345", + "customer_id": "CUST-67890", + "product_category": "Electronics", + "purchase_date": "2024-10-01", + "return_reason": "Product arrived damaged in shipping" + }' +``` + +### Check Processing Status +```bash +# Use the statusQueryGetUri from the submission response +curl http://localhost:7071/runtime/webhooks/durabletask/instances/{instance_id} +``` + +## API Reference + +### Endpoints + +| Method | Endpoint | Description | +|--------|----------|-------------| +| `POST` | `/api/order_return_processor` | Submit a new return request | +| `GET` | `/runtime/webhooks/durabletask/instances/{instance_id}` | Check processing status | + + +### Request Schema + +```json +{ + "order_id": "string (required)", + "customer_id": "string (required)", + "product_category": "string (required)", + "purchase_date": "string (required)", + "return_reason": "string (required)" +} +``` + +## Business Logic + +### Validation Rules + +**✅ Auto-Approved Returns** +- Defective or broken products +- Wrong item shipped +- Damaged during shipping +- Product not as described +- Quality issues +- Size/fit problems + +**❌ Requires Human Review** +- Changed mind without valid cause +- Found item cheaper elsewhere +- Buyer's remorse +- Financial reasons +- Vague complaints + +## Example Responses + +### Successful Auto-Approval +```json +{ + "status": "approved_and_processed", + "validation": { + "agent_response": "Return approved - product defect identified", + "validation_result": { "is_valid": true } + }, + "refund": { + "refund_details": { + "success": true, + "refund_amount": 93.00, + "transaction_id": "REF-ABC123", + "processing_time": "3-5 business days" + } + }, + "message": "Return approved and refund processed successfully" +} +``` + +### Human Review Required +```json +{ + "status": "pending_human_review", + "validation": { + "agent_response": "Return requires manual review - unclear reason", + "validation_result": { "is_valid": false } + }, + "human_review": { + "review_ticket_id": "REV-XYZ789", + "estimated_review_time": "24-48 hours", + "message": "Your return request has been escalated for human review" + } +} +``` + +## Architecture + +The system uses a multi-agent orchestration pattern: + +1. **Order Return Processor** (Main Orchestrator) - Coordinates the entire workflow +2. **Validation Agent** - Analyzes return reasons against business rules +3. **Refund Agent** - Processes approved refunds automatically +4. **Human Review Activity** - Creates support tickets for manual cases + +## File Structure + +``` +basic/ +├── order_return_validation.py # Validation agent +└── refund_processing.py # Refund processing agent + +order_return_orchestrators.py # Main orchestration logic +test_order_return.py # Testing examples and utilities +``` + +## Testing + +```bash +# Start the function app +func start + +# Test valid return (should auto-approve) +curl -X POST http://localhost:7071/api/order_return_processor \ + -H "Content-Type: application/json" \ + -d '{"order_id":"TEST-001","customer_id":"CUST-001","product_category":"Electronics","purchase_date":"2024-10-01","return_reason":"arrived damaged"}' + +# Test invalid return (should require human review) +curl -X POST http://localhost:7071/api/order_return_processor \ + -H "Content-Type: application/json" \ + -d '{"order_id":"TEST-002","customer_id":"CUST-002","product_category":"Clothing","purchase_date":"2024-09-15","return_reason":"changed my mind"}' + +# Check status using the response from above requests +# Look for "statusQueryGetUri" in the response and use that URL +curl {statusQueryGetUri_from_response} +``` \ No newline at end of file diff --git a/samples-v2/openai_agents/basic/order_return_validation.py b/samples-v2/openai_agents/basic/order_return_validation.py new file mode 100644 index 00000000..ec79bc5b --- /dev/null +++ b/samples-v2/openai_agents/basic/order_return_validation.py @@ -0,0 +1,138 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +from __future__ import annotations + +from pydantic import BaseModel +from typing import Literal + +from agents import Agent, Runner, function_tool + + +class ReturnValidationResult(BaseModel): + is_valid: bool + reason: str + confidence_score: float # 0.0 to 1.0 + order_id: str + + +class OrderReturnRequest(BaseModel): + order_id: str + return_reason: str + purchase_date: str + product_category: str + customer_id: str + + +@function_tool +def validate_return_reason(return_request: OrderReturnRequest) -> ReturnValidationResult: + """ + Validate if an order return reason is legitimate based on company policy. + Valid reasons include: defective product, wrong item received, damaged in shipping, + not as described, quality issues, size/fit issues (for clothing). + Invalid reasons include: changed mind after 30 days, buyer's remorse, + found cheaper elsewhere, impulse purchase regret. + """ + + # Simulate policy validation logic + valid_reasons = [ + "defective", "damaged", "wrong item", "not as described", + "quality issues", "size issue", "fit issue", "broken", + "missing parts", "expired" + ] + + invalid_reasons = [ + "changed mind", "buyer's remorse", "found cheaper", + "impulse purchase", "don't need", "financial reasons" + ] + + reason_lower = return_request.return_reason.lower() + + # Check for valid reasons + is_valid = any(valid_reason in reason_lower for valid_reason in valid_reasons) + + # Check for invalid reasons + if any(invalid_reason in reason_lower for invalid_reason in invalid_reasons): + is_valid = False + + # Calculate confidence based on keyword matching + confidence = 0.8 if is_valid else 0.7 + + validation_reason = ( + "Return reason matches company policy for valid returns" if is_valid + else "Return reason does not meet company return policy criteria" + ) + + return ReturnValidationResult( + is_valid=is_valid, + reason=validation_reason, + confidence_score=confidence, + order_id=return_request.order_id + ) + + +def main(return_request_data: dict): + """Main function to run the order return validation agent""" + + agent = Agent( + name="Order Return Validation Specialist", + instructions=""" + You are an expert order return validation specialist. Your job is to: + 1. Analyze customer return requests carefully + 2. Determine if the return reason is valid according to company policy + 3. Provide clear reasoning for your decision + 4. Be fair but firm in applying policy guidelines + + Valid return reasons typically include: + - Defective or broken products + - Wrong item shipped + - Damaged during shipping + - Product not as described + - Quality issues + - Size/fit problems (for applicable items) + + Invalid return reasons typically include: + - Changed mind without valid cause + - Found item cheaper elsewhere + - Buyer's remorse + - Financial hardship + - General dissatisfaction without specific issue + + Always use the validate_return_reason tool to check the policy compliance. + Based on the tool result, clearly state if the return is VALID or INVALID. + End your response with either "Return is VALID" or "Return is INVALID". + """, + tools=[validate_return_reason], + ) + + # Convert dict to OrderReturnRequest + return_request = OrderReturnRequest(**return_request_data) + + user_message = f""" + Please validate this return request: + + Order ID: {return_request.order_id} + Customer ID: {return_request.customer_id} + Product Category: {return_request.product_category} + Purchase Date: {return_request.purchase_date} + Return Reason: {return_request.return_reason} + + Is this a valid return request according to our company policy? + """ + + result = Runner.run_sync(agent, user_message) + # Parse the agent's response to extract validation decision + agent_response = result.final_output + is_valid = "valid" in str(agent_response).lower() and "invalid" not in str(agent_response).lower() + + # Create a structured validation result + validation_result = { + "is_valid": is_valid, + "reason": "Parsed from agent response", + "confidence_score": 0.8 if is_valid else 0.7, + "order_id": return_request_data.get("order_id") + } + + return { + "agent_response": agent_response, + "validation_result": validation_result + } \ No newline at end of file diff --git a/samples-v2/openai_agents/basic/refund_processing.py b/samples-v2/openai_agents/basic/refund_processing.py new file mode 100644 index 00000000..c561d3ed --- /dev/null +++ b/samples-v2/openai_agents/basic/refund_processing.py @@ -0,0 +1,111 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +from __future__ import annotations + +from pydantic import BaseModel +from typing import Dict, Any + +from agents import Agent, Runner, function_tool + + +class RefundResult(BaseModel): + success: bool + refund_amount: float + transaction_id: str + refund_method: str + processing_time: str + + +@function_tool +def process_refund(order_id: str, refund_amount: float, customer_id: str) -> RefundResult: + """ + Process a refund for a validated return request. + This simulates calling payment processing systems. + """ + + # Simulate refund processing + import uuid + transaction_id = f"REF-{uuid.uuid4().hex[:8].upper()}" + + return RefundResult( + success=True, + refund_amount=refund_amount, + transaction_id=transaction_id, + refund_method="original_payment_method", + processing_time="3-5 business days" + ) + + +@function_tool +def get_order_details(order_id: str) -> Dict[str, Any]: + """ + Retrieve order details for refund processing. + This simulates calling order management systems. + """ + + # Simulate order lookup + return { + "order_id": order_id, + "total_amount": 99.99, + "tax_amount": 7.99, + "shipping_cost": 5.99, + "product_cost": 86.01, + "currency": "USD", + "payment_method": "credit_card", + "order_status": "delivered" + } + + +def main(validation_data: dict): + """Main function to process refund for validated return""" + + agent = Agent( + name="Refund Processing Specialist", + instructions=""" + You are a refund processing specialist. Your job is to: + 1. Retrieve the order details for the validated return + 2. Calculate the appropriate refund amount (usually full product cost + tax) + 3. Process the refund through our payment systems + 4. Provide confirmation details to the customer + + Always retrieve order details first, then process the refund. + Be precise with refund amounts and provide clear transaction information. + End your response with "REFUND SUCCESS" if the refund is processed successfully. + """, + tools=[get_order_details, process_refund], + ) + + order_id = validation_data.get("order_id") + customer_id = validation_data.get("customer_id", "unknown") + + user_message = f""" + Process a refund for the validated return: + Order ID: {order_id} + Customer ID: {customer_id} + + Please: + 1. Get the order details + 2. Calculate the refund amount (product cost + tax, excluding shipping) + 3. Process the refund + 4. Provide confirmation details + """ + + result = Runner.run_sync(agent, user_message) + + # Parse the agent's response to extract refund status + agent_response = result.final_output + is_successful = "refund" in str(agent_response).lower() and "success" in str(agent_response).lower() + + # Create a structured refund result + refund_details = { + "success": is_successful, + "refund_amount": 93.00, # Product + Tax (86.01 + 7.99) + "transaction_id": f"REF-{hash(str(validation_data.get('order_id', ''))) % 10000:04d}", + "refund_method": "original_payment_method", + "processing_time": "3-5 business days" + } + + return { + "agent_response": agent_response, + "refund_details": refund_details + } \ No newline at end of file diff --git a/samples-v2/openai_agents/order_return_orchestrators.py b/samples-v2/openai_agents/order_return_orchestrators.py new file mode 100644 index 00000000..303d421b --- /dev/null +++ b/samples-v2/openai_agents/order_return_orchestrators.py @@ -0,0 +1,111 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +import uuid +import azure.durable_functions as df + + +def register_order_return_orchestrators(app: df.DFApp): + """Register all order return related orchestrators and activities with the app""" + + @app.orchestration_trigger(context_name="context") + def order_return_processor(context: df.DurableOrchestrationContext): + """ + Orchestrates the order return process: + 1. Validates return reason using an AI agent + 2. If valid, processes refund via another orchestration + 3. If invalid, routes for human review + """ + + # Get the input data (order return request) + return_request_input = context.get_input() + + if not return_request_input: + return { + "status": "error", + "message": "No return request data provided" + } + + # Step 1: Validate the return reason using AI agent + validation_task = context.call_sub_orchestrator("order_return_validation", return_request_input) + validation_result = yield validation_task + + # Extract validation decision from agent response + is_valid = False + if validation_result: + if isinstance(validation_result, dict) and validation_result.get("validation_result"): + is_valid = validation_result["validation_result"].get("is_valid", False) + elif isinstance(validation_result, str): + # Handle case where validation_result is a string + is_valid = "valid" in validation_result.lower() and "invalid" not in validation_result.lower() + + if is_valid: + # Step 2a: Return is valid - process refund + refund_task = context.call_sub_orchestrator("refund_processor", { + "order_id": return_request_input.get("order_id"), + "customer_id": return_request_input.get("customer_id"), + "validation_result": validation_result + }) + refund_result = yield refund_task + + return { + "status": "approved_and_processed", + "validation": validation_result, + "refund": refund_result, + "message": "Return approved and refund processed successfully" + } + else: + # Step 2b: Return is invalid - route for human review + human_review_task = context.call_activity("route_for_human_review", { + "return_request": return_request_input, + "validation_result": validation_result, + "reason": "Return reason does not meet policy criteria" + }) + review_result = yield human_review_task + + return { + "status": "pending_human_review", + "validation": validation_result, + "human_review": review_result, + "message": "Return requires human review" + } + + @app.orchestration_trigger(context_name="context") + @app.durable_openai_agent_orchestrator + def order_return_validation(context): + """Sub-orchestration that validates return reasons using AI agent""" + import basic.order_return_validation + return_request = context.get_input() + return basic.order_return_validation.main(return_request) + + @app.orchestration_trigger(context_name="context") + @app.durable_openai_agent_orchestrator + def refund_processor(context): + """Sub-orchestration that processes refunds using AI agent""" + import basic.refund_processing + validation_data = context.get_input() + return basic.refund_processing.main(validation_data) + + @app.activity_trigger(input_name="review_data") + async def route_for_human_review(review_data: dict) -> dict: + """Activity function that routes invalid returns for human review""" + + # In a real implementation, this would: + # - Create a ticket in a support system + # - Send notification to review team + # - Update order status in database + # - Send email to customer about review process + + review_ticket_id = f"REV-{uuid.uuid4().hex[:8].upper()}" + + # Simulate creating review ticket + print(f"[HUMAN REVIEW] Created review ticket {review_ticket_id}") + print(f"[HUMAN REVIEW] Order ID: {review_data['return_request'].get('order_id')}") + print(f"[HUMAN REVIEW] Reason: {review_data.get('reason')}") + + return { + "review_ticket_id": review_ticket_id, + "status": "pending_review", + "estimated_review_time": "24-48 hours", + "contact_method": "email", + "message": f"Your return request has been escalated for human review. Ticket ID: {review_ticket_id}" + } \ No newline at end of file From 4838314ad425fe8e8f103bece1815afeacb91d45 Mon Sep 17 00:00:00 2001 From: Varshitha Bachu Date: Wed, 15 Oct 2025 18:07:17 -0700 Subject: [PATCH 2/2] updated function_app.py and whitespace fixes --- .../basic/order_return_validation.py | 46 +++++++++---------- .../openai_agents/basic/refund_processing.py | 27 ++++++----- samples-v2/openai_agents/function_app.py | 20 ++++++++ .../order_return_orchestrators.py | 26 +++++------ 4 files changed, 69 insertions(+), 50 deletions(-) diff --git a/samples-v2/openai_agents/basic/order_return_validation.py b/samples-v2/openai_agents/basic/order_return_validation.py index ec79bc5b..73bcf9a9 100644 --- a/samples-v2/openai_agents/basic/order_return_validation.py +++ b/samples-v2/openai_agents/basic/order_return_validation.py @@ -29,39 +29,39 @@ def validate_return_reason(return_request: OrderReturnRequest) -> ReturnValidati Validate if an order return reason is legitimate based on company policy. Valid reasons include: defective product, wrong item received, damaged in shipping, not as described, quality issues, size/fit issues (for clothing). - Invalid reasons include: changed mind after 30 days, buyer's remorse, + Invalid reasons include: changed mind after 30 days, buyer's remorse, found cheaper elsewhere, impulse purchase regret. """ - + # Simulate policy validation logic valid_reasons = [ - "defective", "damaged", "wrong item", "not as described", - "quality issues", "size issue", "fit issue", "broken", + "defective", "damaged", "wrong item", "not as described", + "quality issues", "size issue", "fit issue", "broken", "missing parts", "expired" ] - + invalid_reasons = [ "changed mind", "buyer's remorse", "found cheaper", "impulse purchase", "don't need", "financial reasons" ] - + reason_lower = return_request.return_reason.lower() - + # Check for valid reasons is_valid = any(valid_reason in reason_lower for valid_reason in valid_reasons) - + # Check for invalid reasons if any(invalid_reason in reason_lower for invalid_reason in invalid_reasons): is_valid = False - + # Calculate confidence based on keyword matching confidence = 0.8 if is_valid else 0.7 - + validation_reason = ( - "Return reason matches company policy for valid returns" if is_valid + "Return reason matches company policy for valid returns" if is_valid else "Return reason does not meet company return policy criteria" ) - + return ReturnValidationResult( is_valid=is_valid, reason=validation_reason, @@ -72,7 +72,7 @@ def validate_return_reason(return_request: OrderReturnRequest) -> ReturnValidati def main(return_request_data: dict): """Main function to run the order return validation agent""" - + agent = Agent( name="Order Return Validation Specialist", instructions=""" @@ -81,44 +81,44 @@ def main(return_request_data: dict): 2. Determine if the return reason is valid according to company policy 3. Provide clear reasoning for your decision 4. Be fair but firm in applying policy guidelines - + Valid return reasons typically include: - Defective or broken products - Wrong item shipped - - Damaged during shipping + - Damaged during shipping - Product not as described - Quality issues - Size/fit problems (for applicable items) - + Invalid return reasons typically include: - Changed mind without valid cause - Found item cheaper elsewhere - Buyer's remorse - Financial hardship - General dissatisfaction without specific issue - + Always use the validate_return_reason tool to check the policy compliance. Based on the tool result, clearly state if the return is VALID or INVALID. End your response with either "Return is VALID" or "Return is INVALID". """, tools=[validate_return_reason], ) - + # Convert dict to OrderReturnRequest return_request = OrderReturnRequest(**return_request_data) - + user_message = f""" Please validate this return request: - + Order ID: {return_request.order_id} - Customer ID: {return_request.customer_id} + Customer ID: {return_request.customer_id} Product Category: {return_request.product_category} Purchase Date: {return_request.purchase_date} Return Reason: {return_request.return_reason} - + Is this a valid return request according to our company policy? """ - + result = Runner.run_sync(agent, user_message) # Parse the agent's response to extract validation decision agent_response = result.final_output diff --git a/samples-v2/openai_agents/basic/refund_processing.py b/samples-v2/openai_agents/basic/refund_processing.py index c561d3ed..4c0718c6 100644 --- a/samples-v2/openai_agents/basic/refund_processing.py +++ b/samples-v2/openai_agents/basic/refund_processing.py @@ -22,11 +22,11 @@ def process_refund(order_id: str, refund_amount: float, customer_id: str) -> Ref Process a refund for a validated return request. This simulates calling payment processing systems. """ - + # Simulate refund processing import uuid transaction_id = f"REF-{uuid.uuid4().hex[:8].upper()}" - + return RefundResult( success=True, refund_amount=refund_amount, @@ -35,14 +35,13 @@ def process_refund(order_id: str, refund_amount: float, customer_id: str) -> Ref processing_time="3-5 business days" ) - -@function_tool +@function_tool def get_order_details(order_id: str) -> Dict[str, Any]: """ Retrieve order details for refund processing. This simulates calling order management systems. """ - + # Simulate order lookup return { "order_id": order_id, @@ -58,40 +57,40 @@ def get_order_details(order_id: str) -> Dict[str, Any]: def main(validation_data: dict): """Main function to process refund for validated return""" - + agent = Agent( - name="Refund Processing Specialist", + name="Refund Processing Specialist", instructions=""" You are a refund processing specialist. Your job is to: 1. Retrieve the order details for the validated return 2. Calculate the appropriate refund amount (usually full product cost + tax) 3. Process the refund through our payment systems 4. Provide confirmation details to the customer - + Always retrieve order details first, then process the refund. Be precise with refund amounts and provide clear transaction information. End your response with "REFUND SUCCESS" if the refund is processed successfully. """, tools=[get_order_details, process_refund], ) - + order_id = validation_data.get("order_id") customer_id = validation_data.get("customer_id", "unknown") - + user_message = f""" Process a refund for the validated return: Order ID: {order_id} Customer ID: {customer_id} - + Please: 1. Get the order details - 2. Calculate the refund amount (product cost + tax, excluding shipping) + 2. Calculate the refund amount (product cost + tax, excluding shipping) 3. Process the refund 4. Provide confirmation details """ result = Runner.run_sync(agent, user_message) - + # Parse the agent's response to extract refund status agent_response = result.final_output is_successful = "refund" in str(agent_response).lower() and "success" in str(agent_response).lower() @@ -101,7 +100,7 @@ def main(validation_data: dict): "success": is_successful, "refund_amount": 93.00, # Product + Tax (86.01 + 7.99) "transaction_id": f"REF-{hash(str(validation_data.get('order_id', ''))) % 10000:04d}", - "refund_method": "original_payment_method", + "refund_method": "original_payment_method", "processing_time": "3-5 business days" } diff --git a/samples-v2/openai_agents/function_app.py b/samples-v2/openai_agents/function_app.py index 1f52fde4..d9b8730b 100644 --- a/samples-v2/openai_agents/function_app.py +++ b/samples-v2/openai_agents/function_app.py @@ -10,6 +10,7 @@ from openai import AsyncAzureOpenAI from agents import set_default_openai_client +from order_return_orchestrators import register_order_return_orchestrators #region Regular Azure OpenAI setup @@ -36,6 +37,7 @@ def get_azure_token(): app = df.DFApp(http_auth_level=func.AuthLevel.FUNCTION) +register_order_return_orchestrators(app) @app.route(route="orchestrators/{functionName}") @app.durable_client_input(client_name="client") @@ -46,6 +48,24 @@ async def orchestration_starter(req: func.HttpRequest, client): response = client.create_check_status_response(req, instance_id) return response +@app.route(route="order_return_processor") +@app.durable_client_input(client_name="client") +async def orchestration_order_return_processor(req: func.HttpRequest, client): + # Extract input data from request body + input_data = None + try: + if req.get_body(): + input_data = req.get_json() + except Exception as e: + return func.HttpResponse( + f"Invalid JSON in request body: {str(e)}", + status_code=400 + ) + + # Starting a new orchestration instance with input data + instance_id = await client.start_new("order_return_processor", client_input=input_data) + response = client.create_check_status_response(req, instance_id) + return response @app.orchestration_trigger(context_name="context") @app.durable_openai_agent_orchestrator diff --git a/samples-v2/openai_agents/order_return_orchestrators.py b/samples-v2/openai_agents/order_return_orchestrators.py index 303d421b..4e81dd9b 100644 --- a/samples-v2/openai_agents/order_return_orchestrators.py +++ b/samples-v2/openai_agents/order_return_orchestrators.py @@ -6,7 +6,7 @@ def register_order_return_orchestrators(app: df.DFApp): """Register all order return related orchestrators and activities with the app""" - + @app.orchestration_trigger(context_name="context") def order_return_processor(context: df.DurableOrchestrationContext): """ @@ -15,20 +15,20 @@ def order_return_processor(context: df.DurableOrchestrationContext): 2. If valid, processes refund via another orchestration 3. If invalid, routes for human review """ - + # Get the input data (order return request) return_request_input = context.get_input() - + if not return_request_input: return { "status": "error", "message": "No return request data provided" } - + # Step 1: Validate the return reason using AI agent validation_task = context.call_sub_orchestrator("order_return_validation", return_request_input) validation_result = yield validation_task - + # Extract validation decision from agent response is_valid = False if validation_result: @@ -46,7 +46,7 @@ def order_return_processor(context: df.DurableOrchestrationContext): "validation_result": validation_result }) refund_result = yield refund_task - + return { "status": "approved_and_processed", "validation": validation_result, @@ -61,7 +61,7 @@ def order_return_processor(context: df.DurableOrchestrationContext): "reason": "Return reason does not meet policy criteria" }) review_result = yield human_review_task - + return { "status": "pending_human_review", "validation": validation_result, @@ -69,7 +69,7 @@ def order_return_processor(context: df.DurableOrchestrationContext): "message": "Return requires human review" } - @app.orchestration_trigger(context_name="context") + @app.orchestration_trigger(context_name="context") @app.durable_openai_agent_orchestrator def order_return_validation(context): """Sub-orchestration that validates return reasons using AI agent""" @@ -78,7 +78,7 @@ def order_return_validation(context): return basic.order_return_validation.main(return_request) @app.orchestration_trigger(context_name="context") - @app.durable_openai_agent_orchestrator + @app.durable_openai_agent_orchestrator def refund_processor(context): """Sub-orchestration that processes refunds using AI agent""" import basic.refund_processing @@ -88,20 +88,20 @@ def refund_processor(context): @app.activity_trigger(input_name="review_data") async def route_for_human_review(review_data: dict) -> dict: """Activity function that routes invalid returns for human review""" - + # In a real implementation, this would: # - Create a ticket in a support system # - Send notification to review team # - Update order status in database # - Send email to customer about review process - + review_ticket_id = f"REV-{uuid.uuid4().hex[:8].upper()}" - + # Simulate creating review ticket print(f"[HUMAN REVIEW] Created review ticket {review_ticket_id}") print(f"[HUMAN REVIEW] Order ID: {review_data['return_request'].get('order_id')}") print(f"[HUMAN REVIEW] Reason: {review_data.get('reason')}") - + return { "review_ticket_id": review_ticket_id, "status": "pending_review",