diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 009e6d0d..f0f6a5f4 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -12,7 +12,7 @@ permissions: read-all jobs: build: - name: Build Documentation + name: Build Documentation and Check Links runs-on: ubuntu-latest steps: - name: Checkout code @@ -24,12 +24,6 @@ jobs: run: | mkdocs build - check_links: - name: Check Links - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - name: Restore lychee cache uses: actions/cache@v4 with: @@ -41,4 +35,4 @@ jobs: id: lychee uses: lycheeverse/lychee-action@v2 with: - args: "--cache --max-cache-age 1d 'docs/**/*.md'" + args: "--cache --max-cache-age 1d 'docs/**/*.md'" \ No newline at end of file diff --git a/.gitignore b/.gitignore index dd5dfe9f..026e257c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ __pycache__ .idea .kiro *.egg-info +docs/api-reference +temp_python_sdk \ No newline at end of file diff --git a/docs/api-reference/.gitkeep b/docs/api-reference/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/docs/api-reference/agent.md b/docs/api-reference/agent.md deleted file mode 100644 index 5eccd889..00000000 --- a/docs/api-reference/agent.md +++ /dev/null @@ -1,29 +0,0 @@ -::: strands.agent - options: - heading_level: 1 - members: false -::: strands.agent.agent - options: - heading_level: 2 -::: strands.agent.agent_result - options: - heading_level: 2 -::: strands.agent.conversation_manager - options: - heading_level: 2 - members: false -::: strands.agent.conversation_manager.conversation_manager - options: - heading_level: 3 -::: strands.agent.conversation_manager.null_conversation_manager - options: - heading_level: 3 -::: strands.agent.conversation_manager.sliding_window_conversation_manager - options: - heading_level: 3 -::: strands.agent.conversation_manager.summarizing_conversation_manager - options: - heading_level: 3 -::: strands.agent.state - options: - heading_level: 2 diff --git a/docs/api-reference/event-loop.md b/docs/api-reference/event-loop.md deleted file mode 100644 index 712d9b6f..00000000 --- a/docs/api-reference/event-loop.md +++ /dev/null @@ -1,10 +0,0 @@ -::: strands.event_loop - options: - heading_level: 1 - members: false -::: strands.event_loop.event_loop - options: - heading_level: 2 -::: strands.event_loop.streaming - options: - heading_level: 2 diff --git a/docs/api-reference/experimental.md b/docs/api-reference/experimental.md deleted file mode 100644 index 803dafc7..00000000 --- a/docs/api-reference/experimental.md +++ /dev/null @@ -1,11 +0,0 @@ -::: strands.experimental - options: - heading_level: 1 - members: false -::: strands.experimental.hooks - options: - heading_level: 2 - members: false -::: strands.experimental.hooks.events - options: - heading_level: 3 diff --git a/docs/api-reference/handlers.md b/docs/api-reference/handlers.md deleted file mode 100644 index 1b9694f2..00000000 --- a/docs/api-reference/handlers.md +++ /dev/null @@ -1,7 +0,0 @@ -::: strands.handlers - options: - heading_level: 1 - members: false -::: strands.handlers.callback_handler - options: - heading_level: 2 diff --git a/docs/api-reference/hooks.md b/docs/api-reference/hooks.md deleted file mode 100644 index cf09deef..00000000 --- a/docs/api-reference/hooks.md +++ /dev/null @@ -1,10 +0,0 @@ -::: strands.hooks - options: - heading_level: 1 - members: false -::: strands.hooks.events - options: - heading_level: 2 -::: strands.hooks.registry - options: - heading_level: 2 diff --git a/docs/api-reference/interrupt.md b/docs/api-reference/interrupt.md deleted file mode 100644 index 31e001aa..00000000 --- a/docs/api-reference/interrupt.md +++ /dev/null @@ -1,3 +0,0 @@ -::: strands.interrupt - options: - heading_level: 1 diff --git a/docs/api-reference/models.md b/docs/api-reference/models.md deleted file mode 100644 index a1ac435d..00000000 --- a/docs/api-reference/models.md +++ /dev/null @@ -1,34 +0,0 @@ -::: strands.models - options: - heading_level: 1 - members: false -::: strands.models.model - options: - heading_level: 2 -::: strands.models.bedrock - options: - heading_level: 2 -::: strands.models.anthropic - options: - heading_level: 2 -::: strands.models.gemini - options: - heading_level: 2 -::: strands.models.litellm - options: - heading_level: 2 -::: strands.models.llamaapi - options: - heading_level: 2 -::: strands.models.mistral - options: - heading_level: 2 -::: strands.models.ollama - options: - heading_level: 2 -::: strands.models.openai - options: - heading_level: 2 -::: strands.models.writer - options: - heading_level: 2 diff --git a/docs/api-reference/multiagent.md b/docs/api-reference/multiagent.md deleted file mode 100644 index 72c9491a..00000000 --- a/docs/api-reference/multiagent.md +++ /dev/null @@ -1,23 +0,0 @@ -::: strands.multiagent - options: - heading_level: 1 - members: false -::: strands.multiagent.base - options: - heading_level: 2 -::: strands.multiagent.graph - options: - heading_level: 2 -::: strands.multiagent.swarm - options: - heading_level: 2 -::: strands.multiagent.a2a - options: - heading_level: 2 - members: false -::: strands.multiagent.a2a.executor - options: - heading_level: 3 -::: strands.multiagent.a2a.server - options: - heading_level: 3 diff --git a/docs/api-reference/session.md b/docs/api-reference/session.md deleted file mode 100644 index 2b20a869..00000000 --- a/docs/api-reference/session.md +++ /dev/null @@ -1,20 +0,0 @@ -::: strands.session - options: - heading_level: 1 - members: false -::: strands.session.file_session_manager - options: - heading_level: 2 -::: strands.session.repository_session_manager - options: - heading_level: 2 -::: strands.session.s3_session_manager - options: - heading_level: 2 -::: strands.session.session_manager - options: - heading_level: 2 - members: false -::: strands.session.session_repository - options: - heading_level: 2 diff --git a/docs/api-reference/telemetry.md b/docs/api-reference/telemetry.md deleted file mode 100644 index 4827a0c0..00000000 --- a/docs/api-reference/telemetry.md +++ /dev/null @@ -1,16 +0,0 @@ -::: strands.telemetry - options: - heading_level: 1 - members: false -::: strands.telemetry.config - options: - heading_level: 2 -::: strands.telemetry.metrics - options: - heading_level: 2 -::: strands.telemetry.metrics_constants - options: - heading_level: 2 -::: strands.telemetry.tracer - options: - heading_level: 2 diff --git a/docs/api-reference/tools.md b/docs/api-reference/tools.md deleted file mode 100644 index 2744782f..00000000 --- a/docs/api-reference/tools.md +++ /dev/null @@ -1,45 +0,0 @@ -::: strands.tools - options: - heading_level: 1 - members: false -::: strands.tools.tools - options: - heading_level: 2 -::: strands.tools.decorator - options: - heading_level: 2 -::: strands.tools.loader - options: - heading_level: 2 -::: strands.tools.registry - options: - heading_level: 2 -::: strands.tools.structured_output - options: - heading_level: 2 -::: strands.tools.watcher - options: - heading_level: 2 -::: strands.tools.executors - options: - heading_level: 2 - members: false -::: strands.tools.executors.concurrent - options: - heading_level: 3 -::: strands.tools.executors.sequential - options: - heading_level: 3 -::: strands.tools.mcp - options: - heading_level: 2 - members: false -::: strands.tools.mcp.mcp_agent_tool - options: - heading_level: 3 -::: strands.tools.mcp.mcp_client - options: - heading_level: 3 -::: strands.tools.mcp.mcp_types - options: - heading_level: 3 diff --git a/docs/api-reference/types.md b/docs/api-reference/types.md deleted file mode 100644 index 193fc113..00000000 --- a/docs/api-reference/types.md +++ /dev/null @@ -1,34 +0,0 @@ -::: strands.types - options: - heading_level: 1 - members: false -::: strands.types.content - options: - heading_level: 2 -::: strands.types.event_loop - options: - heading_level: 2 -::: strands.types.exceptions - options: - heading_level: 2 -::: strands.types.guardrails - options: - heading_level: 2 -::: strands.types.interrupt - options: - heading_level: 2 -::: strands.types.media - options: - heading_level: 2 -::: strands.types.session - options: - heading_level: 2 -::: strands.types.streaming - options: - heading_level: 2 -::: strands.types.tools - options: - heading_level: 2 -::: strands.types.traces - options: - heading_level: 2 diff --git a/docs/user-guide/concepts/agents/agent-loop.md b/docs/user-guide/concepts/agents/agent-loop.md index cced63f5..000c6e13 100644 --- a/docs/user-guide/concepts/agents/agent-loop.md +++ b/docs/user-guide/concepts/agents/agent-loop.md @@ -37,7 +37,7 @@ The agent loop consists of several key components working together to create a s ### Event Loop Cycle -The event loop cycle is the central mechanism that orchestrates the flow of information. It's implemented in the [`event_loop_cycle`](../../../api-reference/event-loop.md#strands.event_loop.event_loop.event_loop_cycle) function, which: +The event loop cycle is the central mechanism that orchestrates the flow of information. It's implemented in the [`event_loop_cycle`](../../../api-reference/event_loop.md#strands.event_loop.event_loop.event_loop_cycle) function, which: - Processes messages with the language model - Handles tool execution requests diff --git a/generate_python_api_docs.py b/generate_python_api_docs.py new file mode 100644 index 00000000..be5036f0 --- /dev/null +++ b/generate_python_api_docs.py @@ -0,0 +1,104 @@ +import os +import subprocess +import shutil +import importlib +from pathlib import Path +from typing import Any + +def _find_container_modules(module_list: list[str], main_module: str) -> list[str]: + container_modules = set() + for module in module_list: + parts = module.split('.') + # Check for potential container modules (3+ parts) + if len(parts) > 2: + for i in range(2, len(parts)): + container = '.'.join(parts[:i+1]) + if container not in module_list and container != main_module: + # Check if this container has multiple sub-modules + sub_modules = [m for m in module_list if m.startswith(container + '.')] + if len(sub_modules) > 1: + container_modules.add(container) + return container_modules + +def on_pre_build(config): + """Generate API docs before build""" + repo_url = "https://github.com/strands-agents/sdk-python.git" + temp_dir = Path('temp_python_sdk') + sdk_path = temp_dir / 'src/strands' + output_dir = Path('docs/api-reference') + # Clean up cloned repository if it already exists + shutil.rmtree(temp_dir, ignore_errors=True) + + # Clone repository + try: + subprocess.run(['git', 'clone', repo_url, str(temp_dir)], check=True) + except subprocess.CalledProcessError: + if sdk_path.exists(): + shutil.rmtree(temp_dir, ignore_errors=True) + print("Failed to clone repository") + return + + print("Generating API docs...") + + # Find modules + modules: list[str] = [] + for item in sdk_path.rglob('*.py'): + if item.name.startswith('_'): + continue + rel_path = item.relative_to(sdk_path.parent) + module = str(rel_path.with_suffix('')).replace('/', '.') + + # Only include modules that can be imported + # Otherwise we get an error like: ERROR - mkdocstrings: strands.types.multiagent could not be found + try: + importlib.import_module(module) + modules.append(module) + except ImportError: + continue + + # Group by api reference category + # Each category will have a list of included python modules + categories: dict[str, list[str]] = {} + for module in modules: + parts = module.split('.') + if len(parts) >= 2: + category = parts[1] + if category not in categories: + categories[category] = [] + categories[category].append(module) + + # Generate files + for category, module_list in categories.items(): + content = [] + main_module = f"strands.{category}" + + # Find container modules (modules that have sub-modules but aren't in the list) + container_modules = _find_container_modules(module_list, main_module) + + # Add container modules to the list + module_list.extend(container_modules) + + # Sort to maintain proper order + sorted_modules = sorted(module_list) + + # Always include main module as header, even if not importable + if main_module not in module_list: + sorted_modules.insert(0, main_module) + else: + sorted_modules.remove(main_module) + sorted_modules.insert(0, main_module) + + for module in sorted_modules: + parts = module.split('.') + level = min(len(parts) - 1, 3) + content.append(f"::: {module}") + content.append(" options:") + content.append(f" heading_level: {level}") + # Add members: false for main module and container modules + if module == main_module or module in container_modules: + content.append(" members: false") + with open(output_dir / f"{category}.md", 'w') as f: + f.write('\n'.join(content) + '\n') + + # Clean up cloned repository + shutil.rmtree(temp_dir, ignore_errors=True) \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index bdc84fd2..5a2e3f7c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -168,7 +168,7 @@ nav: - Contribute ❤️: https://github.com/strands-agents/sdk-python/blob/main/CONTRIBUTING.md - API Reference: - Agent: api-reference/agent.md - - Event Loop: api-reference/event-loop.md + - Event Loop: api-reference/event_loop.md - Experimental: api-reference/experimental.md - Handlers: api-reference/handlers.md - Hooks: api-reference/hooks.md @@ -212,6 +212,9 @@ plugins: API Reference: - api-reference/*.md +hooks: + - generate_python_api_docs.py + extra: social: - icon: fontawesome/brands/github