33import json
44import logging
55import os
6+ import re
67import uuid
78from typing import Dict , List , Optional
89
2728from models .messages_kernel import (
2829 AgentMessage ,
2930 AgentType ,
31+ GeneratePlanRequest ,
3032 HumanClarification ,
3133 HumanFeedback ,
3234 InputTask ,
@@ -188,14 +190,22 @@ async def input_task_endpoint(input_task: InputTask, request: Request):
188190 track_event_if_configured (
189191 "RAI failed" ,
190192 {
191- "status" : "Plan not created" ,
193+ "status" : "Plan not created - RAI validation failed " ,
192194 "description" : input_task .description ,
193195 "session_id" : input_task .session_id ,
194196 },
195197 )
196198
197199 return {
198- "status" : "Plan not created" ,
200+ "status" : "RAI_VALIDATION_FAILED" ,
201+ "message" : "Content Safety Check Failed" ,
202+ "detail" : "Your request contains content that doesn't meet our safety guidelines. Please modify your request to ensure it's appropriate and try again." ,
203+ "suggestions" : [
204+ "Remove any potentially harmful, inappropriate, or unsafe content" ,
205+ "Use more professional and constructive language" ,
206+ "Focus on legitimate business or educational objectives" ,
207+ "Ensure your request complies with content policies" ,
208+ ],
199209 }
200210 authenticated_user = get_authenticated_user_details (request_headers = request .headers )
201211 user_id = authenticated_user ["user_principal_id" ]
@@ -345,7 +355,7 @@ async def create_plan_endpoint(input_task: InputTask, request: Request):
345355 description: Error message
346356 """
347357 # Perform RAI check on the description
348- if not await rai_success (input_task .description ):
358+ if not await rai_success (input_task .description , False ):
349359 track_event_if_configured (
350360 "RAI failed" ,
351361 {
@@ -356,7 +366,18 @@ async def create_plan_endpoint(input_task: InputTask, request: Request):
356366 )
357367 raise HTTPException (
358368 status_code = 400 ,
359- detail = "Task description failed safety validation. Please revise your request." ,
369+ detail = {
370+ "error_type" : "RAI_VALIDATION_FAILED" ,
371+ "message" : "Content Safety Check Failed" ,
372+ "description" : "Your request contains content that doesn't meet our safety guidelines. Please modify your request to ensure it's appropriate and try again." ,
373+ "suggestions" : [
374+ "Remove any potentially harmful, inappropriate, or unsafe content" ,
375+ "Use more professional and constructive language" ,
376+ "Focus on legitimate business or educational objectives" ,
377+ "Ensure your request complies with content policies" ,
378+ ],
379+ "user_action" : "Please revise your request and try again" ,
380+ },
360381 )
361382
362383 # Get authenticated user
@@ -420,6 +441,162 @@ async def create_plan_endpoint(input_task: InputTask, request: Request):
420441 raise HTTPException (status_code = 400 , detail = f"Error creating plan: { e } " )
421442
422443
444+ @app .post ("/api/generate_plan" )
445+ async def generate_plan_endpoint (
446+ generate_plan_request : GeneratePlanRequest , request : Request
447+ ):
448+ """
449+ Generate plan steps for an existing plan using the planner agent.
450+
451+ ---
452+ tags:
453+ - Plans
454+ parameters:
455+ - name: user_principal_id
456+ in: header
457+ type: string
458+ required: true
459+ description: User ID extracted from the authentication header
460+ - name: body
461+ in: body
462+ required: true
463+ schema:
464+ type: object
465+ properties:
466+ plan_id:
467+ type: string
468+ description: The ID of the existing plan to generate steps for
469+ responses:
470+ 200:
471+ description: Plan generation completed successfully
472+ schema:
473+ type: object
474+ properties:
475+ status:
476+ type: string
477+ description: Success message
478+ plan_id:
479+ type: string
480+ description: The ID of the plan that was generated
481+ steps_created:
482+ type: integer
483+ description: Number of steps created
484+ 400:
485+ description: Invalid request or processing error
486+ schema:
487+ type: object
488+ properties:
489+ detail:
490+ type: string
491+ description: Error message
492+ 404:
493+ description: Plan not found
494+ schema:
495+ type: object
496+ properties:
497+ detail:
498+ type: string
499+ description: Error message
500+ """
501+ # Get authenticated user
502+ authenticated_user = get_authenticated_user_details (request_headers = request .headers )
503+ user_id = authenticated_user ["user_principal_id" ]
504+
505+ if not user_id :
506+ track_event_if_configured (
507+ "UserIdNotFound" , {"status_code" : 400 , "detail" : "no user" }
508+ )
509+ raise HTTPException (status_code = 400 , detail = "no user" )
510+
511+ try :
512+ # Initialize memory store
513+ kernel , memory_store = await initialize_runtime_and_context ("" , user_id )
514+
515+ # Get the existing plan
516+ plan = await memory_store .get_plan_by_plan_id (
517+ plan_id = generate_plan_request .plan_id
518+ )
519+ if not plan :
520+ track_event_if_configured (
521+ "GeneratePlanNotFound" ,
522+ {
523+ "status_code" : 404 ,
524+ "detail" : "Plan not found" ,
525+ "plan_id" : generate_plan_request .plan_id ,
526+ },
527+ )
528+ raise HTTPException (status_code = 404 , detail = "Plan not found" )
529+
530+ # Create the agents for this session
531+ client = None
532+ try :
533+ client = config .get_ai_project_client ()
534+ except Exception as client_exc :
535+ logging .error (f"Error creating AIProjectClient: { client_exc } " )
536+
537+ agents = await AgentFactory .create_all_agents (
538+ session_id = plan .session_id ,
539+ user_id = user_id ,
540+ memory_store = memory_store ,
541+ client = client ,
542+ )
543+
544+ # Get the group chat manager to process the plan
545+ group_chat_manager = agents [AgentType .GROUP_CHAT_MANAGER .value ]
546+
547+ # Create an InputTask from the plan's initial goal
548+ input_task = InputTask (
549+ session_id = plan .session_id , description = plan .initial_goal
550+ )
551+
552+ # Use the group chat manager to generate the plan steps
553+ await group_chat_manager .handle_input_task (input_task )
554+
555+ # Get the updated plan with steps
556+ updated_plan = await memory_store .get_plan_by_plan_id (
557+ plan_id = generate_plan_request .plan_id
558+ )
559+ steps = await memory_store .get_steps_by_plan (
560+ plan_id = generate_plan_request .plan_id
561+ )
562+
563+ # Log successful plan generation
564+ track_event_if_configured (
565+ "PlanGenerated" ,
566+ {
567+ "status" : f"Plan generation completed for plan ID: { generate_plan_request .plan_id } " ,
568+ "plan_id" : generate_plan_request .plan_id ,
569+ "session_id" : plan .session_id ,
570+ "steps_created" : len (steps ),
571+ },
572+ )
573+
574+ if client :
575+ try :
576+ client .close ()
577+ except Exception as e :
578+ logging .error (f"Error closing AIProjectClient: { e } " )
579+
580+ return {
581+ "status" : "Plan generation completed successfully" ,
582+ "plan_id" : generate_plan_request .plan_id ,
583+ "steps_created" : len (steps ),
584+ }
585+
586+ except HTTPException :
587+ # Re-raise HTTP exceptions
588+ raise
589+ except Exception as e :
590+ track_event_if_configured (
591+ "GeneratePlanError" ,
592+ {
593+ "plan_id" : generate_plan_request .plan_id ,
594+ "error" : str (e ),
595+ },
596+ )
597+ raise HTTPException (status_code = 400 , detail = f"Error generating plan: { e } " )
598+
599+
423600@app .post ("/api/human_feedback" )
424601async def human_feedback_endpoint (human_feedback : HumanFeedback , request : Request ):
425602 """
@@ -588,12 +765,26 @@ async def human_clarification_endpoint(
588765 track_event_if_configured (
589766 "RAI failed" ,
590767 {
591- "status" : "Clarification is not received " ,
768+ "status" : "Clarification rejected - RAI validation failed " ,
592769 "description" : human_clarification .human_clarification ,
593770 "session_id" : human_clarification .session_id ,
594771 },
595772 )
596- raise HTTPException (status_code = 400 , detail = "Invalida Clarification" )
773+ raise HTTPException (
774+ status_code = 400 ,
775+ detail = {
776+ "error_type" : "RAI_VALIDATION_FAILED" ,
777+ "message" : "Clarification Safety Check Failed" ,
778+ "description" : "Your clarification contains content that doesn't meet our safety guidelines. Please provide a more appropriate clarification." ,
779+ "suggestions" : [
780+ "Use clear and professional language" ,
781+ "Avoid potentially harmful or inappropriate content" ,
782+ "Focus on providing constructive feedback or clarification" ,
783+ "Ensure your message complies with content policies" ,
784+ ],
785+ "user_action" : "Please revise your clarification and try again" ,
786+ },
787+ )
597788
598789 authenticated_user = get_authenticated_user_details (request_headers = request .headers )
599790 user_id = authenticated_user ["user_principal_id" ]
0 commit comments