3535 BASIC_CATALOG_NAME ,
3636 find_repo_root ,
3737)
38- from .catalog import CustomCatalogConfig , A2uiCatalog
38+ from .catalog import CatalogConfig , A2uiCatalog
3939from ...extension .a2ui_extension import INLINE_CATALOGS_KEY , SUPPORTED_CATALOG_IDS_KEY , get_a2ui_agent_extension
4040from a2a .types import AgentExtension
4141
@@ -118,30 +118,26 @@ class A2uiSchemaManager(InferenceStrategy):
118118 def __init__ (
119119 self ,
120120 version : str ,
121- basic_examples_path : Optional [str ] = None ,
122- custom_catalogs : Optional [List [CustomCatalogConfig ]] = None ,
123- exclude_basic_catalog : bool = False ,
121+ catalogs : List [CatalogConfig ] = [],
124122 accepts_inline_catalogs : bool = False ,
125- schema_modifiers : List [Callable [[Dict [str , Any ]], Dict [str , Any ]]] = None ,
123+ schema_modifiers : List [Callable [[Dict [str , Any ]], Dict [str , Any ]]] = [] ,
126124 ):
127125 self ._version = version
128- self ._exclude_basic_catalog = exclude_basic_catalog
129126 self ._accepts_inline_catalogs = accepts_inline_catalogs
130127
131128 self ._server_to_client_schema = None
132129 self ._common_types_schema = None
133- self ._supported_catalogs : Dict [ str , A2uiCatalog ] = {}
130+ self ._supported_catalogs : List [ A2uiCatalog ] = []
134131 self ._catalog_example_paths : Dict [str , str ] = {}
135- self ._basic_catalog = None
136132 self ._schema_modifiers = schema_modifiers
137- self ._load_schemas (version , custom_catalogs , basic_examples_path )
133+ self ._load_schemas (version , catalogs )
138134
139135 @property
140136 def accepts_inline_catalogs (self ) -> bool :
141137 return self ._accepts_inline_catalogs
142138
143139 @property
144- def supported_catalogs (self ) -> Dict [ str , A2uiCatalog ]:
140+ def supported_catalogs (self ) -> List [ A2uiCatalog ]:
145141 return self ._supported_catalogs
146142
147143 def _apply_modifiers (self , schema : Dict [str , Any ]) -> Dict [str , Any ]:
@@ -153,8 +149,7 @@ def _apply_modifiers(self, schema: Dict[str, Any]) -> Dict[str, Any]:
153149 def _load_schemas (
154150 self ,
155151 version : str ,
156- custom_catalogs : Optional [List [CustomCatalogConfig ]] = None ,
157- basic_examples_path : Optional [str ] = None ,
152+ catalogs : List [CatalogConfig ] = [],
158153 ):
159154 """Loads separate schema components and processes catalogs."""
160155 if version not in SPEC_VERSION_MAP :
@@ -172,11 +167,7 @@ def _load_schemas(
172167 )
173168
174169 # Process basic catalog
175- basic_catalog_schema = self ._apply_modifiers (
176- _load_basic_component (version , CATALOG_SCHEMA_KEY )
177- )
178- if not basic_catalog_schema :
179- basic_catalog_schema = {}
170+ basic_catalog_schema = _load_basic_component (version , CATALOG_SCHEMA_KEY )
180171
181172 # Ensure catalog id and schema url are set in the basic catalog schema
182173 if CATALOG_ID_KEY not in basic_catalog_schema :
@@ -190,44 +181,36 @@ def _load_schemas(
190181 if "$schema" not in basic_catalog_schema :
191182 basic_catalog_schema ["$schema" ] = "https://json-schema.org/draft/2020-12/schema"
192183
193- self ._basic_catalog = A2uiCatalog (
194- version = version ,
195- name = BASIC_CATALOG_NAME ,
196- catalog_schema = basic_catalog_schema ,
197- s2c_schema = self ._server_to_client_schema ,
198- common_types_schema = self ._common_types_schema ,
199- )
200- if not self ._exclude_basic_catalog :
201- self ._supported_catalogs [self ._basic_catalog .catalog_id ] = self ._basic_catalog
202- self ._catalog_example_paths [self ._basic_catalog .catalog_id ] = basic_examples_path
203-
204- # Process custom catalogs
205- if custom_catalogs :
206- for config in custom_catalogs :
207- custom_catalog_schema = self ._apply_modifiers (
208- _load_from_path (config .catalog_path )
209- )
210- resolved_catalog_schema = A2uiCatalog .resolve_schema (
211- basic_catalog_schema , custom_catalog_schema
212- )
213- catalog = A2uiCatalog (
214- version = version ,
215- name = config .name ,
216- catalog_schema = self ._apply_modifiers (resolved_catalog_schema ),
217- s2c_schema = self ._server_to_client_schema ,
218- common_types_schema = self ._common_types_schema ,
219- )
220- self ._supported_catalogs [catalog .catalog_id ] = catalog
221- self ._catalog_example_paths [catalog .catalog_id ] = config .examples_path
184+ # Process catalogs
185+ if not catalogs :
186+ # If no catalogs are provided, use the basic catalog
187+ catalogs = [CatalogConfig .for_basic_catalog ()]
188+
189+ for config in catalogs :
190+ catalog_schema = (
191+ basic_catalog_schema
192+ if config .name == BASIC_CATALOG_NAME
193+ else _load_from_path (config .catalog_path )
194+ )
195+ catalog_schema = self ._apply_modifiers (catalog_schema )
196+ catalog = A2uiCatalog (
197+ version = version ,
198+ name = config .name ,
199+ catalog_schema = catalog_schema ,
200+ s2c_schema = self ._server_to_client_schema ,
201+ common_types_schema = self ._common_types_schema ,
202+ )
203+ self ._supported_catalogs .append (catalog )
204+ self ._catalog_example_paths [catalog .catalog_id ] = config .examples_path
222205
223206 def _determine_catalog (
224207 self , client_ui_capabilities : Optional [dict [str , Any ]] = None
225208 ) -> A2uiCatalog :
226209 """Determines the catalog to use based on supported catalog IDs.
227210
228- If neither inline catalogs nor supported catalog IDs are provided, the basic catalog is used.
211+ If neither inline catalogs nor client- supported catalog IDs are provided, the first agent-supported catalog is used.
229212 If inline catalogs are provided, the first inline catalog is used.
230- If supported catalog IDs are provided, the first supported catalog that is recognized is used.
213+ If client- supported catalog IDs are provided, the first one that is supported by the agent is used.
231214
232215 Args:
233216 client_ui_capabilities: A dictionary of client UI capabilities.
@@ -236,16 +219,19 @@ def _determine_catalog(
236219 The A2uiCatalog to use to generate the schema string in the prompt.
237220
238221 Raises:
239- ValueError: If both inline catalogs and supported catalog IDs are provided,
222+ ValueError: If both inline catalogs and client- supported catalog IDs are provided,
240223 or if no supported catalog is recognized.
241224 """
225+ if not self ._supported_catalogs :
226+ raise ValueError ("No supported catalogs found." ) # This should not happen.
227+
242228 if not client_ui_capabilities or not isinstance (client_ui_capabilities , dict ):
243- return self ._basic_catalog
229+ return self ._supported_catalogs [ 0 ]
244230
245231 inline_catalogs : List [dict [str , Any ]] = client_ui_capabilities .get (
246232 INLINE_CATALOGS_KEY , []
247233 )
248- supported_catalog_ids : List [str ] = client_ui_capabilities .get (
234+ client_supported_catalog_ids : List [str ] = client_ui_capabilities .get (
249235 SUPPORTED_CATALOG_IDS_KEY , []
250236 )
251237
@@ -255,37 +241,35 @@ def _determine_catalog(
255241 " capabilities. However, the agent does not accept inline catalogs."
256242 )
257243
258- if inline_catalogs and supported_catalog_ids :
244+ if inline_catalogs and client_supported_catalog_ids :
259245 raise ValueError (
260246 f"Both '{ INLINE_CATALOGS_KEY } ' and '{ SUPPORTED_CATALOG_IDS_KEY } ' "
261247 "are provided in client UI capabilities. Only one is allowed."
262248 )
263249
264250 if inline_catalogs :
265- # Load the first custom inline catalog schema.
251+ # Load the first inline catalog schema.
266252 inline_catalog_schema = inline_catalogs [0 ]
267- resolved_catalog_schema = A2uiCatalog .resolve_schema (
268- self ._basic_catalog .catalog_schema , inline_catalog_schema
269- )
253+ inline_catalog_schema = self ._apply_modifiers (inline_catalog_schema )
270254 return A2uiCatalog (
271255 version = self ._version ,
272256 name = INLINE_CATALOG_NAME ,
273- catalog_schema = resolved_catalog_schema ,
257+ catalog_schema = inline_catalog_schema ,
274258 s2c_schema = self ._server_to_client_schema ,
275259 common_types_schema = self ._common_types_schema ,
276260 )
277261
278- if not supported_catalog_ids :
279- return self ._basic_catalog
262+ if not client_supported_catalog_ids :
263+ return self ._supported_catalogs [ 0 ]
280264
281- for scid in supported_catalog_ids :
282- if scid in self . _supported_catalogs :
283- # Return the first supported catalog.
284- return self . _supported_catalogs [ scid ]
265+ agent_supported_catalogs = { c . catalog_id : c for c in self . _supported_catalogs }
266+ for cscid in client_supported_catalog_ids :
267+ if cscid in agent_supported_catalogs :
268+ return agent_supported_catalogs [ cscid ]
285269
286270 raise ValueError (
287- "No supported catalog found on the agent side. Agent supported catalogs are: "
288- f" { list ( self ._supported_catalogs . keys ()) } "
271+ "No client- supported catalog found on the agent side. Agent- supported catalogs"
272+ f" are: { [ c . catalog_id for c in self ._supported_catalogs ] } "
289273 )
290274
291275 def get_effective_catalog (
@@ -339,5 +323,5 @@ def generate_system_prompt(
339323 return "\n \n " .join (parts )
340324
341325 def get_agent_extension (self ) -> AgentExtension :
342- catalog_ids = self ._supported_catalogs . keys ()
343- return get_a2ui_agent_extension (supported_catalog_ids = list ( catalog_ids ) )
326+ catalog_ids = [ c . catalog_id for c in self ._supported_catalogs ]
327+ return get_a2ui_agent_extension (supported_catalog_ids = catalog_ids )
0 commit comments