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 ,
@@ -186,14 +188,22 @@ async def input_task_endpoint(input_task: InputTask, request: Request):
186188 track_event_if_configured (
187189 "RAI failed" ,
188190 {
189- "status" : "Plan not created" ,
191+ "status" : "Plan not created - RAI validation failed " ,
190192 "description" : input_task .description ,
191193 "session_id" : input_task .session_id ,
192194 },
193195 )
194196
195197 return {
196- "status" : "Plan not created" ,
198+ "status" : "RAI_VALIDATION_FAILED" ,
199+ "message" : "Content Safety Check Failed" ,
200+ "detail" : "Your request contains content that doesn't meet our safety guidelines. Please modify your request to ensure it's appropriate and try again." ,
201+ "suggestions" : [
202+ "Remove any potentially harmful, inappropriate, or unsafe content" ,
203+ "Use more professional and constructive language" ,
204+ "Focus on legitimate business or educational objectives" ,
205+ "Ensure your request complies with content policies"
206+ ]
197207 }
198208 authenticated_user = get_authenticated_user_details (request_headers = request .headers )
199209 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,151 @@ 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 (generate_plan_request : GeneratePlanRequest , request : Request ):
446+ """
447+ Generate plan steps for an existing plan using the planner agent.
448+
449+ ---
450+ tags:
451+ - Plans
452+ parameters:
453+ - name: user_principal_id
454+ in: header
455+ type: string
456+ required: true
457+ description: User ID extracted from the authentication header
458+ - name: body
459+ in: body
460+ required: true
461+ schema:
462+ type: object
463+ properties:
464+ plan_id:
465+ type: string
466+ description: The ID of the existing plan to generate steps for
467+ responses:
468+ 200:
469+ description: Plan generation completed successfully
470+ schema:
471+ type: object
472+ properties:
473+ status:
474+ type: string
475+ description: Success message
476+ plan_id:
477+ type: string
478+ description: The ID of the plan that was generated
479+ steps_created:
480+ type: integer
481+ description: Number of steps created
482+ 400:
483+ description: Invalid request or processing error
484+ schema:
485+ type: object
486+ properties:
487+ detail:
488+ type: string
489+ description: Error message
490+ 404:
491+ description: Plan not found
492+ schema:
493+ type: object
494+ properties:
495+ detail:
496+ type: string
497+ description: Error message
498+ """
499+ # Get authenticated user
500+ authenticated_user = get_authenticated_user_details (request_headers = request .headers )
501+ user_id = authenticated_user ["user_principal_id" ]
502+
503+ if not user_id :
504+ track_event_if_configured (
505+ "UserIdNotFound" , {"status_code" : 400 , "detail" : "no user" }
506+ )
507+ raise HTTPException (status_code = 400 , detail = "no user" )
508+
509+ try :
510+ # Initialize memory store
511+ kernel , memory_store = await initialize_runtime_and_context ("" , user_id )
512+
513+ # Get the existing plan
514+ plan = await memory_store .get_plan_by_plan_id (plan_id = generate_plan_request .plan_id )
515+ if not plan :
516+ track_event_if_configured (
517+ "GeneratePlanNotFound" ,
518+ {"status_code" : 404 , "detail" : "Plan not found" , "plan_id" : generate_plan_request .plan_id }
519+ )
520+ raise HTTPException (status_code = 404 , detail = "Plan not found" )
521+
522+ # Create the agents for this session
523+ client = None
524+ try :
525+ client = config .get_ai_project_client ()
526+ except Exception as client_exc :
527+ logging .error (f"Error creating AIProjectClient: { client_exc } " )
528+
529+ agents = await AgentFactory .create_all_agents (
530+ session_id = plan .session_id ,
531+ user_id = user_id ,
532+ memory_store = memory_store ,
533+ client = client ,
534+ )
535+
536+ # Get the group chat manager to process the plan
537+ group_chat_manager = agents [AgentType .GROUP_CHAT_MANAGER .value ]
538+
539+ # Create an InputTask from the plan's initial goal
540+ input_task = InputTask (
541+ session_id = plan .session_id ,
542+ description = plan .initial_goal
543+ )
544+
545+ # Use the group chat manager to generate the plan steps
546+ await group_chat_manager .handle_input_task (input_task )
547+
548+ # Get the updated plan with steps
549+ updated_plan = await memory_store .get_plan_by_plan_id (plan_id = generate_plan_request .plan_id )
550+ steps = await memory_store .get_steps_by_plan (plan_id = generate_plan_request .plan_id )
551+
552+ # Log successful plan generation
553+ track_event_if_configured (
554+ "PlanGenerated" ,
555+ {
556+ "status" : f"Plan generation completed for plan ID: { generate_plan_request .plan_id } " ,
557+ "plan_id" : generate_plan_request .plan_id ,
558+ "session_id" : plan .session_id ,
559+ "steps_created" : len (steps ),
560+ },
561+ )
562+
563+ if client :
564+ try :
565+ client .close ()
566+ except Exception as e :
567+ logging .error (f"Error closing AIProjectClient: { e } " )
568+
569+ return {
570+ "status" : "Plan generation completed successfully" ,
571+ "plan_id" : generate_plan_request .plan_id ,
572+ "steps_created" : len (steps ),
573+ }
574+
575+ except HTTPException :
576+ # Re-raise HTTP exceptions
577+ raise
578+ except Exception as e :
579+ track_event_if_configured (
580+ "GeneratePlanError" ,
581+ {
582+ "plan_id" : generate_plan_request .plan_id ,
583+ "error" : str (e ),
584+ },
585+ )
586+ raise HTTPException (status_code = 400 , detail = f"Error generating plan: { e } " )
587+
588+
423589@app .post ("/api/human_feedback" )
424590async def human_feedback_endpoint (human_feedback : HumanFeedback , request : Request ):
425591 """
@@ -588,12 +754,26 @@ async def human_clarification_endpoint(
588754 track_event_if_configured (
589755 "RAI failed" ,
590756 {
591- "status" : "Clarification is not received " ,
757+ "status" : "Clarification rejected - RAI validation failed " ,
592758 "description" : human_clarification .human_clarification ,
593759 "session_id" : human_clarification .session_id ,
594760 },
595761 )
596- raise HTTPException (status_code = 400 , detail = "Invalida Clarification" )
762+ raise HTTPException (
763+ status_code = 400 ,
764+ detail = {
765+ "error_type" : "RAI_VALIDATION_FAILED" ,
766+ "message" : "Clarification Safety Check Failed" ,
767+ "description" : "Your clarification contains content that doesn't meet our safety guidelines. Please provide a more appropriate clarification." ,
768+ "suggestions" : [
769+ "Use clear and professional language" ,
770+ "Avoid potentially harmful or inappropriate content" ,
771+ "Focus on providing constructive feedback or clarification" ,
772+ "Ensure your message complies with content policies"
773+ ],
774+ "user_action" : "Please revise your clarification and try again"
775+ }
776+ )
597777
598778 authenticated_user = get_authenticated_user_details (request_headers = request .headers )
599779 user_id = authenticated_user ["user_principal_id" ]
0 commit comments