Skip to content

Commit c481e6b

Browse files
committed
feat: Add related documentation section to SDK reference pages
- Add RELATED_DOCS mapping with 40+ keywords linking to guides/concepts/features - Add get_related_docs() and render_related_section() helper functions - Integrate related section in class/function/module page renders - Fix f-string escaping bug for JSX boolean values in ParamField - Shows up to 5 related docs per page, most relevant first
1 parent 107c4dc commit c481e6b

File tree

1 file changed

+294
-2
lines changed

1 file changed

+294
-2
lines changed

praisonai_tools/docs_generator/generator.py

Lines changed: 294 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)