@@ -285,6 +285,278 @@ def friendly_title(name: str, page_type: str = "class") -> str:
285285 return title
286286
287287
288+ # =============================================================================
289+ # RELATED DOCS MAPPING
290+ # =============================================================================
291+ # Maps keywords found in class/module names to relevant documentation pages.
292+ # Format: keyword -> list of (title, path, icon) tuples, most relevant first.
293+ # Paths are relative to docs root (e.g., "/docs/concepts/agents")
294+
295+ RELATED_DOCS = {
296+ "agent" : [
297+ ("Agents Concept" , "/docs/concepts/agents" , "robot" ),
298+ ("Single Agent Guide" , "/docs/guides/single-agent" , "book-open" ),
299+ ("Multi-Agent Guide" , "/docs/guides/multi-agent" , "users" ),
300+ ("Agent Configuration" , "/docs/configuration/agent-config" , "gear" ),
301+ ("Auto Agents" , "/docs/features/autoagents" , "wand-magic-sparkles" ),
302+ ],
303+ "team" : [
304+ ("AgentTeam Concept" , "/docs/concepts/agentteam" , "users" ),
305+ ("Multi-Agent Guide" , "/docs/guides/multi-agent" , "book-open" ),
306+ ("Orchestrator Worker" , "/docs/features/orchestrator-worker" , "sitemap" ),
307+ ],
308+ "flow" : [
309+ ("AgentFlow Concept" , "/docs/concepts/agentflow" , "diagram-project" ),
310+ ("Workflow Patterns" , "/docs/features/workflow-patterns" , "shuffle" ),
311+ ("Routing" , "/docs/features/routing" , "route" ),
312+ ],
313+ "task" : [
314+ ("Tasks Concept" , "/docs/concepts/tasks" , "list-check" ),
315+ ("Task Configuration" , "/docs/configuration/task-config" , "gear" ),
316+ ("Task Validation" , "/docs/features/task-validation-feedback" , "check-double" ),
317+ ],
318+ "memory" : [
319+ ("Memory Concept" , "/docs/concepts/memory" , "brain" ),
320+ ("Memory Overview" , "/docs/memory/overview" , "database" ),
321+ ("Memory Configuration" , "/docs/configuration/memory-config" , "gear" ),
322+ ("Session Resume" , "/docs/memory/session-resume" , "rotate-right" ),
323+ ],
324+ "knowledge" : [
325+ ("Knowledge Concept" , "/docs/concepts/knowledge" , "book" ),
326+ ("Knowledge Overview" , "/docs/knowledge/overview" , "database" ),
327+ ("Knowledge Configuration" , "/docs/configuration/knowledge-config" , "gear" ),
328+ ("Chat with PDF" , "/docs/knowledge/chat-with-pdf" , "file-pdf" ),
329+ ],
330+ "rag" : [
331+ ("RAG Concept" , "/docs/concepts/rag" , "magnifying-glass" ),
332+ ("RAG Overview" , "/docs/rag/overview" , "database" ),
333+ ("Chunking Strategies" , "/docs/rag/strategies/overview" , "scissors" ),
334+ ],
335+ "tool" : [
336+ ("Tools Concept" , "/docs/concepts/tools" , "wrench" ),
337+ ("Create Custom Tools" , "/docs/guides/tools/create-custom-tools" , "plus" ),
338+ ("Tool Development" , "/docs/tutorials/advanced-tool-development" , "code" ),
339+ ],
340+ "llm" : [
341+ ("Models Overview" , "/docs/models" , "microchip" ),
342+ ("LLM Configuration" , "/docs/configuration/llm-config" , "gear" ),
343+ ("Model Router" , "/docs/features/model-router" , "route" ),
344+ ("Model Failover" , "/docs/features/model-failover" , "shield" ),
345+ ],
346+ "hook" : [
347+ ("Hooks Concept" , "/docs/concepts/hooks" , "anchor" ),
348+ ("Hook Events" , "/docs/features/hook-events" , "bolt" ),
349+ ("Callbacks" , "/docs/features/callbacks" , "phone" ),
350+ ],
351+ "guardrail" : [
352+ ("Guardrails Concept" , "/docs/concepts/guardrails" , "shield-halved" ),
353+ ("Guardrails Feature" , "/docs/features/guardrails" , "shield" ),
354+ ("Approval" , "/docs/features/approval" , "check" ),
355+ ],
356+ "context" : [
357+ ("Context Concept" , "/docs/concepts/context" , "layer-group" ),
358+ ("Context Management" , "/docs/features/context-management" , "sliders" ),
359+ ("Context Strategies" , "/docs/features/context-strategies" , "diagram-project" ),
360+ ],
361+ "session" : [
362+ ("Session Management" , "/docs/concepts/session-management" , "clock" ),
363+ ("Sessions Feature" , "/docs/features/sessions" , "folder" ),
364+ ("Session Persistence" , "/docs/features/session-persistence" , "database" ),
365+ ],
366+ "persistence" : [
367+ ("Persistence Overview" , "/docs/persistence/overview" , "hard-drive" ),
368+ ("Databases Overview" , "/docs/databases/overview" , "database" ),
369+ ("Session Resume" , "/docs/persistence/session-resume" , "rotate-right" ),
370+ ],
371+ "mcp" : [
372+ ("MCP Concept" , "/docs/concepts/mcp" , "server" ),
373+ ("MCP Lifecycle" , "/docs/features/mcp-lifecycle" , "rotate" ),
374+ ],
375+ "browser" : [
376+ ("Browser Agent" , "/docs/features/browser-agent" , "globe" ),
377+ ("Browser Deep Dive" , "/docs/features/browser-agent-deep-dive" , "magnifying-glass" ),
378+ ],
379+ "async" : [
380+ ("Async Feature" , "/docs/features/async" , "clock" ),
381+ ("Background Tasks" , "/docs/features/background-tasks" , "spinner" ),
382+ ("Async Jobs" , "/docs/features/async-jobs" , "list-check" ),
383+ ],
384+ "workflow" : [
385+ ("Workflows Feature" , "/docs/features/workflows" , "diagram-project" ),
386+ ("YAML Workflows" , "/docs/features/yaml-workflows" , "file-code" ),
387+ ("Workflow Patterns" , "/docs/features/workflow-patterns" , "shuffle" ),
388+ ],
389+ "display" : [
390+ ("Display System" , "/docs/features/display-system" , "display" ),
391+ ("Display Callbacks" , "/docs/features/display-callbacks" , "phone" ),
392+ ("Output Styles" , "/docs/features/output-styles" , "palette" ),
393+ ],
394+ "config" : [
395+ ("Configuration Overview" , "/docs/configuration/index" , "gear" ),
396+ ("Agent Config" , "/docs/configuration/agent-config" , "robot" ),
397+ ],
398+ "output" : [
399+ ("Output Concept" , "/docs/concepts/output" , "file-export" ),
400+ ("Output Configuration" , "/docs/configuration/output-config" , "gear" ),
401+ ("Save Output" , "/docs/features/save-output" , "floppy-disk" ),
402+ ],
403+ "profil" : [
404+ ("Agent Profiles" , "/docs/features/agent-profiles" , "id-card" ),
405+ ("Profiling" , "/docs/features/profiling" , "chart-line" ),
406+ ],
407+ "plugin" : [
408+ ("Plugins Feature" , "/docs/features/plugins" , "plug" ),
409+ ],
410+ "recipe" : [
411+ ("Recipes Concept" , "/docs/concepts/recipes" , "book-open" ),
412+ ("Recipes Guide" , "/docs/guides/recipes/index" , "utensils" ),
413+ ("Modular Recipes" , "/docs/features/modular-recipes" , "puzzle-piece" ),
414+ ],
415+ "sandbox" : [
416+ ("Sandbox Feature" , "/docs/features/sandbox" , "box" ),
417+ ],
418+ "scheduler" : [
419+ ("Background Tasks" , "/docs/features/background-tasks" , "clock" ),
420+ ("Async Jobs" , "/docs/features/async-jobs" , "list-check" ),
421+ ],
422+ "middleware" : [
423+ ("Middleware Feature" , "/docs/features/middleware" , "layer-group" ),
424+ ],
425+ "gateway" : [
426+ ("Gateway Feature" , "/docs/features/gateway" , "tower-broadcast" ),
427+ ],
428+ "endpoint" : [
429+ ("Endpoints Code" , "/docs/features/endpoints-code" , "code" ),
430+ ("Agent API Launch" , "/docs/features/agent-api-launch" , "rocket" ),
431+ ],
432+ "integration" : [
433+ ("LangChain Integration" , "/docs/features/langchain" , "link" ),
434+ ("Langflow Integration" , "/docs/integrations/langflow" , "diagram-project" ),
435+ ],
436+ "job" : [
437+ ("Async Jobs" , "/docs/features/async-jobs" , "list-check" ),
438+ ("Background Tasks" , "/docs/features/background-tasks" , "clock" ),
439+ ],
440+ "learn" : [
441+ ("Agent Learn" , "/docs/concepts/agent-learn" , "graduation-cap" ),
442+ ("Learn Configuration" , "/docs/configuration/learn-config" , "gear" ),
443+ ],
444+ "train" : [
445+ ("Agent Train" , "/docs/concepts/agent-train" , "dumbbell" ),
446+ ("Training" , "/docs/train" , "chart-line" ),
447+ ],
448+ "chat" : [
449+ ("Chat Feature" , "/docs/features/chat" , "comments" ),
450+ ("Conversation Stores" , "/docs/databases/overview" , "database" ),
451+ ],
452+ "image" : [
453+ ("Image Generation" , "/docs/features/image-generation" , "image" ),
454+ ("Multimodal" , "/docs/features/multimodal" , "photo-film" ),
455+ ],
456+ "vision" : [
457+ ("Multimodal" , "/docs/features/multimodal" , "eye" ),
458+ ],
459+ "audio" : [
460+ ("Multimodal" , "/docs/features/multimodal" , "volume-high" ),
461+ ],
462+ "video" : [
463+ ("Multimodal" , "/docs/features/multimodal" , "video" ),
464+ ],
465+ "code" : [
466+ ("Code Agent" , "/docs/features/codeagent" , "code" ),
467+ ("Code Feature" , "/docs/features/code" , "terminal" ),
468+ ],
469+ "eval" : [
470+ ("Evaluation Concept" , "/docs/concepts/evaluation" , "gavel" ),
471+ ("LLM as Judge" , "/docs/features/llm-as-judge" , "scale-balanced" ),
472+ ("Evaluation Loop" , "/docs/eval/evaluation-loop" , "rotate" ),
473+ ],
474+ "handoff" : [
475+ ("Handoffs Concept" , "/docs/concepts/handoffs" , "hand-holding" ),
476+ ("Handoffs Feature" , "/docs/features/handoffs" , "arrow-right-arrow-left" ),
477+ ],
478+ "skill" : [
479+ ("Skills Concept" , "/docs/concepts/skills" , "wand-magic-sparkles" ),
480+ ("Skills Feature" , "/docs/features/skills" , "star" ),
481+ ],
482+ "replay" : [
483+ ("Replay Feature" , "/features/replay" , "rotate-left" ),
484+ ],
485+ "cache" : [
486+ ("Caching Concept" , "/docs/concepts/caching" , "database" ),
487+ ],
488+ "planning" : [
489+ ("Planning Concept" , "/docs/concepts/planning" , "map" ),
490+ ("Planning Mode" , "/docs/features/planning-mode" , "diagram-project" ),
491+ ("Planning Configuration" , "/docs/configuration/planning-config" , "gear" ),
492+ ],
493+ "reflection" : [
494+ ("Reflection Concept" , "/docs/concepts/reflection" , "mirror" ),
495+ ("Self Reflection" , "/docs/features/selfreflection" , "brain" ),
496+ ("Reflection Configuration" , "/docs/configuration/reflection-config" , "gear" ),
497+ ],
498+ "reasoning" : [
499+ ("Reasoning Feature" , "/docs/features/reasoning" , "brain" ),
500+ ("Reasoning Extract" , "/docs/features/reasoning-extract" , "lightbulb" ),
501+ ],
502+ }
503+
504+
505+ def get_related_docs (name : str , max_items : int = 5 ) -> list :
506+ """Find related documentation based on keywords in the name.
507+
508+ Args:
509+ name: Class, function, or module name to find related docs for
510+ max_items: Maximum number of related docs to return
511+
512+ Returns:
513+ List of (title, path, icon) tuples, most relevant first
514+ """
515+ name_lower = name .lower ()
516+ related = []
517+ seen_paths = set ()
518+
519+ # Check each keyword against the name
520+ for keyword , docs in RELATED_DOCS .items ():
521+ if keyword in name_lower :
522+ for doc in docs :
523+ if doc [1 ] not in seen_paths :
524+ related .append (doc )
525+ seen_paths .add (doc [1 ])
526+
527+ return related [:max_items ]
528+
529+
530+ def render_related_section (name : str , max_items : int = 5 ) -> str :
531+ """Render a CardGroup section with related documentation links.
532+
533+ Args:
534+ name: Class, function, or module name
535+ max_items: Maximum related items to show
536+
537+ Returns:
538+ MDX string with CardGroup, or empty string if no related docs
539+ """
540+ related = get_related_docs (name , max_items )
541+ if not related :
542+ return ""
543+
544+ cards = []
545+ for title , path , icon in related :
546+ cards .append (f' <Card title="{ title } " icon="{ icon } " href="{ path } " />' )
547+
548+ return f"""
549+
550+ ---
551+
552+ ## Related Documentation
553+
554+ <CardGroup cols={{2}}>
555+ { chr (10 ).join (cards )}
556+ </CardGroup>
557+ """
558+
559+
288560# =============================================================================
289561# CONFIGURATION
290562# =============================================================================
@@ -976,6 +1248,10 @@ def _render_module(self, info: ModuleInfo) -> str:
9761248 truncated_val += "..."
9771249 lines .append (f"| `{ name } ` | `{ escape_for_table (truncated_val , is_type = False )} ` |" )
9781250 lines .append ("" )
1251+ # Add related documentation section
1252+ related_section = render_related_section (info .short_name , max_items = 5 )
1253+ if related_section :
1254+ lines .append (related_section )
9791255
9801256 return "\n " .join (lines )
9811257
@@ -1056,6 +1332,10 @@ def _render_module_granular(self, info: ModuleInfo) -> str:
10561332 truncated_val += "..."
10571333 lines .append (f"| `{ name } ` | `{ escape_for_table (truncated_val , is_type = False )} ` |" )
10581334 lines .append ("" )
1335+ # Add related documentation section
1336+ related_section = render_related_section (info .short_name , max_items = 5 )
1337+ if related_section :
1338+ lines .append (related_section )
10591339
10601340 return "\n " .join (lines )
10611341
@@ -1131,8 +1411,9 @@ def _render_class_page(self, cls: ClassInfo, module_info: ModuleInfo) -> str:
11311411 lines .append ("## Constructor\n " )
11321412 for p in cls .init_params :
11331413 default_str = f' default="{ escape_for_table (p .default )} "' if p .default and p .default != "None" else ""
1414+ required_str = "{true}" if p .required else "{false}"
11341415 lines .extend ([
1135- f'<ParamField query="{ p .name } " type="{ escape_for_table (p .type , is_type = True )} " required={{" { true } " if p.required else " { false } "} }{ default_str } >' ,
1416+ f'<ParamField query="{ p .name } " type="{ escape_for_table (p .type , is_type = True )} " required={ required_str } { default_str } >' ,
11361417 f' { escape_mdx (p .description ) if p .description else "No description available." } ' ,
11371418 '</ParamField>' ,
11381419 ""
@@ -1185,6 +1466,11 @@ def _render_class_page(self, cls: ClassInfo, module_info: ModuleInfo) -> str:
11851466 else :
11861467 lines .append (f"```{ lang } \n { cls .examples [0 ]} \n ```\n " )
11871468
1469+ # Add related documentation section
1470+ related_section = render_related_section (cls .name , max_items = 5 )
1471+ if related_section :
1472+ lines .append (related_section )
1473+
11881474 return "\n " .join (lines )
11891475
11901476 def _render_function_page (self , func : FunctionInfo , module_info : ModuleInfo , cls_name : Optional [str ] = None ) -> str :
@@ -1248,8 +1534,9 @@ def _render_function_page(self, func: FunctionInfo, module_info: ModuleInfo, cls
12481534 lines .append ("## Parameters\n " )
12491535 for i , p in enumerate (func .params ):
12501536 default_str = f' default="{ escape_for_table (p .default )} "' if p .default and p .default != "None" else ""
1537+ required_str = "{true}" if p .required else "{false}"
12511538 lines .extend ([
1252- f'<ParamField query="{ p .name } " type="{ escape_for_table (p .type , is_type = True )} " required={ "{true}" if p . required else "{false}" } { default_str } >' ,
1539+ f'<ParamField query="{ p .name } " type="{ escape_for_table (p .type , is_type = True )} " required={ required_str } { default_str } >' ,
12531540 f' { escape_mdx (p .description ) if p .description else "No description available." } ' ,
12541541 '</ParamField>' ,
12551542 ""
@@ -1289,6 +1576,11 @@ def _render_function_page(self, func: FunctionInfo, module_info: ModuleInfo, cls
12891576 dedented_ex = textwrap .dedent (func .examples [0 ])
12901577 lines .append (f"```python\n { dedented_ex } \n ```\n " )
12911578
1579+ # Add related documentation section
1580+ related_section = render_related_section (func .name , max_items = 5 )
1581+ if related_section :
1582+ lines .append (related_section )
1583+
12921584 return "\n " .join (lines )
12931585
12941586 def _render_mermaid_diagram (self , name : str ) -> Optional [str ]:
0 commit comments