Skip to content

Commit 20627dd

Browse files
authored
Merge pull request microsoft#113 from Fr4nc3/main
Fix planner instructions
2 parents 658bc27 + a044c88 commit 20627dd

File tree

6 files changed

+73
-3485
lines changed

6 files changed

+73
-3485
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,3 +458,4 @@ __pycache__/
458458
*.whl
459459
!autogen_core-0.3.dev0-py3-none-any.whl
460460
.azure
461+
.github/copilot-instructions.md

src/backend/app_kernel.py

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
logging.info("Added health check middleware")
8484

8585

86-
@app.post("/input_task")
86+
@app.post("/api/input_task")
8787
async def input_task_endpoint(input_task: InputTask, request: Request):
8888
"""
8989
Receive the initial input task from the user.
@@ -175,7 +175,7 @@ async def input_task_endpoint(input_task: InputTask, request: Request):
175175
raise HTTPException(status_code=400, detail="Error creating plan")
176176

177177

178-
@app.post("/human_feedback")
178+
@app.post("/api/human_feedback")
179179
async def human_feedback_endpoint(human_feedback: HumanFeedback, request: Request):
180180

181181
"""
@@ -268,7 +268,7 @@ async def human_feedback_endpoint(human_feedback: HumanFeedback, request: Reques
268268
}
269269

270270

271-
@app.post("/human_clarification_on_plan")
271+
@app.post("/api/human_clarification_on_plan")
272272
async def human_clarification_endpoint(
273273
human_clarification: HumanClarification, request: Request
274274
):
@@ -349,7 +349,7 @@ async def human_clarification_endpoint(
349349
}
350350

351351

352-
@app.post("/approve_step_or_steps")
352+
@app.post("/api/approve_step_or_steps")
353353
async def approve_step_endpoint(
354354
human_feedback: HumanFeedback, request: Request
355355
) -> Dict[str, str]:
@@ -453,7 +453,7 @@ async def approve_step_endpoint(
453453
return {"status": "All steps approved"}
454454

455455

456-
@app.get("/plans", response_model=List[PlanWithSteps])
456+
@app.get("/api/plans", response_model=List[PlanWithSteps])
457457
async def get_plans(
458458
request: Request, session_id: Optional[str] = Query(None)
459459
) -> List[PlanWithSteps]:
@@ -553,7 +553,7 @@ async def get_plans(
553553
return list_of_plans_with_steps
554554

555555

556-
@app.get("/steps/{plan_id}", response_model=List[Step])
556+
@app.get("/api/steps/{plan_id}", response_model=List[Step])
557557
async def get_steps_by_plan(plan_id: str, request: Request) -> List[Step]:
558558
"""
559559
Retrieve steps for a specific plan.
@@ -616,7 +616,7 @@ async def get_steps_by_plan(plan_id: str, request: Request) -> List[Step]:
616616
return steps
617617

618618

619-
@app.get("/agent_messages/{session_id}", response_model=List[AgentMessage])
619+
@app.get("/api/agent_messages/{session_id}", response_model=List[AgentMessage])
620620
async def get_agent_messages(session_id: str, request: Request) -> List[AgentMessage]:
621621
"""
622622
Retrieve agent messages for a specific session.
@@ -680,7 +680,7 @@ async def get_agent_messages(session_id: str, request: Request) -> List[AgentMes
680680
return agent_messages
681681

682682

683-
@app.delete("/messages")
683+
@app.delete("/api/messages")
684684
async def delete_all_messages(request: Request) -> Dict[str, str]:
685685
"""
686686
Delete all messages across sessions.
@@ -723,7 +723,7 @@ async def delete_all_messages(request: Request) -> Dict[str, str]:
723723
return {"status": "All messages deleted"}
724724

725725

726-
@app.get("/messages")
726+
@app.get("/api/messages")
727727
async def get_all_messages(request: Request):
728728
"""
729729
Retrieve all messages across sessions.
@@ -804,39 +804,6 @@ async def get_agent_tools():
804804
return []
805805

806806

807-
# Initialize the application when it starts
808-
@app.on_event("startup")
809-
async def startup_event():
810-
"""Initialize the application on startup.
811-
812-
This function runs when the FastAPI application starts up.
813-
It sets up the agent types and tool loaders so the first request is faster.
814-
"""
815-
# Log startup
816-
logging.info("Application starting up. Initializing agent factory...")
817-
818-
try:
819-
# Create a temporary session and user ID to pre-initialize agents
820-
# This ensures tools are loaded into the factory on startup
821-
temp_session_id = "startup-session"
822-
temp_user_id = "startup-user"
823-
824-
# Create a test agent to initialize the tool loading system
825-
# This will pre-load tool configurations into memory
826-
test_agent = await AgentFactory.create_agent(
827-
agent_type=AgentType.GENERIC,
828-
session_id=temp_session_id,
829-
user_id=temp_user_id
830-
)
831-
832-
# Clean up initialization resources
833-
AgentFactory.clear_cache(temp_session_id)
834-
logging.info("Agent factory successfully initialized")
835-
836-
except Exception as e:
837-
# Don't fail startup, but log the error
838-
logging.error(f"Error initializing agent factory: {e}")
839-
840807

841808
# Run the app
842809
if __name__ == "__main__":

src/backend/kernel_agents/planner_agent.py

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,17 @@ async def async_init(self) -> None:
147147
"""
148148
try:
149149
logging.info("Initializing PlannerAgent from async init azure AI Agent")
150-
# Create the Azure AI Agent using AppConfig
150+
151+
# Generate instructions as a string rather than returning an object
152+
# We'll use a blank input since this is just for initialization
153+
instruction_args = self._generate_instruction("")
154+
instructions = self._get_template().format(**instruction_args)
155+
156+
# Create the Azure AI Agent using AppConfig with string instructions
151157
self._azure_ai_agent = await config.create_azure_ai_agent(
152158
kernel=self._kernel,
153159
agent_name="PlannerAgent",
154-
instructions=self._generate_instruction(""),
160+
instructions=instructions, # Pass the formatted string, not an object
155161
temperature=0.0
156162
)
157163
logging.info("Successfully created Azure AI Agent for PlannerAgent")
@@ -311,8 +317,11 @@ async def _create_structured_plan(self, input_task: InputTask) -> Tuple[Plan, Li
311317
logging.debug(f"Input: {input_task}")
312318
logging.debug(f"Available agents: {self._available_agents}")
313319

314-
instruction = self._generate_instruction(input_task.description)
320+
# Get template variables as a dictionary
321+
args = self._generate_instruction(input_task.description)
315322

323+
# Format the template with the arguments
324+
instruction = self._get_template().format(**args)
316325
logging.info(f"Generated instruction: {instruction}")
317326
# Log the input task for debugging
318327
logging.info(f"Creating plan for task: '{input_task.description}'")
@@ -651,14 +660,14 @@ async def _create_fallback_plan_from_text(self, input_task: InputTask, text_cont
651660

652661
return plan, steps
653662

654-
def _generate_instruction(self, objective: str) -> str:
663+
def _generate_instruction(self, objective: str) -> any:
655664
"""Generate instruction for the LLM to create a plan.
656665
657666
Args:
658667
objective: The user's objective
659668
660669
Returns:
661-
Instruction string for the LLM
670+
Dictionary containing the variables to populate the template
662671
"""
663672
# Create a list of available agents
664673
agents_str = ", ".join(self._available_agents)
@@ -766,53 +775,62 @@ def _generate_instruction(self, objective: str) -> str:
766775
# Convert the tools list to a string representation
767776
tools_str = str(tools_list)
768777

769-
# Build the instruction, avoiding backslashes in f-string expressions
778+
# Return a dictionary with template variables
779+
return {
780+
"objective": objective,
781+
"agents_str": agents_str,
782+
"tools_str": tools_str,
783+
}
784+
785+
def _get_template(self):
786+
"""Generate the instruction template for the LLM."""
787+
# Build the instruction with proper format placeholders for .format() method
770788

771-
instruction_template = f"""
772-
You are the Planner, an AI orchestrator that manages a group of AI agents to accomplish tasks.
789+
instruction_template = """
790+
You are the Planner, an AI orchestrator that manages a group of AI agents to accomplish tasks.
773791
774-
For the given objective, come up with a simple step-by-step plan.
775-
This plan should involve individual tasks that, if executed correctly, will yield the correct answer. Do not add any superfluous steps.
776-
The result of the final step should be the final answer. Make sure that each step has all the information needed - do not skip steps.
792+
For the given objective, come up with a simple step-by-step plan.
793+
This plan should involve individual tasks that, if executed correctly, will yield the correct answer. Do not add any superfluous steps.
794+
The result of the final step should be the final answer. Make sure that each step has all the information needed - do not skip steps.
777795
778-
These actions are passed to the specific agent. Make sure the action contains all the information required for the agent to execute the task.
779-
780-
Your objective is:
781-
{objective}
796+
These actions are passed to the specific agent. Make sure the action contains all the information required for the agent to execute the task.
797+
798+
Your objective is:
799+
{objective}
782800
783-
The agents you have access to are:
784-
{agents_str}
801+
The agents you have access to are:
802+
{agents_str}
785803
786-
These agents have access to the following functions:
787-
{tools_str}
804+
These agents have access to the following functions:
805+
{tools_str}
788806
789-
IMPORTANT AGENT SELECTION GUIDANCE:
790-
- HrAgent: ALWAYS use for ALL employee-related tasks like onboarding, hiring, benefits, payroll, training, employee records, ID cards, mentoring, background checks, etc.
791-
- MarketingAgent: Use for marketing campaigns, branding, market research, content creation, social media, etc.
792-
- ProcurementAgent: Use for purchasing, vendor management, supply chain, asset management, etc.
793-
- ProductAgent: Use for product development, roadmaps, features, product feedback, etc.
794-
- TechSupportAgent: Use for technical issues, software/hardware setup, troubleshooting, IT support, etc.
795-
- GenericAgent: Use only for general knowledge tasks that don't fit other categories
796-
- HumanAgent: Use only when human input is absolutely required and no other agent can handle the task
807+
IMPORTANT AGENT SELECTION GUIDANCE:
808+
- HrAgent: ALWAYS use for ALL employee-related tasks like onboarding, hiring, benefits, payroll, training, employee records, ID cards, mentoring, background checks, etc.
809+
- MarketingAgent: Use for marketing campaigns, branding, market research, content creation, social media, etc.
810+
- ProcurementAgent: Use for purchasing, vendor management, supply chain, asset management, etc.
811+
- ProductAgent: Use for product development, roadmaps, features, product feedback, etc.
812+
- TechSupportAgent: Use for technical issues, software/hardware setup, troubleshooting, IT support, etc.
813+
- GenericAgent: Use only for general knowledge tasks that don't fit other categories
814+
- HumanAgent: Use only when human input is absolutely required and no other agent can handle the task
797815
798-
The first step of your plan should be to ask the user for any additional information required to progress the rest of steps planned.
816+
The first step of your plan should be to ask the user for any additional information required to progress the rest of steps planned.
799817
800-
Only use the functions provided as part of your plan. If the task is not possible with the agents and tools provided, create a step with the agent of type Exception and mark the overall status as completed.
818+
Only use the functions provided as part of your plan. If the task is not possible with the agents and tools provided, create a step with the agent of type Exception and mark the overall status as completed.
801819
802-
Do not add superfluous steps - only take the most direct path to the solution, with the minimum number of steps. Only do the minimum necessary to complete the goal.
820+
Do not add superfluous steps - only take the most direct path to the solution, with the minimum number of steps. Only do the minimum necessary to complete the goal.
803821
804-
If there is a single function call that can directly solve the task, only generate a plan with a single step. For example, if someone asks to be granted access to a database, generate a plan with only one step involving the grant_database_access function, with no additional steps.
822+
If there is a single function call that can directly solve the task, only generate a plan with a single step. For example, if someone asks to be granted access to a database, generate a plan with only one step involving the grant_database_access function, with no additional steps.
805823
806-
You must prioritise using the provided functions to accomplish each step. First evaluate each and every function the agents have access too. Only if you cannot find a function needed to complete the task, and you have reviewed each and every function, and determined why each are not suitable, there are two options you can take when generating the plan.
807-
First evaluate whether the step could be handled by a typical large language model, without any specialised functions. For example, tasks such as "add 32 to 54", or "convert this SQL code to a python script", or "write a 200 word story about a fictional product strategy".
824+
You must prioritize using the provided functions to accomplish each step. First evaluate each and every function the agents have access too. Only if you cannot find a function needed to complete the task, and you have reviewed each and every function, and determined why each are not suitable, there are two options you can take when generating the plan.
825+
First evaluate whether the step could be handled by a typical large language model, without any specialized functions. For example, tasks such as "add 32 to 54", or "convert this SQL code to a python script", or "write a 200 word story about a fictional product strategy".
808826
809-
If a general Large Language Model CAN handle the step/required action, add a step to the plan with the action you believe would be needed, and add "EXCEPTION: No suitable function found. A generic LLM model is being used for this step." to the end of the action. Assign these steps to the GenericAgent. For example, if the task is to convert the following SQL into python code (SELECT * FROM employees;), and there is no function to convert SQL to python, write a step with the action "convert the following SQL into python code (SELECT * FROM employees;) EXCEPTION: No suitable function found. A generic LLM model is being used for this step." and assign it to the GenericAgent.
827+
If a general Large Language Model CAN handle the step/required action, add a step to the plan with the action you believe would be needed, and add "EXCEPTION: No suitable function found. A generic LLM model is being used for this step." to the end of the action. Assign these steps to the GenericAgent. For example, if the task is to convert the following SQL into python code (SELECT * FROM employees;), and there is no function to convert SQL to python, write a step with the action "convert the following SQL into python code (SELECT * FROM employees;) EXCEPTION: No suitable function found. A generic LLM model is being used for this step." and assign it to the GenericAgent.
810828
811-
Alternatively, if a general Large Language Model CAN NOT handle the step/required action, add a step to the plan with the action you believe would be needed, and add "EXCEPTION: Human support required to do this step, no suitable function found." to the end of the action. Assign these steps to the HumanAgent. For example, if the task is to find the best way to get from A to B, and there is no function to calculate the best route, write a step with the action "Calculate the best route from A to B. EXCEPTION: Human support required, no suitable function found." and assign it to the HumanAgent.
829+
Alternatively, if a general Large Language Model CAN NOT handle the step/required action, add a step to the plan with the action you believe would be needed, and add "EXCEPTION: Human support required to do this step, no suitable function found." to the end of the action. Assign these steps to the HumanAgent. For example, if the task is to find the best way to get from A to B, and there is no function to calculate the best route, write a step with the action "Calculate the best route from A to B. EXCEPTION: Human support required, no suitable function found." and assign it to the HumanAgent.
812830
813-
Limit the plan to 6 steps or less.
831+
Limit the plan to 6 steps or less.
814832
815-
Choose from {agents_str} ONLY for planning your steps.
833+
Choose from {agents_str} ONLY for planning your steps.
816834
817-
"""
835+
"""
818836
return instruction_template

0 commit comments

Comments
 (0)