@@ -127,6 +127,132 @@ async def handle_action_request_wrapper(*args, **kwargs):
127127 # Use agent name as plugin for handler
128128 self ._kernel .add_function (self ._agent_name , kernel_func )
129129
130+ async def handle_action_request (self , action_request_json : str ) -> str :
131+ """Handle an action request from another agent or the system.
132+
133+ Args:
134+ action_request_json: The action request as a JSON string
135+
136+ Returns:
137+ A JSON string containing the action response
138+ """
139+ # Parse the action request
140+ action_request_dict = json .loads (action_request_json )
141+ action_request = ActionRequest (** action_request_dict )
142+
143+ # Get the step from memory
144+ step : Step = await self ._memory_store .get_step (
145+ action_request .step_id , action_request .session_id
146+ )
147+
148+ if not step :
149+ # Create error response if step not found
150+ response = ActionResponse (
151+ step_id = action_request .step_id ,
152+ status = StepStatus .failed ,
153+ message = "Step not found in memory." ,
154+ )
155+ return response .json ()
156+
157+ # Add messages to chat history for context
158+ # This gives the agent visibility of the conversation history
159+ self ._chat_history .extend ([
160+ {"role" : "assistant" , "content" : action_request .action },
161+ {"role" : "user" , "content" : f"{ step .human_feedback } . Now make the function call" }
162+ ])
163+
164+ try :
165+ # Use the agent to process the action
166+ chat_history = self ._chat_history .copy ()
167+
168+ # Call the agent to handle the action
169+ agent_response = await self ._agent .invoke (self ._kernel , f"{ action_request .action } \n \n Please perform this action" )
170+ result = str (agent_response )
171+
172+ # Store agent message in cosmos memory
173+ await self ._memory_store .add_item (
174+ AgentMessage (
175+ session_id = action_request .session_id ,
176+ user_id = self ._user_id ,
177+ plan_id = action_request .plan_id ,
178+ content = f"{ result } " ,
179+ source = self ._agent_name ,
180+ step_id = action_request .step_id ,
181+ )
182+ )
183+
184+ # Track telemetry
185+ track_event_if_configured (
186+ "Base agent - Added into the cosmos" ,
187+ {
188+ "session_id" : action_request .session_id ,
189+ "user_id" : self ._user_id ,
190+ "plan_id" : action_request .plan_id ,
191+ "content" : f"{ result } " ,
192+ "source" : self ._agent_name ,
193+ "step_id" : action_request .step_id ,
194+ },
195+ )
196+
197+ except Exception as e :
198+ logging .exception (f"Error during agent execution: { e } " )
199+
200+ # Track error in telemetry
201+ track_event_if_configured (
202+ "Base agent - Error during agent execution, captured into the cosmos" ,
203+ {
204+ "session_id" : action_request .session_id ,
205+ "user_id" : self ._user_id ,
206+ "plan_id" : action_request .plan_id ,
207+ "content" : f"{ e } " ,
208+ "source" : self ._agent_name ,
209+ "step_id" : action_request .step_id ,
210+ },
211+ )
212+
213+ # Return an error response
214+ response = ActionResponse (
215+ step_id = action_request .step_id ,
216+ plan_id = action_request .plan_id ,
217+ session_id = action_request .session_id ,
218+ result = f"Error: { str (e )} " ,
219+ status = StepStatus .failed ,
220+ )
221+ return response .json ()
222+
223+ logging .info (f"Task completed: { result } " )
224+
225+ # Update step status
226+ step .status = StepStatus .completed
227+ step .agent_reply = result
228+ await self ._memory_store .update_step (step )
229+
230+ # Track step completion in telemetry
231+ track_event_if_configured (
232+ "Base agent - Updated step and updated into the cosmos" ,
233+ {
234+ "status" : StepStatus .completed ,
235+ "session_id" : action_request .session_id ,
236+ "agent_reply" : f"{ result } " ,
237+ "user_id" : self ._user_id ,
238+ "plan_id" : action_request .plan_id ,
239+ "content" : f"{ result } " ,
240+ "source" : self ._agent_name ,
241+ "step_id" : action_request .step_id ,
242+ },
243+ )
244+
245+ # Create and return action response
246+ response = ActionResponse (
247+ step_id = step .id ,
248+ plan_id = step .plan_id ,
249+ session_id = action_request .session_id ,
250+ result = result ,
251+ status = StepStatus .completed ,
252+ )
253+
254+ return response .json ()
255+
130256 async def invoke_tool (self , tool_name : str , arguments : Dict [str , Any ]) -> str :
131257 """Invoke a specific tool by name with the provided arguments.
132258
@@ -275,6 +401,11 @@ def get_tools_from_config(cls, kernel: sk.Kernel, agent_type: str, config_path:
275401 kernel_functions = []
276402 plugin_name = f"{ agent_type } _plugin"
277403
404+ # Early return if no tools defined - prevent empty iteration
405+ if not config .get ("tools" ):
406+ logging .info (f"No tools defined for agent type '{ agent_type } '. Returning empty list." )
407+ return kernel_functions
408+
278409 for tool in config .get ("tools" , []):
279410 try :
280411 function_name = tool ["name" ]
@@ -301,8 +432,22 @@ def get_tools_from_config(cls, kernel: sk.Kernel, agent_type: str, config_path:
301432 # Register the function with the kernel
302433 kernel .add_function (plugin_name , kernel_func )
303434 kernel_functions .append (kernel_func )
304- # logging.info (f"Successfully created dynamic tool '{function_name}' for {agent_type}")
435+ logging .debug (f"Successfully created dynamic tool '{ function_name } ' for { agent_type } " )
305436 except Exception as e :
306437 logging .error (f"Failed to create tool '{ tool .get ('name' , 'unknown' )} ': { str (e )} " )
307438
308- return kernel_functions
439+ # Log the total number of tools created
440+ if kernel_functions :
441+ logging .info (f"Created { len (kernel_functions )} tools for agent type '{ agent_type } '" )
442+ else :
443+ logging .info (f"No tools were successfully created for agent type '{ agent_type } '" )
444+
445+ return kernel_functions
446+
447+ def save_state (self ) -> Mapping [str , Any ]:
448+ """Save the state of this agent."""
449+ return {"memory" : self ._memory_store .save_state ()}
450+
451+ def load_state (self , state : Mapping [str , Any ]) -> None :
452+ """Load the state of this agent."""
453+ self ._memory_store .load_state (state ["memory" ])
0 commit comments