@@ -76,7 +76,7 @@ def load_agent(self, config: Dict[str, Any], cache_key: Optional[str] = None) ->
7676 """Load an Agent from a dictionary configuration.
7777
7878 Args:
79- config: Dictionary containing agent configuration.
79+ config: Dictionary containing agent configuration with top-level 'agent' key .
8080 cache_key: Optional key for caching the loaded agent.
8181
8282 Returns:
@@ -86,6 +86,14 @@ def load_agent(self, config: Dict[str, Any], cache_key: Optional[str] = None) ->
8686 ValueError: If required configuration is missing or invalid.
8787 ImportError: If specified models or tools cannot be imported.
8888 """
89+ # Validate top-level structure
90+ if "agent" not in config :
91+ raise ValueError ("Configuration must contain a top-level 'agent' key" )
92+
93+ agent_config = config ["agent" ]
94+ if not isinstance (agent_config , dict ):
95+ raise ValueError ("The 'agent' configuration must be a dictionary" )
96+
8997 # Check cache first
9098 if cache_key and cache_key in self ._agent_cache :
9199 logger .debug ("agent_cache_key=<%s> | found in cache" , cache_key )
@@ -100,30 +108,30 @@ def load_agent(self, config: Dict[str, Any], cache_key: Optional[str] = None) ->
100108 if "structured_output_defaults" in config :
101109 self ._structured_output_defaults = config ["structured_output_defaults" ]
102110
103- # Extract configuration values
104- model_config = config .get ("model" )
105- system_prompt = config .get ("system_prompt" )
106- tools_config = config .get ("tools" , [])
107- messages_config = config .get ("messages" , [])
111+ # Extract configuration values from agent_config
112+ model_config = agent_config .get ("model" )
113+ system_prompt = agent_config .get ("system_prompt" )
114+ tools_config = agent_config .get ("tools" , [])
115+ messages_config = agent_config .get ("messages" , [])
108116
109117 # Note: 'prompt' field is handled by AgentAsToolWrapper, not by Agent itself
110118 # The Agent class doesn't have a prompt parameter - it uses system_prompt
111119 # The prompt field is used for tool invocation templates
112120
113121 # Agent metadata
114- agent_id = config .get ("agent_id" )
115- name = config .get ("name" )
116- description = config .get ("description" )
122+ agent_id = agent_config .get ("agent_id" )
123+ name = agent_config .get ("name" )
124+ description = agent_config .get ("description" )
117125
118126 # Advanced configuration
119- callback_handler_config = config .get ("callback_handler" )
120- conversation_manager_config = config .get ("conversation_manager" )
121- record_direct_tool_call = config .get ("record_direct_tool_call" , True )
122- load_tools_from_directory = config .get ("load_tools_from_directory" , False )
123- trace_attributes = config .get ("trace_attributes" )
124- state_config = config .get ("state" )
125- hooks_config = config .get ("hooks" , [])
126- session_manager_config = config .get ("session_manager" )
127+ callback_handler_config = agent_config .get ("callback_handler" )
128+ conversation_manager_config = agent_config .get ("conversation_manager" )
129+ record_direct_tool_call = agent_config .get ("record_direct_tool_call" , True )
130+ load_tools_from_directory = agent_config .get ("load_tools_from_directory" , False )
131+ trace_attributes = agent_config .get ("trace_attributes" )
132+ state_config = agent_config .get ("state" )
133+ hooks_config = agent_config .get ("hooks" , [])
134+ session_manager_config = agent_config .get ("session_manager" )
127135
128136 # Load model
129137 model = self ._load_model (model_config )
@@ -169,8 +177,8 @@ def load_agent(self, config: Dict[str, Any], cache_key: Optional[str] = None) ->
169177 )
170178
171179 # Configure structured output if specified
172- if "structured_output" in config :
173- self ._configure_agent_structured_output (agent , config ["structured_output" ])
180+ if "structured_output" in agent_config :
181+ self ._configure_agent_structured_output (agent , agent_config ["structured_output" ])
174182
175183 # Cache the agent if cache key provided
176184 if cache_key :
@@ -186,56 +194,56 @@ def serialize_agent(self, agent: Agent) -> Dict[str, Any]:
186194 agent: Agent instance to serialize.
187195
188196 Returns:
189- Dictionary containing the agent's configuration.
197+ Dictionary containing the agent's configuration with top-level 'agent' key .
190198
191199 Note:
192200 The 'prompt' field is not serialized here as it's specific to AgentAsToolWrapper
193201 and not part of the core Agent configuration.
194202 """
195- config = {}
203+ agent_config = {}
196204
197205 # Basic configuration
198206 if hasattr (agent .model , "model_id" ):
199- config ["model" ] = agent .model .model_id
207+ agent_config ["model" ] = agent .model .model_id
200208 elif hasattr (agent .model , "config" ) and agent .model .config .get ("model_id" ):
201- config ["model" ] = agent .model .config ["model_id" ]
209+ agent_config ["model" ] = agent .model .config ["model_id" ]
202210
203211 if agent .system_prompt :
204- config ["system_prompt" ] = agent .system_prompt
212+ agent_config ["system_prompt" ] = agent .system_prompt
205213
206214 # Tools configuration
207215 if hasattr (agent , "tool_registry" ) and agent .tool_registry :
208216 tools_config = []
209217 for tool_name in agent .tool_names :
210218 tools_config .append ({"name" : tool_name })
211219 if tools_config :
212- config ["tools" ] = tools_config
220+ agent_config ["tools" ] = tools_config
213221
214222 # Messages
215223 if agent .messages :
216- config ["messages" ] = agent .messages
224+ agent_config ["messages" ] = agent .messages
217225
218226 # Agent metadata
219227 if agent .agent_id != "default" :
220- config ["agent_id" ] = agent .agent_id
228+ agent_config ["agent_id" ] = agent .agent_id
221229 if agent .name != "Strands Agents" :
222- config ["name" ] = agent .name
230+ agent_config ["name" ] = agent .name
223231 if agent .description :
224- config ["description" ] = agent .description
232+ agent_config ["description" ] = agent .description
225233
226234 # Advanced configuration
227235 if agent .record_direct_tool_call is not True :
228- config ["record_direct_tool_call" ] = agent .record_direct_tool_call
236+ agent_config ["record_direct_tool_call" ] = agent .record_direct_tool_call
229237 if agent .load_tools_from_directory is not False :
230- config ["load_tools_from_directory" ] = agent .load_tools_from_directory
238+ agent_config ["load_tools_from_directory" ] = agent .load_tools_from_directory
231239 if agent .trace_attributes :
232- config ["trace_attributes" ] = agent .trace_attributes
240+ agent_config ["trace_attributes" ] = agent .trace_attributes
233241
234242 # State
235243 if agent .state and agent .state .get ():
236- config ["state" ] = agent .state .get ()
244+ agent_config ["state" ] = agent .state .get ()
237245
238- return config
246+ return { "agent" : agent_config }
239247
240248 def _load_model (self , model_config : Optional [Union [str , Dict [str , Any ]]]) -> Optional [Model ]:
241249 """Load a model from configuration.
0 commit comments