diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 9a10302b97a..df6236d6860 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -63,3 +63,13 @@ jobs: python-version: ${{ matrix.python-version }} - run: pip install ".[dev]" - run: pytest + + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.10' + - run: pip install ".[docs]" + - run: sphinx-build --fail-on-warning docs/src docs/build diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000000..9591dfad5b2 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,43 @@ +# Simple workflow for deploying static content to GitHub Pages +name: Docs + +on: + # Runs on pushes targeting the default branch + push: + branches: ["main"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Pages + uses: actions/configure-pages@v5 + - run: pip install ".[docs]" + - run: sphinx-build docs/src docs/build + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: 'docs/build/html' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index ec3e5ffaf67..bf95311d43a 100644 --- a/.gitignore +++ b/.gitignore @@ -159,4 +159,6 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ -.ruff_cache/ \ No newline at end of file +.ruff_cache/ + +/docs/src/reference diff --git a/README.md b/README.md index 02fb8fba854..c658564d893 100644 --- a/README.md +++ b/README.md @@ -46,3 +46,14 @@ ruff check ```sh ruff format ``` + +### Build docs + +```sh +pip install -e ".[docs]" + +sphinx-build docs/src docs/build + +# To view the docs: +python -m http.server -d docs/build/html +``` diff --git a/docs/src/_apidoc_templates/module.rst_t b/docs/src/_apidoc_templates/module.rst_t new file mode 100644 index 00000000000..3878eba0334 --- /dev/null +++ b/docs/src/_apidoc_templates/module.rst_t @@ -0,0 +1,8 @@ +{%- if show_headings %} +{{- basename | e | heading }} + +{% endif -%} +.. automodule:: {{ qualname }} +{%- for option in automodule_options %} + :{{ option }}: +{%- endfor %} diff --git a/docs/src/_apidoc_templates/package.rst_t b/docs/src/_apidoc_templates/package.rst_t new file mode 100644 index 00000000000..3a8e91f3588 --- /dev/null +++ b/docs/src/_apidoc_templates/package.rst_t @@ -0,0 +1,53 @@ +{%- macro automodule(modname, options) -%} +.. automodule:: {{ modname }} +{%- for option in options %} + :{{ option }}: +{%- endfor %} +{%- endmacro %} + +{%- macro toctree(docnames) -%} +.. toctree:: + :maxdepth: {{ maxdepth }} + :hidden: +{% for docname in docnames %} + {{ docname }} +{%- endfor %} +{%- endmacro %} + +{%- if is_namespace %} +{{- [pkgname, "namespace"] | join(" ") | e | heading }} +{% else %} +{{- pkgname | e | heading }} +{% endif %} + +{%- if is_namespace %} +.. py:module:: {{ pkgname }} +{% endif %} + +{%- if modulefirst and not is_namespace %} +{{ automodule(pkgname, automodule_options) }} +{% endif %} + +{%- if subpackages %} + +{{ toctree(subpackages) }} +{% endif %} + +{%- if submodules %} + +{% if separatemodules %} +{{ toctree(submodules) }} +{% else %} +{%- for submodule in submodules %} +{% if show_headings %} +{{- [submodule, "module"] | join(" ") | e | heading(2) }} +{% endif %} +{{ automodule(submodule, automodule_options) }} +{% endfor %} +{%- endif %} +{%- endif %} + +{%- if not modulefirst and not is_namespace %} + +{{ automodule(pkgname, automodule_options) }} +{% endif %} \ No newline at end of file diff --git a/docs/src/conf.py b/docs/src/conf.py new file mode 100644 index 00000000000..de2225338b0 --- /dev/null +++ b/docs/src/conf.py @@ -0,0 +1,48 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "agnext" +copyright = "2024, Microsoft" +author = "Microsoft" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.napoleon", + "sphinxcontrib.apidoc" +] + +apidoc_module_dir = '../../src/agnext' +apidoc_output_dir = 'reference' +apidoc_template_dir = '_apidoc_templates' +apidoc_separate_modules = True +apidoc_extra_args = ["--no-toc"] + +templates_path = [] +exclude_patterns = ["reference/agnext.rst"] + +autoclass_content = "init" + +# Guides and tutorials must succeed. +nb_execution_raise_on_error = True +nb_execution_timeout = 60 + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "furo" +html_static_path = [] + +html_theme_options = { + "source_repository": "https://github.com/microsoft/agnext", + "source_branch": "main", + "source_directory": "docs/src/", +} diff --git a/docs/src/index.rst b/docs/src/index.rst new file mode 100644 index 00000000000..8aedc84e3d3 --- /dev/null +++ b/docs/src/index.rst @@ -0,0 +1,11 @@ +agnext +------ + +.. toctree:: + :caption: Reference + :hidden: + + reference/agnext.agent_components + reference/agnext.application_components + reference/agnext.chat + reference/agnext.core diff --git a/pyproject.toml b/pyproject.toml index 69f6ab6c680..9417bb00845 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ dependencies = ["openai>=1.3", "pillow", "aiohttp", "typing-extensions"] [project.optional-dependencies] dev = ["ruff", "pyright", "mypy", "pytest", "pytest-asyncio", "types-Pillow"] +docs = [ "sphinx", "furo", "sphinxcontrib-apidoc"] [tool.setuptools.package-data] agnext = ["py.typed"] diff --git a/src/agnext/agent_components/__init__.py b/src/agnext/agent_components/__init__.py index e69de29bb2d..30d509be026 100644 --- a/src/agnext/agent_components/__init__.py +++ b/src/agnext/agent_components/__init__.py @@ -0,0 +1,3 @@ +""" +The :mod:`agnext.agent_components` module provides building blocks for creating single agents +""" diff --git a/src/agnext/application_components/__init__.py b/src/agnext/application_components/__init__.py index e69de29bb2d..26874edf22b 100644 --- a/src/agnext/application_components/__init__.py +++ b/src/agnext/application_components/__init__.py @@ -0,0 +1,3 @@ +""" +The :mod:`agnext.application_components` module provides implementations of core components that are used to compose an application +""" diff --git a/src/agnext/chat/__init__.py b/src/agnext/chat/__init__.py index e69de29bb2d..efd6c1c6583 100644 --- a/src/agnext/chat/__init__.py +++ b/src/agnext/chat/__init__.py @@ -0,0 +1,3 @@ +""" +The :mod:`agnext.chat` module is the concrete implementation of multi-agent interaction patterns +""" diff --git a/src/agnext/core/__init__.py b/src/agnext/core/__init__.py index e69de29bb2d..786971c5209 100644 --- a/src/agnext/core/__init__.py +++ b/src/agnext/core/__init__.py @@ -0,0 +1,3 @@ +""" +The :mod:`agnext.core` module provides the foundational generic interfaces upon which all else is built. This module must not depend on any other module. +"""