@@ -269,6 +269,44 @@ async def _build_recon_history_texts_async(
269269 return local_text , global_text
270270
271271
272+ async def _normalize_keywords_list (raw_keywords : List [str ] | None ) -> List [str ]:
273+ """Normalize Recon keywords into single-word tokens.
274+
275+ Rules:
276+ - split on underscores, hyphens and non-alphanumeric chars
277+ - split camelCase boundaries (e.g. behaviorChange -> behavior, change)
278+ - lowercase, strip and dedupe while preserving order
279+ - return an empty list if input is None or no valid tokens
280+ """
281+ if not raw_keywords :
282+ return []
283+
284+ import re
285+
286+ def _split_camel (s : str ) -> List [str ]:
287+ # Insert space between lower->upper transitions then split
288+ parts = re .sub ('([a-z0-9])([A-Z])' , r"\1 \2" , s ).split ()
289+ return parts
290+
291+ seen = set ()
292+ out : List [str ] = []
293+ for k in raw_keywords :
294+ if not k :
295+ continue
296+ # replace non-alnum with space, then split camelCase
297+ k = str (k ).strip ()
298+ k = re .sub (r"[^0-9A-Za-z]+" , " " , k )
299+ for part in k .split ():
300+ for sub in _split_camel (part ):
301+ tok = sub .strip ().lower ()
302+ if not tok :
303+ continue
304+ if tok not in seen :
305+ seen .add (tok )
306+ out .append (tok )
307+ return out
308+
309+
272310async def gather_recon_contributions (
273311 message = None ,
274312 context_memory = None ,
@@ -407,6 +445,9 @@ async def gather_recon_contributions(
407445 return []
408446
409447 # Dispatch responses to plugins
448+ # normalize keywords into single-word tokens before dispatching to plugins
449+ norm_keywords = await _normalize_keywords_list (keywords )
450+
410451 for plugin in recon_plugins :
411452 key = plugin .get_recon_key ()
412453 plugin_name = plugin .__class__ .__name__
@@ -418,7 +459,7 @@ async def gather_recon_contributions(
418459 context_memory = context_memory ,
419460 text = text ,
420461 tags = tags ,
421- keywords = keywords ,
462+ keywords = norm_keywords ,
422463 max_results = max_results ,
423464 )
424465 except Exception as e :
0 commit comments