Skip to content

Contributing to the Docs

This guide explains how to write documentation for Railtracks. It covers the file layout, the Markdown extensions we use, code snippets, and how to build and preview the site locally.

Where docs live

  • User-facing guides live in docs/documentation/ and are organized by topic: getting_started/, agent_design/, invocation/, advanced/, upgrading/.
  • Integrations (LLM providers, retrieval, observability) live in docs/integrations/, docs/retrieval/, and docs/observability/.
  • API reference is generated by pdoc into docs/api_reference.md — do not hand-edit generated API sections. If you change a public signature, regenerate instead.
  • Tutorials live in docs/tutorials/.

Every page that should appear in the sidebar must be listed in the nav section of mkdocs.yml; a page that is not listed is still served, but hidden from navigation and triggers a build warning.

Markdown flavor

The site uses MkDocs Material with these extensions, so you can use them in any page:

  • admonition / pymdownx.details — !!! note, !!! warning, ???+ tip
  • pymdownx.tabbed — tabbed content
  • pymdownx.superfences — fenced code blocks, including mermaid diagrams
  • pymdownx.inlinehilite — inline code highlighting
  • pymdownx.snippets — --8<-- "path" file inclusion (used below)
  • pymdownx.highlight — line numbers, copy buttons

Code snippets

Prefer file inclusion over pasting code. When a snippet belongs in a real, runnable script, keep it in docs/scripts/documentation/ and include it:

```python
import railtracks as rt

# To create your agent, you just need a model and a system message. 
Agent = rt.agent_node(
    llm=rt.llm.OpenAILLM("gpt-6-luna"),
    system_message="You are a helpful AI assistant."
)


# Create your flow and set the entry point to the agent we just created.
# Then we can invoke the flow with the input to that agent.
flow = rt.Flow("Quickstart Example", entry_point=Agent)

result = flow.invoke("Hello, what can you do?")

```

The :setup suffix selects a named section in the source file. This keeps the docs and the runnable examples from drifting.

For short, illustrative snippets that are not meant to run, paste them directly with a title:

```bash title="Install Library"
pip install railtracks
```

Admonitions

Use admonitions sparingly, and match the existing tone:

  • !!! note — neutral background
  • !!! warning / ???+ warning — things that commonly go wrong (e.g. "No API key set?")
  • !!! tip — recommended setup steps
  • ???+ — collapsed by default, expanded on click
  • Prefer relative links between docs pages: ../../integrations/llms/providers.md
  • External links must be full https:// URLs.
  • Do not link to main-branch file paths for pages that are also in the nav; link to the rendered page instead.
  • Link to the anchor that holds the definition, not to the top of the page that contains it: ../invocation/flows.md#entry-point, not ../invocation/flows.md. Broken anchors fail mkdocs build --strict.

Keywords and the glossary

Railtracks vocabulary (node, agent node, Flow, entry point, run, middleware and so on) is defined in exactly one place, and every other page links to it.

  • One canonical home per term. The page that owns a subject owns the full description of its terms, with the reasons and an example. Do not restate a definition on a second page, link to it.
  • Link the first mention on a page, not every mention. A reader who already followed the link does not need it again three paragraphs later.
  • Add an entry to the glossary when you introduce a term. Entries there are pointers rather than documentation: at most two sentences, always ending in a link to the canonical section, and never any code.
  • Glossary entries also become hover definitions site-wide. The abbr definitions behind them are generated from docs/glossary.md by scripts/mkdocs_hooks.py, so a tooltip and its glossary entry cannot drift apart. Only the first mention of a term on each page gets a tooltip, and headings, admonition titles, <summary> elements and tab labels never do.
  • Choose which spellings carry a term's tooltip with a comment directly under its glossary heading. With no comment, only the heading text matches, and matching is case sensitive, so Flow gets a tooltip and the informal "flow" does not. <!-- tooltip: agent node, agent nodes --> adds lowercase or plural forms; list one only when that spelling always means the glossary sense, which is why "entry point" has none. <!-- tooltip: none --> keeps a term out of the tooltips when its capitalized form also appears in an unrelated sense, as with Run, Tool and Context.

Building and previewing locally

pip install -e '.[docs]'   # or the docs extra named in pyproject.toml
mkdocs serve               # http://127.0.0.1:8000

mkdocs serve watches for changes and rebuilds automatically. Before opening a PR, run a full build to catch broken links and nav warnings:

mkdocs build --strict

What a good docs PR looks like

  1. One page or one coherent section per PR.
  2. The page is added to mkdocs.yml nav in the right place.
  3. Runnable snippets live in docs/scripts/documentation/ and are included, not pasted.
  4. mkdocs build --strict passes locally.
  5. The PR description says what the page covers and why.

pdoc and API reference

The API reference is generated from docstrings. When you document a public class or function, prefer the existing docstring style used in packages/railtracks/src/railtracks/ — the pdoc output is derived from it. Configuration sections (like the .env variables listed on the LLM setup page) are hand-written Markdown; keep those in sync with pdoc where the two overlap.