From 5a97496d94388ee868221a96112895370ec9c018 Mon Sep 17 00:00:00 2001 From: Pete Cheslock Date: Tue, 29 Jul 2025 14:15:40 -0400 Subject: [PATCH 01/11] Move the video demo to the main root landing page Signed-off-by: Pete Cheslock --- docs/architecture/00_architecture.mdx | 6 ------ src/components/Install/index.js | 4 ++-- src/pages/index.js | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/docs/architecture/00_architecture.mdx b/docs/architecture/00_architecture.mdx index 6302eef..c977e05 100644 --- a/docs/architecture/00_architecture.mdx +++ b/docs/architecture/00_architecture.mdx @@ -9,12 +9,6 @@ With `llm-d`, users can operationalize GenAI deployments with a modular solution Built by leaders in the Kubernetes and vLLM projects, `llm-d` is a community-driven, Apache-2 licensed project with an open development model. -## Video Demonstration - -import VideoEmbed from '@site/src/components/VideoEmbed'; - - - ## Architecture `llm-d` adopts a layered architecture on top of industry-standard open technologies: vLLM, Kubernetes, and Inference Gateway. diff --git a/src/components/Install/index.js b/src/components/Install/index.js index 34c1947..a1950bd 100644 --- a/src/components/Install/index.js +++ b/src/components/Install/index.js @@ -34,7 +34,7 @@ export default function Install() { alt="2. " src={require('/docs/assets/counting-02.png').default} > - + Run the Quickstart @@ -46,7 +46,7 @@ export default function Install() { alt="3. " src={require('/docs/assets/counting-03.png').default} > - Explore llm-d! + Explore llm-d! {/* -------------------------------------------------------------------------- */} Complete install methods here diff --git a/src/pages/index.js b/src/pages/index.js index 1b4a087..e2818c2 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -5,6 +5,7 @@ import Welcome from '@site/src/components/Welcome' import Install from '@site/src/components/Install' import Demo from '@site/src/components/Demo' import About from '@site/src/components/About' +import VideoEmbed from '@site/src/components/VideoEmbed' export default function Home() { const {siteConfig} = useDocusaurusContext(); @@ -14,6 +15,24 @@ export default function Home() { description="llm-d: a Kubernetes-native high-performance distributed LLM inference framework">
+ + {/* Video Section */} +
+
+ +
+
+ {/* */} {/* */} From 35b393d27bfa326b9f01f43a85546b289c3c7ff1 Mon Sep 17 00:00:00 2001 From: Pete Cheslock Date: Thu, 31 Jul 2025 11:01:03 -0400 Subject: [PATCH 02/11] Enhance documentation structure and content integration - Updated .gitignore to exclude new architecture and component documentation files. - Expanded CONTRIBUTING.md with detailed guidelines for contributing to the llm-d website, including a quick guide for documentation changes and types of content. - Modified docusaurus.config.js to correct links for architecture documentation. - Added new remote content integration for architecture and component documentation, allowing automatic syncing from the main llm-d repository. - Removed outdated local documentation files to streamline content management. Signed-off-by: Pete Cheslock --- .gitignore | 18 +- CONTRIBUTING.md | 96 +++++++- README.md | 38 +++- docs/architecture/00_architecture.mdx | 76 ------- docs/architecture/Components/01_deployer.md | 9 - .../Components/02_inf-simulator.md | 125 ---------- .../Components/03_inf-scheduler.md | 150 ------------ .../Components/04_disagg_prefill-decode.md | 135 ----------- .../Components/05_routing-sidecar.md | 137 ----------- docs/architecture/Components/06_kv-cache.md | 214 ------------------ docs/community/partners.md.exclude | 5 - docs/contributing-to-docs.md | 9 - docs/intro.md | 46 ---- docusaurus.config.js | 2 +- release-info.json | 16 ++ remote-content/README.md | 76 ++++++- remote-content/remote-content.js | 8 + .../remote-sources/architecture-main.js | 51 +++++ .../remote-sources/component-configs.js | 66 ++++++ .../remote-sources/components-generator.js | 209 +++++++++++++++++ .../remote-sources/guide-examples.js | 31 +-- .../guide-inference-scheduling.js | 44 +--- .../remote-sources/guide-pd-disaggregation.js | 23 +- .../remote-sources/guide-prerequisites.js | 40 +--- .../remote-sources/guide-wide-ep-lws.js | 23 +- .../remote-sources/repo-transforms.js | 87 +++++++ remote-content/remote-sources/sigs.js | 16 +- remote-content/remote-sources/utils.js | 2 +- src/components/Welcome/index.js | 2 +- 29 files changed, 721 insertions(+), 1033 deletions(-) delete mode 100644 docs/architecture/00_architecture.mdx delete mode 100644 docs/architecture/Components/01_deployer.md delete mode 100644 docs/architecture/Components/02_inf-simulator.md delete mode 100644 docs/architecture/Components/03_inf-scheduler.md delete mode 100644 docs/architecture/Components/04_disagg_prefill-decode.md delete mode 100644 docs/architecture/Components/05_routing-sidecar.md delete mode 100644 docs/architecture/Components/06_kv-cache.md delete mode 100644 docs/community/partners.md.exclude delete mode 100644 docs/contributing-to-docs.md delete mode 100644 docs/intro.md create mode 100644 release-info.json create mode 100644 remote-content/remote-sources/architecture-main.js create mode 100644 remote-content/remote-sources/component-configs.js create mode 100644 remote-content/remote-sources/components-generator.js create mode 100644 remote-content/remote-sources/repo-transforms.js diff --git a/.gitignore b/.gitignore index 72ba3c2..04cabca 100644 --- a/.gitignore +++ b/.gitignore @@ -3,15 +3,21 @@ node_modules build .docusaurus -# Remote content files (downloaded automatically) +# Remote content files (downloaded automatically from GitHub repositories) +# These are generated by the remote content system and should not be committed + +# Architecture content (from llm-d/llm-d main repo) +docs/architecture/architecture.mdx + +# Component documentation (from all component repos in component-configs.js) +docs/architecture/Components/ + +# Community content (from llm-d/llm-d main repo) docs/community/contribute.md docs/community/code-of-conduct.md docs/community/security.md docs/community/sigs.md -# Guide remote content files +# Guide content (from llm-d-incubation/llm-d-infra repo) docs/guide/guide.md -docs/guide/Installation/prerequisites.md -docs/guide/Installation/inference-scheduling.md -docs/guide/Installation/pd-disaggregation.md -docs/guide/Installation/wide-ep-lws.md \ No newline at end of file +docs/guide/Installation/ \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4085928..51bc925 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,97 @@ # Contributing to llm-d Website -Thank you for your interest in contributing to the llm-d website! This project adheres to the llm-d [Contributing Guidelines](https://github.com/llm-d/llm-d/blob/dev/CONTRIBUTING.md). \ No newline at end of file +Thank you for your interest in contributing to the llm-d website! This repository manages the documentation website and follows both general project guidelines and website-specific processes. + +## 🎯 Quick Guide + +### πŸ“ Documentation Changes + +**Before making changes, check if the content is synced:** + +1. **Look for "Content Source" banners** at the bottom of pages +2. **If banner exists**: Click "edit the source file" to edit in the source repository +3. **If no banner**: The content is local to this repository - proceed with PR below + +### πŸ”„ Types of Content + +| Content Type | Location | How to Edit | +|--------------|----------|-------------| +| **Synced Content** | Architecture docs, guides, component docs | Edit in source repo (follow banner link) | +| **Local Content** | Blog posts, community pages, website config | Edit in this repository | +| **Component Documentation** | Auto-generated from component repos | Add to `component-configs.js` | + +### πŸš€ Making Local Changes + +For content **without** "Content Source" banners: + +1. **Fork & Clone** + ```bash + git clone https://github.com/YOUR-USERNAME/llm-d.github.io.git + cd llm-d.github.io + npm install + ``` + +2. **Create Branch** + ```bash + git checkout -b docs/your-change-description + ``` + +3. **Test Locally** + ```bash + npm start + ``` + +4. **Commit & Push** + ```bash + git add . + git commit -s -m "docs: your change description" + git push origin docs/your-change-description + ``` + +5. **Open Pull Request** with preview link for reviewers + +### πŸ”§ Adding Remote Content + +To sync new content from repositories: + +1. **Copy the template:** + ```bash + cp remote-content/remote-sources/example-readme.js.template remote-content/remote-sources/my-content.js + ``` + +2. **Edit configuration** in the new file + +3. **Add to system** in `remote-content/remote-content.js` + +4. **Test** with `npm start` + +See [remote-content/README.md](remote-content/README.md) for detailed instructions. + +### βš™οΈ Adding New Components + +Components are auto-generated! Just add to `remote-content/remote-sources/component-configs.js`: + +```javascript +{ + name: 'your-component-name', + org: 'llm-d', + branch: 'main', + description: 'Component description', + sidebarPosition: 10 +} +``` + +## πŸ“‹ General Guidelines + +This project follows the main llm-d [Contributing Guidelines](https://github.com/llm-d/llm-d/blob/dev/CONTRIBUTING.md): + +- **DCO Sign-off Required**: Use `git commit -s` +- **All changes via PR**: No direct pushes to main +- **Review required**: Maintainer approval needed +- **Preview deployments**: Available for all PRs + +## πŸ†˜ Need Help? + +- **General questions**: [llm-d Slack](https://inviter.co/llm-d-slack) +- **Website issues**: [Create an issue](https://github.com/llm-d/llm-d.github.io/issues) +- **Content questions**: Check if content is synced, then edit in appropriate repository \ No newline at end of file diff --git a/README.md b/README.md index 09df399..c18fe08 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,43 @@ The site may be previewed at [llm-d.github.io](https://llm-d.github.io/) before If you spot any errors or omissions in the site, please open an issue at [github.com/llm-d/llm-d.github.io](https://github.com/llm-d/llm-d.github.io/issues) +## πŸ“‹ Documentation Types + +This repository contains two types of documentation: + +1. **Local Documentation** - Written directly in this repository (blog posts, etc.) +2. **Remote Synced Content** - Automatically synced from other llm-d repositories (architecture docs, guides, component documentation, community docs.) + +Most technical documentation is automatically synced from the main [llm-d/llm-d](https://github.com/llm-d/llm-d) repository to ensure accuracy and consistency. + +## πŸ”„ Remote Content System + +Many docs pages are automatically synced from source repositories using our remote content system: + +- **Architecture Documentation** - Synced from component repositories +- **User Guides** - Synced from the main llm-d repository +- **Component Documentation** - Automatically generated from individual component repos +- **Contributing Guidelines** - Synced from the main repository + +Files with remote content show a "Content Source" banner at the bottom with links to edit the original source. + +### Making Changes to Synced Content + +**For synced content (files with "Content Source" banners):** +- Click the "edit the source file" link in the Content Source banner +- Make changes in the source repository +- Changes will automatically sync to this website during the next build + +**For local website content:** +- Follow the standard pull request process below + ## BEFORE DOING A PULL REQUEST -1. Make sure you are familiar with how docusaurus builds menus and links to images -2. Make sure there are no relative links to any of the llm-d component repositories in your markdown. -3. Fork the website repo and deploy a preview version of your proposed change for reviewers to check. This will make obvious any missed links from step 2 +1. **Check if content is synced** - Look for "Content Source" banners at the bottom of pages +2. **For synced content** - Edit the source repository, not this one +3. **For local content** - Follow the process below +4. Make sure you are familiar with how docusaurus builds menus and links to images +5. Fork the website repo and deploy a preview version of your proposed change for reviewers to check ### Installation diff --git a/docs/architecture/00_architecture.mdx b/docs/architecture/00_architecture.mdx deleted file mode 100644 index c977e05..0000000 --- a/docs/architecture/00_architecture.mdx +++ /dev/null @@ -1,76 +0,0 @@ ---- -sidebar_position: 0 -label: llm-d Architecture ---- -# Overview of llm-d architecture -`llm-d` is a Kubernetes-native distributed inference serving stack - a well-lit path for anyone to serve large language models at scale, with the fastest time-to-value and competitive performance per dollar for most models across most hardware accelerators. - -With `llm-d`, users can operationalize GenAI deployments with a modular solution that leverages the latest distributed inference optimizations like KV-cache aware routing and disaggregated serving, co-designed and integrated with the Kubernetes operational tooling in [Inference Gateway (IGW)](https://github.com/kubernetes-sigs/gateway-api-inference-extension). - -Built by leaders in the Kubernetes and vLLM projects, `llm-d` is a community-driven, Apache-2 licensed project with an open development model. - -## Architecture - -`llm-d` adopts a layered architecture on top of industry-standard open technologies: vLLM, Kubernetes, and Inference Gateway. - - -![llm-d Architecture](../assets/images/llm-d-arch-simplified.svg) - - -Key features of `llm-d` include: - -- **vLLM-Optimized Inference Scheduler:** `llm-d` builds on IGW's pattern for customizable β€œsmart” load-balancing via the Endpoint Picker Protocol (EPP) to define vLLM-optimized scheduling. Leveraging operational telemetry, the Inference Scheduler implements the filtering and scoring algorithms to make decisions with P/D-, KV-cache-, SLA-, and load-awareness. Advanced teams can implement their own scorers to further customize, while benefiting from other features in IGW, like flow control and latency-aware balancing. [See our Northstar design](https://docs.google.com/document/d/1kE1LY8OVjiOgKVD9-9Po96HODbTIbgHp4qgvw06BCOc/edit?tab=t.0#heading=h.4rgkvvo5gnle) - -- **Disaggregated Serving with vLLM:** `llm-d` leverages vLLM’s support for disaggregated serving to run prefill and decode on independent instances, using high-performance transport libraries like NVIDIA’s NIXL. In `llm-d`, we plan to support latency-optimized implementation using fast interconnects (IB, RDMA, ICI) and throughput optimized implementation using data-center networking. [See our Northstar design](https://docs.google.com/document/d/1FNN5snmipaTxEA1FGEeSH7Z_kEqskouKD1XYhVyTHr8/edit?tab=t.0) - -- **Disaggregated Prefix Caching with vLLM:** `llm-d` uses vLLM's KVConnector API to provide a pluggable cache for previous calculations, including offloading KVs to host, remote storage, and systems like LMCache. We plan to support two KV caching schemes. [See our Northstar design](https://docs.google.com/document/d/1d-jKVHpTJ_tkvy6Pfbl3q2FM59NpfnqPAh__Uz_bEZ8/edit?tab=t.0) - - *Independent* (north-south) caching with offloading to local memory and disk, providing a zero operational cost mechanism for offloading. - - *Shared* (east-west) caching with KV transfer between instances and shared storage with global indexing, providing potential for higher performance at the cost of a more operationally complex system. - -- **Variant Autoscaling over Hardware, Workload, and Traffic** (🚧): We plan to implement a traffic- and hardware-aware autoscaler that (a) measures the capacity of each model server instance, (b) derive a load function that takes into account different request shapes and QoS, and (c) assesses recent traffic mix (QPS, QoS, and shapes) -Using the recent traffic mix to calculate the optimal mix of instances to handle prefill, decode, and latency-tolerant requests, enabling use of HPA for SLO-level efficiency. [See our Northstar design](https://docs.google.com/document/d/1inTneLEZTv3rDEBB9KLOB9K6oMq8c3jkogARJqdt_58/edit?tab=t.0) - -For more, see the [project proposal](https://github.com/llm-d/llm-d/blob/dev/docs/proposals/llm-d.md) - -## Getting Started - -`llm-d` can be installed as a full solution, customizing enabled features, or through its individual components for experimentation. - -### Deploying as a solution - -llm-d's deployer can be used to install it as a solution using a single Helm chart on Kubernetes. - -**Tip** -See the guided experience with our [quickstart](https://github.com/llm-d/llm-d-deployer/blob/main/quickstart/README.md). - -### Experimenting and developing with llm-d - -llm-d repo is a metaproject with subcomponents that can be cloned individually. - -To clone all the components: - -```bash -git clone --recurse-submodules https://github.com/llm-d/llm-d.git -``` - -**Tip** -As a customization example, see [here](https://github.com/llm-d/llm-d/tree/dev) a template for adding a scheduler scorer. - -## Releases - -Visit our [GitHub Releases page](https://github.com/llm-d/llm-d-deployer/releases) and review the release notes to stay updated with the latest releases. - - -## Contribute - -### Guidelines -- See [our project overview](https://github.com/llm-d/llm-d/blob/dev/PROJECT.md) for more details on our development process and governance. - -### Connect -- We use Slack to discuss development across organizations. Please join via [this inviter link](https://inviter.co/llm-d-slack) and access the workspace [here](https://llm-d.slack.com). -- We host a weekly standup for contributors on Wednesdays at 1230pm ET. Please join by [adding the shared calendar](https://calendar.google.com/calendar/u/0?cid=NzA4ZWNlZDY0NDBjYjBkYzA3NjdlZTNhZTk2NWQ2ZTc1Y2U5NTZlMzA5MzhmYTAyZmQ3ZmU1MDJjMDBhNTRiNEBncm91cC5jYWxlbmRhci5nb29nbGUuY29t) -- We use Google Groups to share architecture diagrams and other content. Please join: [Google Group](https://groups.google.com/g/llm-d-contributors) - -## License - -This project is licensed under Apache License 2.0. See the [LICENSE file](@site/docs/assets/files/LICENSE) for details. diff --git a/docs/architecture/Components/01_deployer.md b/docs/architecture/Components/01_deployer.md deleted file mode 100644 index b42df5a..0000000 --- a/docs/architecture/Components/01_deployer.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Deployer - -A key component in llm-d's toolbox is the **llm-d deployer**, the Helm chart for deploying llm-d on Kubernetes. - -[llm-d-deployer repository](https://github.com/llm-d/llm-d-deployer) \ No newline at end of file diff --git a/docs/architecture/Components/02_inf-simulator.md b/docs/architecture/Components/02_inf-simulator.md deleted file mode 100644 index f87db66..0000000 --- a/docs/architecture/Components/02_inf-simulator.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -sidebar_position: 2 -sidebar_label: Inference Simulator ---- -# vLLM Simulator -To help with development and testing we have developed a light weight vLLM simulator. It does not truly -run inference, but it does emulate responses to the HTTP REST endpoints of vLLM. -Currently it supports partial OpenAI-compatible API: -- /v1/chat/completions -- /v1/completions -- /v1/models - -In addition, it supports a subset of vLLM's Prometheus metrics. These metrics are exposed via the /metrics HTTP REST endpoint. Currently supported are the following metrics: -- vllm:lora_requests_info - -The simulated inferense has no connection with the model and LoRA adapters specified in the command line parameters. The /v1/models endpoint returns simulated results based on those same command line parameters. - -The simulator supports two modes of operation: -- `echo` mode: the response contains the same text that was received in the request. For `/v1/chat/completions` the last message for the role=`user` is used. -- `random` mode: the response is randomly chosen from a set of pre-defined sentences. - -Timing of the response is defined by two parameters: `time-to-first-token` and `inter-token-latency`. - -For a request with `stream=true`: `time-to-first-token` defines the delay before the first token is returned, `inter-token-latency` defines the delay between subsequent tokens in the stream. - -For a requst with `stream=false`: the response is returned after delay of ` + ( * ( - 1))` - -It can be run standalone or in a Pod for testing under packages such as Kind. - -## Limitations -API responses contains a subset of the fields provided by the OpenAI API. - -
- Click to show the structure of requests/responses - -- `/v1/chat/completions` - - **request** - - stream - - model - - messages - - role - - content - - **response** - - id - - created - - model - - choices - - index - - finish_reason - - message -- `/v1/completions` - - **request** - - stream - - model - - prompt - - max_tokens (for future usage) - - **response** - - id - - created - - model - - choices - - text -- `/v1/models` - - **response** - - object (list) - - data - - id - - object (model) - - created - - owned_by - - root - - parent -
-
-For more details see the [vLLM documentation](https://docs.vllm.ai/en/stable/getting_started/quickstart.html#openai-completions-api-with-vllm) - -## Command line parameters -- `port`: the port the simulator listents on, mandatory -- `model`: the currently 'loaded' model, mandatory -- `lora`: a list of available LoRA adapters, separated by commas, optional, by default empty -- `mode`: the simulator mode, optional, by default `random` - - `echo`: returns the same text that was sent in the request - - `random`: returns a sentence chosen at random from a set of pre-defined sentences -- `time-to-first-token`: the time to the first token (in milliseconds), optional, by default zero -- `inter-token-latency`: the time to 'generate' each additional token (in milliseconds), optional, by default zero -- `max-loras`: maximum number of LoRAs in a single batch, optional, default is one -- `max-cpu-loras`: maximum number of LoRAs to store in CPU memory, optional, must be >= than max_loras, default is max_loras -- `max-running-requests`: maximum number of inference requests that could be processed at the same time - - -## Working with docker image - -### Clone the llm-d-inference-sim repository -```bash -git clone https://github.com/llm-d/llm-d-inference-sim.git -``` - -### Building -To build a Docker image of the vLLM Simulator, run: -```bash -make image-build -``` - -### Running -To run the vLLM Simulator image under Docker, run: -```bash -docker run --rm --publish 8000:8000 ghcr.io/llm-d/llm-d-inference-sim:dev --port 8000 --model "Qwen/Qwen2.5-1.5B-Instruct" --lora "tweet-summary-0,tweet-summary-1" -``` -**Note:** The above command exposes the simulator on port 8000, and serves the Qwen/Qwen2.5-1.5B-Instruct model. - -## Standalone testing - -### Building -To build the vLLM simulator, run: -```bash -make build -``` - -### Running -To run the router in a standalone test environment, run: -```bash -./bin/llm-d-inference-sim --model my_model --port 8000 -``` - - diff --git a/docs/architecture/Components/03_inf-scheduler.md b/docs/architecture/Components/03_inf-scheduler.md deleted file mode 100644 index ff84cfc..0000000 --- a/docs/architecture/Components/03_inf-scheduler.md +++ /dev/null @@ -1,150 +0,0 @@ ---- -sidebar_position: 3 -sidebar_label: Inference Scheduler ---- - -# llm-d Inference Router Architecture - -## Overview - -**llm-d** is an extensible architecture designed to route inference requests efficiently across model-serving pods. A central component of this architecture is the **Inference Gateway**, which builds on the Kubernetes-native **Gateway API Inference Extension (GIE)** to enable scalable, flexible, and pluggable routing of requests. - -The design enables: -- Support for **multiple base models** and **LoRA adapters** within a shared cluster [Not supported in Phase1] -- Efficient routing based on **KV cache locality**, **prefix**, **session affinity**, **load**, and **model metadata** -- Disaggregated **Prefill/Decode (P/D)** execution -- Pluggable **filters**, **scorers**, and **scrapers** for extensible routing - ---- - -## Core Goals - -- Route inference requests to optimal pods based on: - - Base model compatibility - - KV cache reuse - - Load balancing -- Support multi-model deployments on heterogeneous hardware -- Enable runtime extensibility with pluggable logic (filters, scorers, scrapers) -- Community-aligned implementation using GIE and Envoy + External Processing (EPP) - ---- - -## Architecture Design - -![Inference Gateway Architecture](../../assets/images/architecture.png) - -The inference scheduler is built on top of: -- **Envoy** as a programmable data plane -- **EPP (External Processing Plugin)** using **GIE** - -### Pluggability - -![Pluggability Architecture](../../assets/images/plugability.png) - -Routing decisions are governed by dynamic components: -- **Filters**: Exclude pods based on static or dynamic criteria -- **Scorers**: Assign scores to candidate pods -- **Scrapers**: Collect pod metadata and metrics for scorers - -These components are maintained in the `llm-d-inference-scheduler` repository and can evolve independently. - ---- - -## Filters, Scorers, and Scrapers - -### Core Design Principles - -- **Pluggability**: No core changes are needed to add new scorers or filters -- **Isolation**: Each component operates independently - - -### Routing Flow - -1. **Filtering** - - Pods in an `InferencePool` go through a sequential chain of filters - - Pods may be excluded based on criteria like model compatibility, resource usage, or custom logic - -2. **Scoring** - - Filtered pods are scored using a weighted set of scorers - - Scorers currently run sequentially (future: parallel execution) - - Scorers access a shared datastore populated by scrapers - -3. **Pod Selection** - - The highest-scored pod is selected - - If multiple pods share the same score, one is selected at random - -### Lifecycle Hooks -- `Pre-call` -- `Scoring` -- `Post-choice` -- `After-response` - ---- - -## Scorers & Configuration - -| Scorer | Description | Env Vars | -|------------------|--------------------------------------------|----------| -| Session-aware | Prefers pods from same session | `ENABLE_SESSION_AWARE_SCORER`, `SESSION_AWARE_SCORER_WEIGHT`, `PREFILL_ENABLE_SESSION_AWARE_SCORER`, `PREFILL_SESSION_AWARE_SCORER_WEIGHT` | -| Prefix-aware | Matches prompt prefix | `ENABLE_PREFIX_AWARE_SCORER`, `PREFIX_AWARE_SCORER_WEIGHT`, `PREFILL_ENABLE_PREFIX_AWARE_SCORER`, `PREFILL_PREFIX_AWARE_SCORER_WEIGHT` | -| KVCache-aware | Optimizes for KV reuse | `ENABLE_KVCACHE_AWARE_SCORER`, `KVCACHE_INDEXER_REDIS_ADDR`, `PREFILL_ENABLE_KVCACHE_AWARE_SCORER`, `PREFILL_KVCACHE_INDEXER_REDIS_ADDR`, `HF_TOKEN`, `KVCACHE_INDEXER_REDIS_ADDR` | -| Load-aware | Avoids busy pods | `ENABLE_LOAD_AWARE_SCORER`, `LOAD_AWARE_SCORER_WEIGHT`, `PREFILL_ENABLE_LOAD_AWARE_SCORER`, `PREFILL_LOAD_AWARE_SCORER_WEIGHT` | - -### Prefill / Decode Configuration - -In case Disaggregated Prefill is enabled, you should also define the following environment variables. - -- Toggle P/D mode: `PD_ENABLED=true` -- Threshold: `PD_PROMPT_LEN_THRESHOLD=` - -#### Prefill Scorers: -```bash -export PREFILL_ENABLE_SESSION_AWARE_SCORER=true -export PREFILL_SESSION_AWARE_SCORER_WEIGHT=1 -export PREFILL_ENABLE_KVCACHE_AWARE_SCORER=true -export PREFILL_KVCACHE_AWARE_SCORER_WEIGHT=1 -export PREFILL_ENABLE_LOAD_AWARE_SCORER=true -export PREFILL_LOAD_AWARE_SCORER_WEIGHT=1 -export PREFILL_ENABLE_PREFIX_AWARE_SCORER=true -export PREFILL_PREFIX_AWARE_SCORER_WEIGHT=1 -``` - - ---- - -## Metric Scraping - -- Scrapers collect metrics (e.g., memory usage, active adapters) -- Data is injected into the shared datastore for scorers -- Scoring can rely on numerical metrics or metadata (model ID, adapter tags) - ---- - -## Disaggregated Prefill/Decode (P/D) - -When enabled, the router: -- Selects one pod for **Prefill** (prompt processing) -- Selects another pod for **Decode** (token generation) - -The **vLLM sidecar** handles orchestration between Prefill and Decode stages. It allows: -- Queuing -- Local memory management -- Experimental protocol compatibility - -> **Note**: The detailed P/D design is available in this document: [Disaggregated Prefill/Decode in llm-d](./04_disagg_prefill-decode.md) ---- - -## InferencePool & InferenceModel Design - -### Current Assumptions -- Single `InferencePool` and single `EPP` due to Envoy limitations -- Model-based filtering can be handled within EPP -- Currently only one base model is supported - ---- - -## References -- [GIE Spec](https://gateway-api-inference-extension.sigs.k8s.io/) -- [Envoy External Processing](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/ext_proc_filter) - - diff --git a/docs/architecture/Components/04_disagg_prefill-decode.md b/docs/architecture/Components/04_disagg_prefill-decode.md deleted file mode 100644 index 20bab86..0000000 --- a/docs/architecture/Components/04_disagg_prefill-decode.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -sidebar_location: 4 -sidebar_label: Disagg Prefill/Decode -sidebar_class_name: hidden ---- - - -# Disaggregated Prefill/Decode Inference Serving in llm-d - -## Overview - -This document describes the architecture and request lifecycle for enabling **disaggregated prefill and decode (P/D)** inference execution in the llm-d router. The architecture aims to improve flexibility, scalability, and performance by enabling separation of prefill and decode stages onto different workers. - -This evolved version removes the requirement for sidecars on the **prefill node**, simplifying deployment while maintaining orchestration from the **decode node**. - ---- - -## Goals - -- Enable routing of prefill and decode to different pods -- Maintain low latency and high throughput -- Improve resource utilization by specializing pods for prefill or decode -- Align with GIE-compatible architectures for potential upstreaming - ---- - -## Key Components - -| Component | Role | -|----------------------|----------------------------------------------------------------------| -| **Prefill Worker** | Handles only prefill stage using vLLM engine | -| **Decode Worker** | Handles decode stage and contains the sidecar for coordination | -| **Sidecar (Decode)** | Orchestrates communication with prefill worker and manages lifecycle | -| **Envoy Proxy** | Accepts OpenAI-style requests and forwards them to EPP | -| **EPP** | End Point Picker, makes scheduling decisions | - ---- - -## Request Lifecycle - -1. **User Request** - - Sent via OpenAI API to the Envoy Proxy - -2. **EPP Scheduling Decision** - - EPP evaluates: - - Prompt length - - KV cache hit probability - - System and pod load - - Selects either: - - **Single node** path (decode handles all) - - **Split node** path (distinct prefill and decode workers) - - Returns Decode Worker (always), and optionally Prefill Worker URL - -3. **Execution** - - Request lands on Decode Worker (as selected by EPP) - - Decode sidecar coordinates: - - If `prefill_worker_id == nil`, runs both stages locally by passing request to local vllm - - If split: - - Sends prefill job to Prefill Worker with a special header `do_remote_decode=true` - - Upon receiving response from Prefill Worker runs decode stage - -4. **Response Flow** - - Response flows from decode sidecar β†’ Envoy β†’ EPP β†’ User - ---- - -## Architectural Details - -### Sidecar Responsibilities (Decode Only) - -- Receives EPP metadata (decode pod, optional prefill pod) -- Sends request to prefill -- Waits and validates result -- Launches local decode job -- Sends final response - -> **Note**: No sidecar or coordination logic is needed on the prefill node. - ---- - -## Worker Selection Logic - -- **Decode Worker**: - - Prefer longest prefix match / KV cache utilization (depends on avaialble scorers) - -- **Prefill Worker**: - - High prefix-cache hit rate - - Low load - -> **Skip prefill worker** when: -> - Prefix match/kv cache hit is high -> - Prompt is very short - ---- - -## vLLM and LMCache Integration - -- **vLLM changes** (or wrapper APIs): - - `save()`, `load()` APIs - - `done_sending`, `done_receiving` - - Connector API supporting async transfer - ---- - -## Drawbacks & Limitations - -- Slight increase in TTFT for split P/D -- Possibility of stranded memory on prefill crash -- Need for timeout and retry logic - ---- - -## Design Benefits - -- **Flexibility**: Enables per-request specialization and resource balancing -- **Scalability**: Clean separation of concerns for easier ops and tuning -- **Upstream-ready**: Follows GIE-compatible request handling -- **Minimal Changes**: Only decode node includes orchestration sidecar - ---- - -## Future Considerations - -- Cache coordinate -- Pre allocation of kv blocks in decode node , push cache from prefill to decode worker during calculation - ---- - -## Diagram - -![Disaggregated Prefill/Decode Architecture](../../assets/images/dp_architecture.png) - ---- - -## References diff --git a/docs/architecture/Components/05_routing-sidecar.md b/docs/architecture/Components/05_routing-sidecar.md deleted file mode 100644 index 228522e..0000000 --- a/docs/architecture/Components/05_routing-sidecar.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -sidebar_position: 5 -sidebar_label: Routing Sidecar ---- -# P/D Routing Sidecar - -This project provides a reverse proxy redirecting incoming requests -to the prefill worker specified in the `x-prefiller-url` HTTP request header. - -This is a prototype of a vLLM-native protocol for disaggregated serving. The -inference scheduler determines the best decode worker when it determines the -prefill worker, then informs the prefill worker where to direct the K/V transfer -as a single transaction. This ensures request cancellation or failures release -resources on both workers promptly. - -See the [disaggregated serving Northstar](https://docs.google.com/document/d/1FNN5snmipaTxEA1FGEeSH7Z_kEqskouKD1XYhVyTHr8/edit?tab=t.0#heading=h.ycwld2oth1kj) for more. - -## Getting Started - -### Requirements - -- a container engine (docker, podman, etc...) -- a server with at least 2 GPUs - -### Quick Start (From source) - -1. Start two vLLM servers with P/D enabled via the NIXLConnector. - -In one terminal, run this command to start the decoder: - -``` -$ podman run --network host --device nvidia.com/gpu=0 -v $HOME/models:/models \ - -e UCX_TLS="cuda_ipc,cuda_copy,tcp" \ - -e VLLM_NIXL_SIDE_CHANNEL_PORT=5555 \ - -e VLLM_NIXL_SIDE_CHANNEL_HOST=localhost \ - -e VLLM_LOGGING_LEVEL=DEBUG \ - -e HF_HOME=/models ghcr.io/llm-d/llm-d:0.0.8 --model Qwen/Qwen3-0.6B \ - --enforce-eager \ - --port 8001 \ - --kv-transfer-config='{"kv_connector":"NixlConnector","kv_role":"kv_both"}' -``` - -In another terminal, run this command to start the prefiller: - -``` -$ podman run --network host --device nvidia.com/gpu=1 -v $HOME/models:/models \ - -e UCX_TLS="cuda_ipc,cuda_copy,tcp" \ - -e VLLM_NIXL_SIDE_CHANNEL_PORT=5556 \ - -e VLLM_NIXL_SIDE_CHANNEL_HOST=localhost \ - -e VLLM_LOGGING_LEVEL=DEBUG \ - -e HF_HOME=/models ghcr.io/llm-d/llm-d:0.0.8 --model Qwen/Qwen3-0.6B \ - --enforce-eager \ - --port 8002 \ - --kv-transfer-config='{"kv_connector":"NixlConnector","kv_role":"kv_both"}' -``` - -2. Clone and start the routing proxy. - -In another terminal, clone this repository and build the routing proxy: - -``` -$ git clone https://github.com/llm-d/llm-d-routing-sidecar.git && \ - cd llm-d-routing-sidecar && \ - make build -``` - -In the same terminal, start the routing proxy: - -``` -$ ./bin/llm-d-routing-sidecar -port=8000 -vllm-port=8001 -connector=nixlv2 -``` - -3. Send a request. - -Finally, in another terminal, send a chat completions request to the router proxy on port 8000 and tell it to use the prefiller on port 8002: - -``` -$ curl http://localhost:8000/v1/completions \ - -H "Content-Type: application/json" \ - -H "x-prefiller-url: http://localhost:8002" \ - -d '{ - "model": "Qwen/Qwen3-0.6B", - "prompt": "Author-contribution statements and acknowledgements in research papers should state clearly and specifically whether, and to what extent, the authors used AI technologies such as ChatGPT in the preparation of their manuscript and analysis. They should also indicate which LLMs were used. This will alert editors and reviewers to scrutinize manuscripts more carefully for potential biases, inaccuracies and improper source crediting. Likewise, scientific journals should be transparent about their use of LLMs, for example when selecting submitted manuscripts. Mention the large language model based product mentioned in the paragraph above:" - }' -``` - -4. Verification - -Observe the request is processed by both the prefiller and then the decoder: - -*Prefiller logs (trimmed for clarity purpose):* - -``` -... -Received request cmpl-386a7566-31a0-11f0-b783-0200017aca02-0: prompt: ... -... -NIXLConnector request_finished, request_status=7 ... -``` - -*Decoder logs (trimmed for clarity purpose):* -``` -... -Received request cmpl-386a7566-31a0-11f0-b783-0200017aca02-0: prompt: ... -... -DEBUG 05-15 15:21:06 [nixl_connector.py:646] start_load_kv for request cmpl-386a7566-31a0-11f0-b783-0200017aca02-0 from remote engine c53ac287-36cd-4b52-811f-16de4e4bd3a5. Num local_block_ids: 6. Num remote_block_ids: 6 -... - -## Development - -### Building the routing proxy - -Build the routing proxy from source: - -```sh -$ make build -``` - -Check the build was successful by running it locally: - -``` -$ ./bin/llm-d-routing-sidecar -help -Usage of ./bin/llm-d-routing-sidecar: - -connector string - the P/D connector being used. Either nixl, nixlv2 or lmcache (default "nixl") - -port string - the port the sidecar is listening on (default "8000") - -vllm-port string - the port vLLM is listening on (default "8001") -... -``` - -> **Note:** lmcache connector is deprecated. - - -## License - -This project is licensed under the Apache License 2.0. See the [LICENSE](@site/docs/assets/files/LICENSE) file for details. diff --git a/docs/architecture/Components/06_kv-cache.md b/docs/architecture/Components/06_kv-cache.md deleted file mode 100644 index 1545c8b..0000000 --- a/docs/architecture/Components/06_kv-cache.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -sidecar_position: 06 -sidecar_label: KV-Cache Manager ---- -# KV-Cache Manager - -## Introduction - -LLM inference can be computationally expensive due to the sequential nature of token generation. -KV-caching plays a critical role in optimizing this process. By storing previously computed key and value attention vectors, -KV-cache reuse avoids redundant computations during inference, significantly reducing latency and resource consumption. -This is particularly beneficial for long context multi-turn conversations or Agentic (&RAG) applications where -previously computed information can be leveraged effectively. -Efficient KV-cache management and routing are essential for scaling LLM inference and delivering a responsive user experience. - -llmd-kv-cache-manager is a pluggable KV-cache Manager for KV-cache Aware Routing in LLM serving platforms. - -This initial work will expand in capacity as development continues. - - See the [docs folder in the repository](https://github.com/llm-d/llm-d-kv-cache-manager/blob/main/docs/README.md) for more information on goals, architecture and more. - -## Goals - -The KV-Cache-Manager is designed to connect high-level serving-stack goals with concrete system capabilities through a layered objective structure: - -- **Improve user experience** - - By reducing Time-To-First-Token (TTFT) - - Enabled through higher KVCache hit rates and reduced tensor transfers - - Supported by smart routing and distributed cache availability - - Optimized by proactive pre-placement of hot caches and session duplication/migration -- **Reduce serving costs** - - By improving compute utilization - - Minimize re-compute via KVCache reuse and locality-aware request handling - - Leverage zero-copy cache transfers across nodes -- **Enable system scalability** - - Through a distributed KVCache pool - - Allows cache offloading and reuse across multiple serving instances - - User session duplication/migration for true and seamless load balancing - - -## Vision - -This goal structure above is shaped by our vision for emerging use cases like RAG and agentic workflows, -which involve heavy context-reuse across sessions and instances. -Shared documents, tool prompts, and workflow steps create overlapping token streams that benefit significantly from -cross-instance KVCache coordination. - -To implement this vision, the KVCache-Manager incorporates proactive cache placement, session duplication, -and cluster-level cache APIs - bridging gaps in current serving stacks where KVCache management and utilization is -not yet treated as a first-class concern. - -## Architecture Overview - -The code defines a [kvcache.Indexer](https://github.com/llm-d/llm-d-kv-cache-manager/blob/main/pkg/kvcache/indexer.go) module that efficiently maintains a global view of KV-cache states and localities. -In the current state of vLLM, the only available information on KV-cache availability is that of the offloaded tensors to KV-cache Engines via the Connector API. - -The `kvcache.Indexer` module is a pluggable Go package designed for use by orchestrators to enable KV-cache-aware scheduling decisions. - -```mermaid -graph - subgraph Cluster - Router - subgraph KVCacheManager[KV-cache Manager] - kvcache.Indexer[KV-cache Indexer] - PrefixStore[LRU Prefix Store] - KVBlockToPodIndex[KVBlock to Pod availability Index] - end - subgraph vLLMNode[vLLM Node] - vLLMCore[vLLM Core] - KVCacheEngine["KV-cache Engine (LMCache)"] - end - Redis - end - - Router -->|"Score(prompt, ModelName, relevantPods)"| kvcache.Indexer - kvcache.Indexer -->|"{Pod to Scores map}"| Router - Router -->|Route| vLLMNode - - kvcache.Indexer -->|"FindLongestTokenizedPrefix(prompt, ModelName) -> tokens"| PrefixStore - PrefixStore -->|"DigestPromptAsync"| PrefixStore - kvcache.Indexer -->|"GetPodsForKeys(tokens) -> {KVBlock keys to Pods} availability map"| KVBlockToPodIndex - KVBlockToPodIndex -->|"Redis MGet(blockKeys) -> {KVBlock keys to Pods}"| Redis - - vLLMCore -->|Connector API| KVCacheEngine - KVCacheEngine -->|"UpdateIndex(KVBlock keys, nodeIP)"| Redis -``` -This overview greatly simplifies the actual architecture and combines steps across several submodules. - - - -## Architecture - -For even more a detailed architecture, refer to the [architecture](https://github.com/llm-d/llm-d-kv-cache-manager/tree/main/docs/architecture.md) document. - -The architecture is designed to efficiently maintain a global view of KV-cache states and localities, enabling KV-cache-aware scheduling decisions. - -### Detailed System Flow - -```mermaid -sequenceDiagram - participant U as User - participant KVI as kvcache.Indexer - box - participant KVBS as KVBlockScorer - participant TPR as TokenProcessor - participant KVBI as KVBlockIndexer - participant Redis as Redis - end - box - participant PS as PrefixStore - participant LRUS as LRUStore - participant TS as TrieStore - end - box - participant TPO as TokenizersPool - participant W as Worker - participant CHT as HuggingFaceTokenizer - participant CH as TokenizersCache - end - -# kvcache.Indexer -U->>KVI: 1. Score(prompt, ModelName, relevantPods) - -# get available tokens of longest prefix -KVI->>PS: 2. FindLongestTokenizedPrefix(prompt, ModelName) - alt LRU - PS->>LRUS: 2.1 BuildLongestPrefix(prompt, ModelName) - else Trie - PS->>TS: 2.1 BuildLongestPrefix(prompt, ModelName) - end -PS->>KVI: 2.2 Tokens of longest prefix - -# get block keys -KVI->>TPR: 3 GetBlockKeys(tokens, ModelName) - TPR->>KVI: 3.1 BlockKeys - -# query kvblock indexer for pods -KVI->>KVBI: 4. GetPodsForKeys(blockKeys, relevantPods) -KVBI->>Redis: 4.1 MGet(blockKeys) -Redis->>KVBI: 4.2 key -> Pods mapping (KV-cache availability) -KVBI->>KVBI: 4.3 FilterPods(relevantPods) - -# score pods -KVI->>KVBS: 5. ScorePods(key->Pods) based on strategy - -# results -KVI->>U: 6. Pod -> Score mapping - -# add to tokenizers pool -KVI->>TPO: 2. AddTask(prompt, ModelName) // Registers task only -Note over TPO: Task added to queue -W-->>TPO: 2.1 Get(Task) // Async worker fetches task -W->>CHT: 2.3 Tokenize(prompt, ModelName) -CHT->>CH: 2.4 GetCachedTokenizerForModel() -CHT->>W: 2.5 Tokens -W->>PS: 2.6 AddTokens(prompt, ModelName, tokens) -alt LRU - PS->>LRUS: 2.7 AddTokens(prompt, ModelName, tokens) -else Trie - PS->>TS: 2.7 AddTokens(prompt, ModelName, tokens) -end -``` - -### Explanation -The main blocking sequence of steps that happens when a user (e.g., router) sends a request to the kvcache.Indexer is as follows: -1. **User** sends a request to the **kvcache.Indexer** with a prompt, model name, and relevant pods. -2. **kvcache.Indexer**: - - Finds the longest tokenized prefix for the prompt and model name using the **PrefixStore**. - - Depending on the store type (LRU or Trie), it gets the tokenization of the longest cached prefix - - Adds a tokenization task to the **TokenizersPool**, which is handled asynchronously by a worker. This bit is explained later. -3. **kvcache.Indexer** queries the **TokenProcessor** to get block keys for the tokens of the longest prefix. -4. **TokenProcessor**: - - Chunks the tokens and generate keys for the token blocks. The chunking and key calculating has to be aligned with - the source that feeds the key -> pods backend (Redis). - - Returns the block keys to the **kvcache.Indexer**. -5. **kvcache.Indexer** queries the **KVBlockIndexer** for pods that have the block keys. - - The **KVBlockIndexer** queries the **Redis** backend for the mappings with MGet. - - The **Redis** backend efficiently returns the key -> pods mapping. -6. **kvcache.Indexer** uses the configured **KVBlockScorer** to score the pods based block hits: - - LongestPrefixMatch: scores by the longest consecutive (ordered) block hits in a single pod. - - HighestBlockHit: scores by the index of the highest block hit in a single pod. - - CoverageBasedMatching: scores by the total number of block hits in a single pod. - -Asynchronous tokenization flow: -1. A worker fetches the task from the **TokenizersPool**. -2. The worker tokenizes the prompt using the **HuggingFaceTokenizer**. -3. The **HuggingFaceTokenizer** retrieves the cached in-memory tokenizer for the model. - - If the tokenizer is not cached, it gets created and cached. -4. The **HuggingFaceTokenizer** returns the tokens to the worker. -5. The worker adds the tokens to the **PrefixStore**. - - Depending on the store type (LRU or Trie), it adds the tokens to the appropriate store: - - LRUStore: an LRU HashTable of prompt-chunks to tokens - - TrieStore: a Trie of characters to tokens - - Due to the nature of how tokenizers operate, the tokenization of a prefix of a prompt is a prefix of the tokenization of the full prompt. - One challenge in tokenization is that different chunks of a prompt map to different tokens. - Therefore, when we chunk a prompt, we use the [_, end] index associated with the tokens to contain token in a chunk. - The implication of this design is that the tokens contained in a chunk are only correct if all previous chunks are also considered, - since one token may be associated with the edge-characters of two consecutive chunks. - -### Maintenance of Redis for KVBlock -> Pods Mapping - -Currently, indexing information is updated from vLLM for the offloaded tokens using the Connector API, specifically leveraging the LMCache connector. - -Future enhancements will enable the `llm-d-kv-cache-manager` component to process KV-cache events across all memory layers of vLLM, ensuring an accurate holistic view of KV-cache localities throughout the system. - - - -## Examples - -- [KV-cache Indexer](https://github.com/llm-d/llm-d-kv-cache-manager/tree/main/examples/kv_cache_index): - - A reference implementation of using the `kvcache.Indexer` module. -- [KV-cache Aware Scorer](https://github.com/llm-d/llm-d-kv-cache-manager/tree/main/examples/kv_cache_aware_scorer): - - A reference implementation of integrating the `kvcache.Indexer` module in - [llm-d-inference-scheduler](https://github.com/llm-d/llm-d-inference-scheduler) in a KV-cache aware scorer. diff --git a/docs/community/partners.md.exclude b/docs/community/partners.md.exclude deleted file mode 100644 index 6874885..0000000 --- a/docs/community/partners.md.exclude +++ /dev/null @@ -1,5 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Partners diff --git a/docs/contributing-to-docs.md b/docs/contributing-to-docs.md deleted file mode 100644 index c8a2be9..0000000 --- a/docs/contributing-to-docs.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Contributing to the Docs - -Contributing to the docs is very simple! All of the Docs section is created using MarkDown. - -Click the 'Edit this page' button below to test it out! \ No newline at end of file diff --git a/docs/intro.md b/docs/intro.md deleted file mode 100644 index 653528b..0000000 --- a/docs/intro.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Getting Started - -## Fork and Clone the Repository - -Fork the repositorty of the site on our [GitHub](https://https://github.com/RedHatOfficial/static-website-template-for-ospo). - -Clone your fork to your own computer then using this command and replacing the link with your own HTTPS clone link found underneath the **Code** button (see image below): - -```bash -git clone https://github.com/[USERNAME]/[NAME-OF-FORK] -``` - -![Location of HTML clone link](./images/clone-repo.png) - -## Start the Site - -Install [Node.js](https://nodejs.org/en) if you do not have it on your local machine. - -Run `node --version` in your terminal to check to see if you have it installed correctly. It should come back with a version number (vX.Y.Z): - -Run a fresh install of npm on the project: - -```bash -cd [NAME-OF-FILE] -npm install -``` - -Run the server itself with this command: - -```bash -npm start -``` - -The `cd` command changes the directory you're working with. - -The `npm start` command builds your website locally and serves it through a development server, ready for you to view at http://localhost:3000/. - -Open `docs/intro.md` (this page) and edit some lines: the site **reloads automatically** and displays your changes. - -## Using Docusaurus - -Docusaurus is a static-site generator that convetakes Markdown files and donverts them into a documentation website. It is written in JavaScript however no prior knowledge of JavaScript is needed to edit the website. diff --git a/docusaurus.config.js b/docusaurus.config.js index 0bb912a..34fa25e 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -185,7 +185,7 @@ const config = { items: [ { label: "Overview", - to: "docs/architecture/architecture", + to: "docs/architecture", }, /* { label: "FAQ", diff --git a/release-info.json b/release-info.json new file mode 100644 index 0000000..a14a961 --- /dev/null +++ b/release-info.json @@ -0,0 +1,16 @@ +{ + "current": { + "version": "v0.2.0", + "releaseDate": "2024-07-29", + "releaseDateFormatted": "July 29, 2024", + "releaseUrl": "https://github.com/llm-d/llm-d/releases/tag/v0.2.0", + "releaseName": "llm-d v0.2.0" + }, + "latest": { + "version": "v0.2.0", + "releaseDate": "2024-07-29", + "releaseDateFormatted": "July 29, 2024", + "releaseUrl": "https://github.com/llm-d/llm-d/releases/tag/v0.2.0", + "releaseName": "llm-d v0.2.0" + } +} \ No newline at end of file diff --git a/remote-content/README.md b/remote-content/README.md index 50bc435..cc56d3f 100644 --- a/remote-content/README.md +++ b/remote-content/README.md @@ -2,11 +2,19 @@ Automatically download and sync content from remote repositories (like GitHub) into your Docusaurus site. Each remote file gets its own configuration with automatic source attribution and edit links. +## 🎯 Features + +- **Automatic Content Syncing** - Downloads content from remote repositories during build +- **Source Attribution** - Adds "Content Source" banners with edit links (now at bottom of pages) +- **Component Auto-Generation** - Automatically creates documentation for all components +- **Link Transformation** - Fixes relative links to work in the documentation site +- **Repository Transforms** - Handles different repository structures and conventions + ## πŸš€ Quick Start ### 1. Copy & Edit Template ```bash -cp config/remote-sources/example-readme.js.template config/remote-sources/my-content.js +cp remote-content/remote-sources/example-readme.js.template remote-content/remote-sources/my-content.js ``` Edit the file and replace these placeholders: @@ -19,7 +27,7 @@ Edit the file and replace these placeholders: ### 2. Add to System ```javascript -// config/remote-content.js +// remote-content/remote-content.js import myContent from './remote-sources/my-content.js'; const remoteContentPlugins = [ @@ -34,19 +42,63 @@ const remoteContentPlugins = [ npm start ``` +## πŸ—οΈ Architecture + +### Component Auto-Generation + +The system automatically generates documentation for all components listed in `component-configs.js`. This includes: +- Fetching README files from component repositories +- Adding consistent frontmatter and navigation +- Applying repository-specific transformations +- Creating source attribution banners + +### Repository Transforms + +Different repositories may have different link structures or conventions. The `repo-transforms.js` file handles: +- Fixing relative links to point to the correct repositories +- Adjusting image paths +- Handling repository-specific markdown formats + ## πŸ“ File Structure ``` -config/ +remote-content/ β”œβ”€β”€ remote-content.js # Main system (imports all sources) β”œβ”€β”€ remote-sources/ β”‚ β”œβ”€β”€ utils.js # Shared utilities +β”‚ β”œβ”€β”€ repo-transforms.js # Repository-specific transformations +β”‚ β”œβ”€β”€ component-configs.js # Component repository configurations +β”‚ β”œβ”€β”€ components-generator.js # Auto-generates component documentation +β”‚ β”œβ”€β”€ architecture-main.js # Main architecture documentation β”‚ β”œβ”€β”€ contribute.js # Contributing guide β”‚ β”œβ”€β”€ code-of-conduct.js # Code of conduct -β”‚ └── example-readme.js.template # Copy this for new sources +β”‚ β”œβ”€β”€ security.js # Security policy +β”‚ β”œβ”€β”€ sigs.js # Special Interest Groups +β”‚ β”œβ”€β”€ guide-*.js # User guide sections +β”‚ └── example-readme.js.template # Template for new sources └── README.md # This file ``` +## πŸ”§ Adding Components + +To add a new component to the auto-generation system: + +1. **Add to component-configs.js**: + ```javascript + export const COMPONENT_CONFIGS = [ + // ... existing components + { + name: 'your-component-name', + org: 'llm-d', // or other org + branch: 'main', // or 'dev' + description: 'Description of your component', + sidebarPosition: 10 // adjust as needed + } + ]; + ``` + +2. **Component will auto-appear** in the next build under `/docs/architecture/Components/` + ## πŸ› Troubleshooting | Problem | Fix | @@ -54,5 +106,17 @@ config/ | Page not appearing | Check source URL is publicly accessible | | Build errors | Verify all `YOUR-...` placeholders are replaced | | Wrong sidebar order | Check `sidebarPosition` numbers | -| Links broken | Use `contentTransform` to fix relative links | -| Import errors | Ensure file is imported in `config/remote-content.js` | \ No newline at end of file +| Links broken | Use `contentTransform` to fix relative links or add to `repo-transforms.js` | +| Import errors | Ensure file is imported in `remote-content/remote-content.js` | +| Component not showing | Check `component-configs.js` and ensure repository is public | +| Source banner missing | Verify you're using `createContentWithSource()` from utils.js | +| Banner at wrong location | Source banners now appear at bottom of pages automatically | + +## πŸ“ Content Source Banners + +All synced content automatically includes a "Content Source" banner at the **bottom** of the page with: +- Link to the original source file +- Edit link for contributors +- Link to file issues + +This helps users understand where content comes from and how to contribute changes. \ No newline at end of file diff --git a/remote-content/remote-content.js b/remote-content/remote-content.js index 81ad860..476a629 100644 --- a/remote-content/remote-content.js +++ b/remote-content/remote-content.js @@ -6,6 +6,10 @@ import codeOfConductSource from './remote-sources/code-of-conduct.js'; import securitySource from './remote-sources/security.js'; import sigsSource from './remote-sources/sigs.js'; +// Import architecture remote content sources +import architectureMainSource from './remote-sources/architecture-main.js'; +import componentSources from './remote-sources/components-generator.js'; + // Import guide remote content sources import guideExamplesSource from './remote-sources/guide-examples.js'; import guidePrerequisitesSource from './remote-sources/guide-prerequisites.js'; @@ -37,6 +41,10 @@ const remoteContentPlugins = [ securitySource, sigsSource, + // Architecture remote content sources + architectureMainSource, + ...componentSources, // Spread all dynamically generated component sources + // Guide remote content sources guideExamplesSource, guidePrerequisitesSource, diff --git a/remote-content/remote-sources/architecture-main.js b/remote-content/remote-sources/architecture-main.js new file mode 100644 index 0000000..1806940 --- /dev/null +++ b/remote-content/remote-sources/architecture-main.js @@ -0,0 +1,51 @@ +/** + * Main Architecture README Remote Content + * + * Downloads the README.md file from the main llm-d repository + * and transforms it into docs/architecture/00_architecture.mdx + */ + +import { createContentWithSource } from './utils.js'; +import { getRepoTransform } from './repo-transforms.js'; + +export default [ + 'docusaurus-plugin-remote-content', + { + // Basic configuration + name: 'architecture-main', + sourceBaseUrl: 'https://raw.githubusercontent.com/llm-d/llm-d/dev/', + outDir: 'docs/architecture', + documents: ['README.md'], + + // Plugin behavior + noRuntimeDownloads: false, // Download automatically when building + performCleanup: true, // Clean up files after build + + // Transform the content for this specific document + modifyContent(filename, content) { + if (filename === 'README.md') { + return createContentWithSource({ + title: 'llm-d Architecture', + description: 'Overview of llm-d distributed inference architecture and components', + sidebarLabel: 'llm-d Architecture', + sidebarPosition: 0, + filename: 'README.md', + newFilename: 'architecture.mdx', + repoUrl: 'https://github.com/llm-d/llm-d', + branch: 'dev', + content, + // Transform content to work in docusaurus context + contentTransform: (content) => { + // Get the appropriate repository transform + const transform = getRepoTransform('llm-d', 'llm-d'); + return transform(content, { + repoUrl: 'https://github.com/llm-d/llm-d', + branch: 'dev' + }); + } + }); + } + return undefined; + }, + }, +]; \ No newline at end of file diff --git a/remote-content/remote-sources/component-configs.js b/remote-content/remote-sources/component-configs.js new file mode 100644 index 0000000..8e7af73 --- /dev/null +++ b/remote-content/remote-sources/component-configs.js @@ -0,0 +1,66 @@ +/** + * Shared Component Configurations + * + * Central location for all llm-d component definitions used across + * the documentation system. This eliminates duplication and ensures + * consistency across different generators. + */ + +export const COMPONENT_CONFIGS = [ + { + name: 'llm-d-inference-scheduler', + org: 'llm-d', + branch: 'main', + description: 'vLLM-optimized inference scheduler with smart load balancing', + category: 'Core Infrastructure', + sidebarPosition: 1 + }, + { + name: 'llm-d-modelservice', + org: 'llm-d-incubation', + branch: 'main', + description: 'Helm chart for declarative LLM deployment management', + category: 'Infrastructure Tools', + sidebarPosition: 2 + }, + { + name: 'llm-d-routing-sidecar', + org: 'llm-d', + branch: 'main', + description: 'Reverse proxy for prefill and decode worker routing', + category: 'Core Infrastructure', + sidebarPosition: 3 + }, + { + name: 'llm-d-inference-sim', + org: 'llm-d', + branch: 'main', + description: 'Lightweight vLLM simulator for testing and development', + category: 'Development Tools', + sidebarPosition: 4 + }, + { + name: 'llm-d-infra', + org: 'llm-d-incubation', + branch: 'main', + description: 'Examples, Helm charts, and release assets for llm-d infrastructure', + category: 'Infrastructure Tools', + sidebarPosition: 5 + }, + { + name: 'llm-d-kv-cache-manager', + org: 'llm-d', + branch: 'main', + description: 'Pluggable service for KV-Cache aware routing and cross-node coordination', + category: 'Core Infrastructure', + sidebarPosition: 6 + }, + { + name: 'llm-d-benchmark', + org: 'llm-d', + branch: 'main', + description: 'Automated workflow for benchmarking LLM inference performance', + category: 'Development Tools', + sidebarPosition: 7 + } +]; \ No newline at end of file diff --git a/remote-content/remote-sources/components-generator.js b/remote-content/remote-sources/components-generator.js new file mode 100644 index 0000000..f6fe250 --- /dev/null +++ b/remote-content/remote-sources/components-generator.js @@ -0,0 +1,209 @@ +/** + * Dynamic Components Remote Content Generator + * + * Generates remote content configurations for all components listed in the v0.2.0 release + * This creates a foundation for automatically syncing component documentation + */ + +import { createContentWithSource } from './utils.js'; +import { COMPONENT_CONFIGS } from './component-configs.js'; +import { getRepoTransform } from './repo-transforms.js'; +import fs from 'fs'; +import path from 'path'; + +/** + * Generate a remote content configuration for a single component + * @param {Object} config - Component configuration + * @returns {Array} Remote content plugin configuration + */ +function generateComponentRemoteSource(config) { + const { name, org, branch, description, sidebarPosition } = config; + const repoUrl = `https://github.com/${org}/${name}`; + const sourceBaseUrl = `https://raw.githubusercontent.com/${org}/${name}/${branch}/`; + + return [ + 'docusaurus-plugin-remote-content', + { + // Basic configuration + name: `component-${name}`, + sourceBaseUrl, + outDir: 'docs/architecture/Components', + documents: ['README.md'], + + // Plugin behavior + noRuntimeDownloads: false, + performCleanup: true, + + // Transform the content for this specific document + modifyContent(filename, content) { + if (filename === 'README.md') { + // Generate clean names without llm-d prefix + const cleanName = name.replace(/^llm-d-/, ''); + const cleanTitle = cleanName.split('-').map(word => + word.charAt(0).toUpperCase() + word.slice(1) + ).join(' '); + + return createContentWithSource({ + title: cleanTitle, + description, + sidebarLabel: cleanTitle, + sidebarPosition, + filename: 'README.md', + newFilename: `${cleanName}.md`, + repoUrl, + branch, + content, + // Transform content to work in docusaurus context + contentTransform: (content) => { + // Get the appropriate repository transform + const transform = getRepoTransform(org, name); + return transform(content, { repoUrl, branch, org, name }); + } + }); + } + return undefined; + }, + }, + ]; +} + +/** + * Generate the components overview page content + * @returns {string} Markdown content for the overview page + */ +function generateComponentsOverviewContent() { + // Read version information from release-info.json + let versionInfo; + try { + const releaseInfoPath = path.resolve('./release-info.json'); + const releaseInfoContent = fs.readFileSync(releaseInfoPath, 'utf8'); + versionInfo = JSON.parse(releaseInfoContent).current; + } catch (error) { + console.warn('Could not read release-info.json, using fallback data'); + versionInfo = { + version: 'v0.2.0', + releaseDateFormatted: 'July 29, 2024', + releaseUrl: 'https://github.com/llm-d/llm-d/releases/tag/v0.2.0', + releaseName: 'llm-d v0.2.0' + }; + } + + const currentDate = new Date().toISOString().split('T')[0]; + + // Group components by category + const categorizedComponents = COMPONENT_CONFIGS.reduce((acc, component) => { + if (!acc[component.category]) { + acc[component.category] = []; + } + acc[component.category].push(component); + return acc; + }, {}); + + let content = `--- +title: llm-d Components +description: Overview of all llm-d ecosystem components and their documentation +sidebar_label: Components +sidebar_position: 1 +--- + +# llm-d components + +The llm-d ecosystem consists of multiple interconnected components that work together to provide distributed inference capabilities for large language models. + +## Latest Release: [${versionInfo.version}](${versionInfo.releaseUrl}) + +**Released**: ${versionInfo.releaseDateFormatted} + +:::info Auto-Generated Content +This page is automatically updated from the latest component repository information and release data. Last updated: ${currentDate} +::: + +## Components + +| Component | Description | Repository | Documentation | +|-----------|-------------|------------|---------------|`; + + // Generate single table with all components (sorted by sidebarPosition) + const sortedComponents = COMPONENT_CONFIGS.sort((a, b) => a.sidebarPosition - b.sidebarPosition); + + sortedComponents.forEach((component) => { + const repoUrl = `https://github.com/${component.org}/${component.name}`; + const cleanName = component.name.replace(/^llm-d-/, ''); + const cleanTitle = cleanName.split('-').map(word => + word.charAt(0).toUpperCase() + word.slice(1) + ).join(' '); + const docLink = `./${cleanName}.md`; + + content += `\n| **[${cleanTitle}](${repoUrl})** | ${component.description} | [${component.org}/${component.name}](${repoUrl}) | [View Docs](${docLink}) |`; + }); + + content += ` + +## Getting Started + +Each component has its own detailed documentation page accessible from the links above. For a comprehensive view of how these components work together, see the main [Architecture Overview](../architecture.mdx). + +### Quick Links + +- [Main llm-d Repository](https://github.com/llm-d/llm-d) - Core platform and orchestration +- [llm-d-incubation Organization](https://github.com/llm-d-incubation) - Experimental and supporting components +- [Latest Release](${versionInfo.releaseUrl}) - ${versionInfo.releaseName} +- [All Releases](https://github.com/llm-d/llm-d/releases) - Complete release history + +## Contributing + +To contribute to any of these components, visit their respective repositories and follow their contribution guidelines. Each component maintains its own development workflow and contribution process. + +--- + +*This page is automatically updated from the component configurations and stays up to date with the latest release information.* +`; + + return content; +} + +/** + * Generate the components overview page remote source + * @returns {Array} Remote content plugin configuration for overview page + */ +function generateComponentsOverviewSource() { + return [ + 'docusaurus-plugin-remote-content', + { + // Basic configuration + name: 'components-overview', + sourceBaseUrl: 'https://raw.githubusercontent.com/llm-d/llm-d/dev/', // Dummy URL + outDir: 'docs/architecture/Components', + documents: ['LICENSE'], // Fetch a small file to trigger modifyContent + + // Plugin behavior + noRuntimeDownloads: false, + performCleanup: true, + + // Generate the overview content + modifyContent(filename, content) { + // Always generate the overview page regardless of the downloaded content + const overviewContent = generateComponentsOverviewContent(); + + return { + filename: 'index.md', + content: overviewContent + }; + }, + }, + ]; +} + +/** + * Generate all component remote sources including the overview page + * @returns {Array} Array of remote content plugin configurations + */ +function generateAllComponentSources() { + return [ + generateComponentsOverviewSource(), // Overview page first + ...COMPONENT_CONFIGS.map(generateComponentRemoteSource) // Individual components + ]; +} + +// Export the generated component sources +export default generateAllComponentSources(); \ No newline at end of file diff --git a/remote-content/remote-sources/guide-examples.js b/remote-content/remote-sources/guide-examples.js index e7d6aa4..66d9280 100644 --- a/remote-content/remote-sources/guide-examples.js +++ b/remote-content/remote-sources/guide-examples.js @@ -6,6 +6,7 @@ */ import { createContentWithSource } from './utils.js'; +import { getRepoTransform } from './repo-transforms.js'; export default [ 'docusaurus-plugin-remote-content', @@ -33,26 +34,26 @@ export default [ repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', branch: 'main', content, - // Transform content to work in docusaurus context - contentTransform: (content) => content + // Transform content using repository-specific logic + contentTransform: (content) => { // Add what is llm-d section before the main content - .replace(/^# /, `**What is llm-d?** + const withIntro = content.replace(/^# /, `**What is llm-d?** llm-d is an open source project providing distributed inferencing for GenAI runtimes on any Kubernetes cluster. Its highly performant, scalable architecture helps reduce costs through a spectrum of hardware efficiency improvements. The project prioritizes ease of deployment+use as well as SRE needs + day 2 operations associated with running large GPU clusters. -[For more information check out the Architecture Documentation](/docs/architecture/00_architecture.mdx) +[For more information check out the Architecture Documentation](/docs/architecture) -# `) - // Fix relative links to work within the guide section - .replace(/README\.md/g, '') - // Fix specific broken links - .replace(/\]\(TBD\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/examples/)') - .replace(/\]\(\.\/(sim)\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/examples/sim/README.md)') - // Fix Installation links to work within Docusaurus guide structure - // Use absolute paths within the docs structure to ensure correct resolution - .replace(/\]\(\.\/(inference-scheduling)\)/g, '](/docs/guide/Installation/$1)') - .replace(/\]\(\.\/(pd-disaggregation)\)/g, '](/docs/guide/Installation/$1)') - .replace(/\]\(\.\/(wide-ep-lws)\)/g, '](/docs/guide/Installation/$1)') +# `); + + // Apply repository-specific transforms (all links go to GitHub) + const transform = getRepoTransform('llm-d-incubation', 'llm-d-infra'); + return transform(withIntro, { + repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', + branch: 'main', + org: 'llm-d-incubation', + name: 'llm-d-infra' + }); + } }); } return undefined; diff --git a/remote-content/remote-sources/guide-inference-scheduling.js b/remote-content/remote-sources/guide-inference-scheduling.js index 2816726..05552a6 100644 --- a/remote-content/remote-sources/guide-inference-scheduling.js +++ b/remote-content/remote-sources/guide-inference-scheduling.js @@ -6,6 +6,7 @@ */ import { createContentWithSource } from './utils.js'; +import { getRepoTransform } from './repo-transforms.js'; export default [ 'docusaurus-plugin-remote-content', @@ -33,39 +34,16 @@ export default [ repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', branch: 'main', content, - // Transform content to work in docusaurus context - contentTransform: (content) => content - // Fix MDX compilation issues with angle bracket URLs - .replace(/<(http[s]?:\/\/[^>]+)>/g, '`$1`') - - // CRITICAL: Fix istio-workaround.md FIRST before any other URL transformations - .replace(/\]\([^)]*istio-workaround\.md\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/istio-workaround.md)') - - // Fix specific problematic links first (before general patterns) - .replace(/\[install\-deps\.sh\]\(\.\.\/\.\.\/install\-deps\.sh\)/g, '[install-deps.sh](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/install-deps.sh)') - .replace(/\[gke\.md\]\(gke\.md\)/g, '[gke.md](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/examples/inference-scheduling/gke.md)') - .replace(/\[gke\.md\]\(\.\/gke\.md\)/g, '[gke.md](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/examples/inference-scheduling/gke.md)') - .replace(/\[scheduling configuration\]\(https\:\/\/github\.com\/llm\-d\/llm\-d\-inference\-scheduler\/blob\/main\/docs\/architecture\.md\)/g, '[scheduling configuration](https://github.com/llm-d/llm-d-inference-scheduler/blob/main/docs/architecture.md)') - - // Fix broken external references - .replace(/\]\(\.\.\/\.\.\/precise-prefix-cache-aware\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/tree/main/quickstart/examples/precise-prefix-cache-aware)') - .replace(/\]\(precise-prefix-cache-aware\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/tree/main/quickstart/examples/precise-prefix-cache-aware)') - .replace(/\]\(\.\.\/precise-prefix-cache-aware\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/tree/main/quickstart/examples/precise-prefix-cache-aware)') - - // Fix relative path resolution for install-deps.sh (catch any remaining patterns) - .replace(/\]\(\.\.\/\.\.\/\.\.\/([^)]+\.sh)\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/$1)') - // Fix any remaining ../../../*.md patterns before general md processing - .replace(/\]\(\.\.\/\.\.\/\.\.\/([^)]+\.md)\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/$1)') - - // Fix relative links (but be more careful) - .replace(/\]\(\.\.\//g, '](../../') - .replace(/\]\(\.\//g, '](') - - // Fix file references to point to repository (only if not already a full URL) - .replace(/\]\((?!https?:\/\/)([^)]+\.(yaml|sh))\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/examples/inference-scheduling/$1)') - - // Convert other relative markdown links to repository links (only if not already a full URL) - .replace(/\]\((?!https?:\/\/)([^)]+\.md)\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/examples/inference-scheduling/$1)') + // Transform content using repository-specific logic + contentTransform: (content) => { + const transform = getRepoTransform('llm-d-incubation', 'llm-d-infra'); + return transform(content, { + repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', + branch: 'main', + org: 'llm-d-incubation', + name: 'llm-d-infra' + }); + } }); } return undefined; diff --git a/remote-content/remote-sources/guide-pd-disaggregation.js b/remote-content/remote-sources/guide-pd-disaggregation.js index dc9005d..118ea44 100644 --- a/remote-content/remote-sources/guide-pd-disaggregation.js +++ b/remote-content/remote-sources/guide-pd-disaggregation.js @@ -6,6 +6,7 @@ */ import { createContentWithSource } from './utils.js'; +import { getRepoTransform } from './repo-transforms.js'; export default [ 'docusaurus-plugin-remote-content', @@ -33,18 +34,16 @@ export default [ repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', branch: 'main', content, - // Transform content to work in docusaurus context - contentTransform: (content) => content - // Fix relative links - .replace(/\]\(\.\.\//g, '](../../') - .replace(/\]\(\.\//g, '](') - // Fix MDX compilation issues with angle bracket URLs - .replace(/<(http[s]?:\/\/[^>]+)>/g, '`$1`') - // Fix file references to point to repository - .replace(/\]\(([^)]+\.(yaml|sh|json))\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/examples/pd-disaggregation/$1)') - .replace(/\]\(\.\.\/\.\.\/\.\.\/([^)]+\.sh)\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/$1)') - // Convert relative markdown links to repository links - .replace(/\]\(([^)]+\.md)\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/examples/pd-disaggregation/$1)') + // Transform content using repository-specific logic + contentTransform: (content) => { + const transform = getRepoTransform('llm-d-incubation', 'llm-d-infra'); + return transform(content, { + repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', + branch: 'main', + org: 'llm-d-incubation', + name: 'llm-d-infra' + }); + } }); } return undefined; diff --git a/remote-content/remote-sources/guide-prerequisites.js b/remote-content/remote-sources/guide-prerequisites.js index bac9a78..f95bbc2 100644 --- a/remote-content/remote-sources/guide-prerequisites.js +++ b/remote-content/remote-sources/guide-prerequisites.js @@ -6,6 +6,7 @@ */ import { createContentWithSource } from './utils.js'; +import { getRepoTransform } from './repo-transforms.js'; export default [ 'docusaurus-plugin-remote-content', @@ -33,35 +34,16 @@ export default [ repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', branch: 'main', content, - // Transform content to work in docusaurus context - contentTransform: (content) => content - // Fix MDX compilation issues with angle bracket URLs - .replace(/<(http[s]?:\/\/[^>]+)>/g, '`$1`') - // Fix broken anchor reference - .replace(/#openshift-and-grafana/g, '#install-on-openshift') - - // Fix specific problematic links first (before general patterns) - .replace(/\[Grafana\ setup\ guide\]\(\.\/grafana\-setup\.md\)/g, '[Grafana setup guide](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/docs/monitoring/grafana-setup.md)') - .replace(/\[llm\-d dashboard\]\(\.\/grafana\/dashboards\/llm\-d\-dashboard\.json\)/g, '[llm-d dashboard](https://raw.githubusercontent.com/llm-d-incubation/llm-d-infra/refs/heads/main/quickstart/docs/monitoring/grafana/dashboards/llm-d-dashboard.json)') - .replace(/\[inference\-gateway\ dashboard\]\(https\:\/\/github\.com\/kubernetes\-sigs\/gateway\-api\-inference\-extension\/blob\/main\/tools\/dashboards\/inference\_gateway\.json\)/g, '[inference-gateway dashboard](https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/refs/heads/main/tools/dashboards/inference_gateway.json)') - - // Fix OpenShift documentation links - use a simple string replacement first - .replace(/docs\/infra-providers\/openshift\/README-openshift\.md/g, 'https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/docs/infra-providers/openshift/README-openshift.md') - // More general pattern for remaining docs paths (only if not already a full URL) - .replace(/\]\((?!https?:\/\/)docs\/([^)]+)\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/docs/$1)') - - // Fix relative path references to files - .replace(/\]\(grafana\/dashboards\/([^)]+)\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/grafana/dashboards/$1)') - - // Fix any remaining relative links that might break (but avoid full URLs) - .replace(/\]\(examples\//g, '](../') - .replace(/\]\(\.\//g, '](') - - // Convert relative markdown links to repository links (only if not already a full URL) - .replace(/\]\((?!https?:\/\/)([^)]+\.md)\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/$1)') - // Fix file links to point to repository (only if not already a full URL) - .replace(/\]\((?!https?:\/\/)([^)]+\.(yaml|json|sh))\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/$1)') - + // Transform content using repository-specific logic + contentTransform: (content) => { + const transform = getRepoTransform('llm-d-incubation', 'llm-d-infra'); + return transform(content, { + repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', + branch: 'main', + org: 'llm-d-incubation', + name: 'llm-d-infra' + }); + } }); } return undefined; diff --git a/remote-content/remote-sources/guide-wide-ep-lws.js b/remote-content/remote-sources/guide-wide-ep-lws.js index e83fc80..047b9d1 100644 --- a/remote-content/remote-sources/guide-wide-ep-lws.js +++ b/remote-content/remote-sources/guide-wide-ep-lws.js @@ -6,6 +6,7 @@ */ import { createContentWithSource } from './utils.js'; +import { getRepoTransform } from './repo-transforms.js'; export default [ 'docusaurus-plugin-remote-content', @@ -33,18 +34,16 @@ export default [ repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', branch: 'main', content, - // Transform content to work in docusaurus context - contentTransform: (content) => content - // Fix relative links - .replace(/\]\(\.\.\//g, '](../../') - .replace(/\]\(\.\//g, '](') - // Fix MDX compilation issues with angle bracket URLs - .replace(/<(http[s]?:\/\/[^>]+)>/g, '`$1`') - // Fix file references to point to repository - .replace(/\]\(([^)]+\.(yaml|sh|json))\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/examples/wide-ep-lws/$1)') - .replace(/\]\(\.\.\/\.\.\/\.\.\/([^)]+\.sh)\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/$1)') - // Convert relative markdown links to repository links - .replace(/\]\(([^)]+\.md)\)/g, '](https://github.com/llm-d-incubation/llm-d-infra/blob/main/quickstart/examples/wide-ep-lws/$1)') + // Transform content using repository-specific logic + contentTransform: (content) => { + const transform = getRepoTransform('llm-d-incubation', 'llm-d-infra'); + return transform(content, { + repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', + branch: 'main', + org: 'llm-d-incubation', + name: 'llm-d-infra' + }); + } }); } return undefined; diff --git a/remote-content/remote-sources/repo-transforms.js b/remote-content/remote-sources/repo-transforms.js new file mode 100644 index 0000000..9b3c964 --- /dev/null +++ b/remote-content/remote-sources/repo-transforms.js @@ -0,0 +1,87 @@ +/** + * Repository-Specific Transformation System + * + * Two repository types: + * 1. Main llm-d/llm-d repository (keeps docs/ links local) + * 2. Component repositories (all links point to source repo) + */ + +/** + * Apply essential MDX compatibility fixes + */ +function applyBasicMdxFixes(content) { + return content + .replace(/
/g, '
') + .replace(/]*?)>/g, '') + .replace(/]*>/g, '') + .replace(/<\/picture>/g, '') + .replace(/(<(?:img|input|area|base|col|embed|hr|link|meta|param|source|track|wbr)[^>]*?)(?/gi, '$1 />') + .replace(/(<\w+[^>]*?)(\s+\w+)=([^"'\s>]+)([^>]*?>)/g, '$1$2="$3"$4') + .replace(/'(\{[^}]*\})'/g, '`$1`') + .replace(/\{[^}]*\}/g, (match) => { + if (match.includes('"') || match.includes("'") || match.includes('\\') || match.match(/\{[^}]*\d+[^}]*\}/)) { + return '`' + match + '`'; + } + return match; + }) + .replace(/<(http[s]?:\/\/[^>]+)>/g, '`$1`') + .replace(/]*>/gi, '
') + .replace(/]*>/gi, ''); +} + +/** + * Fix all images to point to GitHub raw URLs + */ +function fixImages(content, repoUrl, branch) { + return content + .replace(/!\[([^\]]*)\]\((?!http)([^)]+)\)/g, (match, alt, path) => { + const cleanPath = path.replace(/^\.\//, ''); + return `![${alt}](${repoUrl}/raw/${branch}/${cleanPath})`; + }) + .replace(/]*?)src=["'](?!http)([^"']+)["']([^>]*?)>/g, (match, before, path, after) => { + const cleanPath = path.replace(/^\.\//, ''); + return ``; + }); +} + +/** + * Transform content from the main llm-d/llm-d repository + * Keeps docs/ links pointing to our local docs site + */ +export function transformMainRepo(content, { repoUrl, branch }) { + return fixImages(applyBasicMdxFixes(content), repoUrl, branch) + // Keep docs/ links local (inline format) + .replace(/\]\(docs\//g, '](/docs/architecture/') + .replace(/\]\(\.\/docs\//g, '](/docs/architecture/') + // Keep docs/ links local (reference format) + .replace(/^\[([^\]]+)\]:docs\//gm, `[$1]:/docs/architecture/`) + .replace(/^\[([^\]]+)\]:\.\/docs\//gm, `[$1]:/docs/architecture/`) + // All other relative links go to GitHub + .replace(/\]\((?!http|https|#|\/docs|\/blog|mailto:)([^)]+)\)/g, `](${repoUrl}/blob/${branch}/$1)`) + .replace(/^\[([^\]]+)\]:(?!http|https|#|mailto:|\/docs|\/blog)([^\s]+)/gm, `[$1]:${repoUrl}/blob/${branch}/$2`); +} + +/** + * Transform content from component repositories + * All relative links point back to the source repository + */ +export function transformComponentRepo(content, { repoUrl, branch }) { + return fixImages(applyBasicMdxFixes(content), repoUrl, branch) + // All relative links go to source repository (inline format) + .replace(/\]\((?!http|https|#|mailto:)([^)]+)\)/g, (match, path) => { + const cleanPath = path.replace(/^\]\(/, '').replace(/^\.\//, ''); + return `](${repoUrl}/blob/${branch}/${cleanPath})`; + }) + // All relative links go to source repository (reference format) + .replace(/^\[([^\]]+)\]:(?!http|https|#|mailto:)([^\s]+)/gm, (match, label, path) => { + const cleanPath = path.replace(/^\.\//, ''); + return `[${label}]:${repoUrl}/blob/${branch}/${cleanPath}`; + }); +} + +/** + * Get the appropriate transform function for a repository + */ +export function getRepoTransform(org, name) { + return (org === 'llm-d' && name === 'llm-d') ? transformMainRepo : transformComponentRepo; +} \ No newline at end of file diff --git a/remote-content/remote-sources/sigs.js b/remote-content/remote-sources/sigs.js index 31bbf58..44a5649 100644 --- a/remote-content/remote-sources/sigs.js +++ b/remote-content/remote-sources/sigs.js @@ -6,6 +6,7 @@ */ import { createContentWithSource } from './utils.js'; +import { getRepoTransform } from './repo-transforms.js'; export default [ 'docusaurus-plugin-remote-content', @@ -33,13 +34,14 @@ export default [ repoUrl: 'https://github.com/llm-d/llm-d', branch: 'dev', content, - // Fix relative links and HTML tags for MDX compatibility - contentTransform: (content) => content - .replace(/
/g, '
') - .replace(/
/g, '
') - .replace(/]*?)>/g, '') - .replace(/\(CONTRIBUTING\.md\)/g, '(contribute)') - .replace(/\(PROJECT\.md\)/g, '(https://github.com/llm-d/llm-d/blob/dev/PROJECT.md)') + // Transform content using repository-specific logic + contentTransform: (content) => { + const transform = getRepoTransform('llm-d', 'llm-d'); + return transform(content, { + repoUrl: 'https://github.com/llm-d/llm-d', + branch: 'dev' + }); + } }); } return undefined; diff --git a/remote-content/remote-sources/utils.js b/remote-content/remote-sources/utils.js index 1da81fa..bce3b27 100644 --- a/remote-content/remote-sources/utils.js +++ b/remote-content/remote-sources/utils.js @@ -68,6 +68,6 @@ sidebar_position: ${sidebarPosition} return { filename: newFilename, - content: frontmatter + sourceCallout + transformedContent + content: frontmatter + transformedContent + sourceCallout }; } \ No newline at end of file diff --git a/src/components/Welcome/index.js b/src/components/Welcome/index.js index eaf21ee..334e22b 100644 --- a/src/components/Welcome/index.js +++ b/src/components/Welcome/index.js @@ -17,7 +17,7 @@ export default function Welcome() {
- + Architecture From 65d6da1bef68c73f72ea9a9968bb3f0fbbe4d0f3 Mon Sep 17 00:00:00 2001 From: Pete Cheslock Date: Thu, 31 Jul 2025 12:06:42 -0400 Subject: [PATCH 03/11] Refactor remote content structure and enhance documentation - Updated CONTRIBUTING.md to clarify directory structure for new content types and provided examples for copying templates. - Expanded remote-content/README.md with detailed instructions on content organization and configuration. - Introduced new remote content sources for architecture, community, and guide documentation, allowing for automatic syncing from the llm-d repository. - Added multiple new files for community guidelines, security policies, and various guide topics to improve documentation accessibility. Signed-off-by: Pete Cheslock --- CONTRIBUTING.md | 20 +++- remote-content/README.md | 96 +++++++++++++++---- .../{ => architecture}/architecture-main.js | 31 +++--- .../components-generator.js | 16 +--- .../{ => community}/code-of-conduct.js | 19 ++-- .../{ => community}/contribute.js | 19 ++-- .../{ => community}/security.js | 19 ++-- .../remote-sources/{ => community}/sigs.js | 30 +++--- .../remote-sources/component-configs.js | 47 +++++++++ .../remote-sources/example-readme.js.template | 86 +++++++++++++---- .../{ => guide}/guide-examples.js | 31 +++--- .../{ => guide}/guide-inference-scheduling.js | 34 +++---- .../{ => guide}/guide-pd-disaggregation.js | 32 +++---- .../{ => guide}/guide-prerequisites.js | 34 +++---- .../{ => guide}/guide-wide-ep-lws.js | 32 +++---- remote-content/remote-sources/utils.js | 21 ++++ 16 files changed, 368 insertions(+), 199 deletions(-) rename remote-content/remote-sources/{ => architecture}/architecture-main.js (53%) rename remote-content/remote-sources/{ => architecture}/components-generator.js (91%) rename remote-content/remote-sources/{ => community}/code-of-conduct.js (64%) rename remote-content/remote-sources/{ => community}/contribute.js (68%) rename remote-content/remote-sources/{ => community}/security.js (66%) rename remote-content/remote-sources/{ => community}/sigs.js (54%) rename remote-content/remote-sources/{ => guide}/guide-examples.js (66%) rename remote-content/remote-sources/{ => guide}/guide-inference-scheduling.js (54%) rename remote-content/remote-sources/{ => guide}/guide-pd-disaggregation.js (55%) rename remote-content/remote-sources/{ => guide}/guide-prerequisites.js (50%) rename remote-content/remote-sources/{ => guide}/guide-wide-ep-lws.js (53%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 51bc925..749c1cb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -54,16 +54,26 @@ For content **without** "Content Source" banners: To sync new content from repositories: -1. **Copy the template:** +1. **Choose the right directory** based on content type: + - `architecture/` β†’ `docs/architecture/` + - `guide/` β†’ `docs/guide/` + - `community/` β†’ `docs/community/` + +2. **Copy the template:** ```bash - cp remote-content/remote-sources/example-readme.js.template remote-content/remote-sources/my-content.js + # Choose appropriate directory + cp remote-content/remote-sources/example-readme.js.template remote-content/remote-sources/DIRECTORY/my-content.js + + # Examples: + cp remote-content/remote-sources/example-readme.js.template remote-content/remote-sources/guide/my-guide.js + cp remote-content/remote-sources/example-readme.js.template remote-content/remote-sources/architecture/my-arch-doc.js ``` -2. **Edit configuration** in the new file +3. **Edit configuration** in the new file (note the `../` imports for utils) -3. **Add to system** in `remote-content/remote-content.js` +4. **Add to system** in `remote-content/remote-content.js` -4. **Test** with `npm start` +5. **Test** with `npm start` See [remote-content/README.md](remote-content/README.md) for detailed instructions. diff --git a/remote-content/README.md b/remote-content/README.md index cc56d3f..c3e7ddc 100644 --- a/remote-content/README.md +++ b/remote-content/README.md @@ -12,23 +12,40 @@ Automatically download and sync content from remote repositories (like GitHub) i ## πŸš€ Quick Start -### 1. Copy & Edit Template +### 1. Choose Directory & Copy Template + +Files are organized by their destination in the docs: + +| Directory | Purpose | Final Location | +|-----------|---------|----------------| +| `architecture/` | Architecture docs | `docs/architecture/` | +| `guide/` | User guides & installation | `docs/guide/` | +| `community/` | Community resources | `docs/community/` | + ```bash -cp remote-content/remote-sources/example-readme.js.template remote-content/remote-sources/my-content.js +# Choose the appropriate directory for your content +cp remote-content/remote-sources/example-readme.js.template remote-content/remote-sources/DIRECTORY/my-content.js + +# Examples: +cp remote-content/remote-sources/example-readme.js.template remote-content/remote-sources/guide/my-guide.js +cp remote-content/remote-sources/example-readme.js.template remote-content/remote-sources/architecture/my-component.js ``` -Edit the file and replace these placeholders: + +### 2. Edit Configuration + +Update the copied file and replace these placeholders: | Placeholder | Example | Description | |-------------|---------|-------------| -| `YOUR-CONTENT-NAME` | `user-guide` | Unique name for CLI commands | -| `YOUR-ORG/YOUR-REPO` | `microsoft/vscode` | GitHub repo path | -| `YOUR-SECTION` | `docs/guides` | Where to put the file | -| `YOUR-FILE.md` | `README.md` | Source filename | +| `YOUR-REPO-NAME` | `llm-d-infra` | Repo name from component-configs.js | +| `your-content-name` | `user-guide` | Unique name for CLI commands | +| `docs/YOUR-SECTION` | `docs/guide` | Where to put the file | +| `your-file.md` | `guide.md` | Output filename | -### 2. Add to System +### 3. Add to System ```javascript // remote-content/remote-content.js -import myContent from './remote-sources/my-content.js'; +import myContent from './remote-sources/DIRECTORY/my-content.js'; const remoteContentPlugins = [ contributeSource, @@ -37,7 +54,7 @@ const remoteContentPlugins = [ ]; ``` -### 3. Test +### 4. Test ```bash npm start ``` @@ -65,23 +82,41 @@ Different repositories may have different link structures or conventions. The `r remote-content/ β”œβ”€β”€ remote-content.js # Main system (imports all sources) β”œβ”€β”€ remote-sources/ -β”‚ β”œβ”€β”€ utils.js # Shared utilities +β”‚ β”œβ”€β”€ architecture/ # β†’ docs/architecture/ +β”‚ β”‚ β”œβ”€β”€ architecture-main.js # Main architecture documentation +β”‚ β”‚ └── components-generator.js # Auto-generates component documentation +β”‚ β”œβ”€β”€ guide/ # β†’ docs/guide/ & docs/guide/Installation/ +β”‚ β”‚ β”œβ”€β”€ guide-examples.js # User guide landing page +β”‚ β”‚ β”œβ”€β”€ guide-inference-scheduling.js # Installation guide sections +β”‚ β”‚ β”œβ”€β”€ guide-pd-disaggregation.js # Installation guide sections +β”‚ β”‚ β”œβ”€β”€ guide-prerequisites.js # Installation guide sections +β”‚ β”‚ └── guide-wide-ep-lws.js # Installation guide sections +β”‚ β”œβ”€β”€ community/ # β†’ docs/community/ +β”‚ β”‚ β”œβ”€β”€ code-of-conduct.js # Code of conduct +β”‚ β”‚ β”œβ”€β”€ contribute.js # Contributing guide +β”‚ β”‚ β”œβ”€β”€ security.js # Security policy +β”‚ β”‚ └── sigs.js # Special Interest Groups +β”‚ β”œβ”€β”€ utils.js # Shared utilities (used by all) β”‚ β”œβ”€β”€ repo-transforms.js # Repository-specific transformations β”‚ β”œβ”€β”€ component-configs.js # Component repository configurations -β”‚ β”œβ”€β”€ components-generator.js # Auto-generates component documentation -β”‚ β”œβ”€β”€ architecture-main.js # Main architecture documentation -β”‚ β”œβ”€β”€ contribute.js # Contributing guide -β”‚ β”œβ”€β”€ code-of-conduct.js # Code of conduct -β”‚ β”œβ”€β”€ security.js # Security policy -β”‚ β”œβ”€β”€ sigs.js # Special Interest Groups -β”‚ β”œβ”€β”€ guide-*.js # User guide sections β”‚ └── example-readme.js.template # Template for new sources └── README.md # This file ``` -## πŸ”§ Adding Components +### Directory Organization + +The remote-sources directory is organized to mirror the final documentation structure: + +- **`architecture/`** - Files that generate content for `docs/architecture/` +- **`guide/`** - Files that generate content for `docs/guide/` and `docs/guide/Installation/` +- **`community/`** - Files that generate content for `docs/community/` +- **Root level** - Shared utilities and configurations used across all directories -To add a new component to the auto-generation system: +## πŸ”§ Adding New Content + +### Adding Components + +Components are automatically generated from `component-configs.js`. To add a new component: 1. **Add to component-configs.js**: ```javascript @@ -99,6 +134,22 @@ To add a new component to the auto-generation system: 2. **Component will auto-appear** in the next build under `/docs/architecture/Components/` +### Adding Other Content + +For non-component content: + +1. **Choose the right directory**: + - `architecture/` for architecture documentation + - `guide/` for user guides and installation docs + - `community/` for community resources + +2. **Copy and customize template**: + ```bash + cp remote-content/remote-sources/example-readme.js.template remote-content/remote-sources/DIRECTORY/your-content.js + ``` + +3. **Update imports in remote-content.js** to include your new file + ## πŸ› Troubleshooting | Problem | Fix | @@ -107,10 +158,13 @@ To add a new component to the auto-generation system: | Build errors | Verify all `YOUR-...` placeholders are replaced | | Wrong sidebar order | Check `sidebarPosition` numbers | | Links broken | Use `contentTransform` to fix relative links or add to `repo-transforms.js` | -| Import errors | Ensure file is imported in `remote-content/remote-content.js` | +| Import errors | Ensure file is imported in `remote-content/remote-content.js` with correct path | | Component not showing | Check `component-configs.js` and ensure repository is public | | Source banner missing | Verify you're using `createContentWithSource()` from utils.js | | Banner at wrong location | Source banners now appear at bottom of pages automatically | +| Import path errors | Use `../` to reference utils from subdirectories (e.g., `../utils.js`) | +| File in wrong directory | Move to appropriate subdirectory: `architecture/`, `guide/`, or `community/` | +| Template not working | Ensure you're using the updated template with correct import paths | ## πŸ“ Content Source Banners diff --git a/remote-content/remote-sources/architecture-main.js b/remote-content/remote-sources/architecture/architecture-main.js similarity index 53% rename from remote-content/remote-sources/architecture-main.js rename to remote-content/remote-sources/architecture/architecture-main.js index 1806940..3a89acc 100644 --- a/remote-content/remote-sources/architecture-main.js +++ b/remote-content/remote-sources/architecture/architecture-main.js @@ -5,21 +5,26 @@ * and transforms it into docs/architecture/00_architecture.mdx */ -import { createContentWithSource } from './utils.js'; -import { getRepoTransform } from './repo-transforms.js'; +import { createContentWithSource, createStandardTransform } from '../utils.js'; +import { findRepoConfig, generateRepoUrls } from '../component-configs.js'; + +// Get repository configuration from centralized config +const repoConfig = findRepoConfig('llm-d'); +const { repoUrl, sourceBaseUrl } = generateRepoUrls(repoConfig); +const contentTransform = createStandardTransform('llm-d'); export default [ 'docusaurus-plugin-remote-content', { - // Basic configuration + // Basic configuration - all URLs generated from centralized config name: 'architecture-main', - sourceBaseUrl: 'https://raw.githubusercontent.com/llm-d/llm-d/dev/', + sourceBaseUrl, outDir: 'docs/architecture', documents: ['README.md'], // Plugin behavior - noRuntimeDownloads: false, // Download automatically when building - performCleanup: true, // Clean up files after build + noRuntimeDownloads: false, + performCleanup: true, // Transform the content for this specific document modifyContent(filename, content) { @@ -31,18 +36,10 @@ export default [ sidebarPosition: 0, filename: 'README.md', newFilename: 'architecture.mdx', - repoUrl: 'https://github.com/llm-d/llm-d', - branch: 'dev', + repoUrl, + branch: repoConfig.branch, content, - // Transform content to work in docusaurus context - contentTransform: (content) => { - // Get the appropriate repository transform - const transform = getRepoTransform('llm-d', 'llm-d'); - return transform(content, { - repoUrl: 'https://github.com/llm-d/llm-d', - branch: 'dev' - }); - } + contentTransform }); } return undefined; diff --git a/remote-content/remote-sources/components-generator.js b/remote-content/remote-sources/architecture/components-generator.js similarity index 91% rename from remote-content/remote-sources/components-generator.js rename to remote-content/remote-sources/architecture/components-generator.js index f6fe250..ff72ad1 100644 --- a/remote-content/remote-sources/components-generator.js +++ b/remote-content/remote-sources/architecture/components-generator.js @@ -5,9 +5,8 @@ * This creates a foundation for automatically syncing component documentation */ -import { createContentWithSource } from './utils.js'; -import { COMPONENT_CONFIGS } from './component-configs.js'; -import { getRepoTransform } from './repo-transforms.js'; +import { createContentWithSource, createStandardTransform } from '../utils.js'; +import { COMPONENT_CONFIGS, generateRepoUrls } from '../component-configs.js'; import fs from 'fs'; import path from 'path'; @@ -18,8 +17,7 @@ import path from 'path'; */ function generateComponentRemoteSource(config) { const { name, org, branch, description, sidebarPosition } = config; - const repoUrl = `https://github.com/${org}/${name}`; - const sourceBaseUrl = `https://raw.githubusercontent.com/${org}/${name}/${branch}/`; + const { repoUrl, sourceBaseUrl } = generateRepoUrls(config); return [ 'docusaurus-plugin-remote-content', @@ -54,11 +52,7 @@ function generateComponentRemoteSource(config) { branch, content, // Transform content to work in docusaurus context - contentTransform: (content) => { - // Get the appropriate repository transform - const transform = getRepoTransform(org, name); - return transform(content, { repoUrl, branch, org, name }); - } + contentTransform: createStandardTransform(name) }); } return undefined; @@ -127,7 +121,7 @@ This page is automatically updated from the latest component repository informat const sortedComponents = COMPONENT_CONFIGS.sort((a, b) => a.sidebarPosition - b.sidebarPosition); sortedComponents.forEach((component) => { - const repoUrl = `https://github.com/${component.org}/${component.name}`; + const { repoUrl } = generateRepoUrls(component); const cleanName = component.name.replace(/^llm-d-/, ''); const cleanTitle = cleanName.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1) diff --git a/remote-content/remote-sources/code-of-conduct.js b/remote-content/remote-sources/community/code-of-conduct.js similarity index 64% rename from remote-content/remote-sources/code-of-conduct.js rename to remote-content/remote-sources/community/code-of-conduct.js index 4c60020..b212b12 100644 --- a/remote-content/remote-sources/code-of-conduct.js +++ b/remote-content/remote-sources/community/code-of-conduct.js @@ -5,20 +5,25 @@ * and transforms it into docs/community/code-of-conduct.md */ -import { createContentWithSource } from './utils.js'; +import { createContentWithSource } from '../utils.js'; +import { findRepoConfig, generateRepoUrls } from '../component-configs.js'; + +// Get repository configuration from centralized config +const repoConfig = findRepoConfig('llm-d'); +const { repoUrl, sourceBaseUrl } = generateRepoUrls(repoConfig); export default [ 'docusaurus-plugin-remote-content', { - // Basic configuration + // Basic configuration - all URLs generated from centralized config name: 'code-of-conduct', - sourceBaseUrl: 'https://raw.githubusercontent.com/llm-d/llm-d/dev/', + sourceBaseUrl, outDir: 'docs/community', documents: ['CODE_OF_CONDUCT.md'], // Plugin behavior - noRuntimeDownloads: false, // Download automatically when building - performCleanup: true, // Clean up files after build + noRuntimeDownloads: false, + performCleanup: true, // Transform the content for this specific document modifyContent(filename, content) { @@ -30,8 +35,8 @@ export default [ sidebarPosition: 2, filename: 'CODE_OF_CONDUCT.md', newFilename: 'code-of-conduct.md', - repoUrl: 'https://github.com/llm-d/llm-d', - branch: 'dev', + repoUrl, + branch: repoConfig.branch, content }); } diff --git a/remote-content/remote-sources/contribute.js b/remote-content/remote-sources/community/contribute.js similarity index 68% rename from remote-content/remote-sources/contribute.js rename to remote-content/remote-sources/community/contribute.js index 8f6c571..36d25c2 100644 --- a/remote-content/remote-sources/contribute.js +++ b/remote-content/remote-sources/community/contribute.js @@ -5,20 +5,25 @@ * and transforms it into docs/community/contribute.md */ -import { createContentWithSource } from './utils.js'; +import { createContentWithSource } from '../utils.js'; +import { findRepoConfig, generateRepoUrls } from '../component-configs.js'; + +// Get repository configuration from centralized config +const repoConfig = findRepoConfig('llm-d'); +const { repoUrl, sourceBaseUrl } = generateRepoUrls(repoConfig); export default [ 'docusaurus-plugin-remote-content', { - // Basic configuration + // Basic configuration - all URLs generated from centralized config name: 'contribute-guide', - sourceBaseUrl: 'https://raw.githubusercontent.com/llm-d/llm-d/dev/', + sourceBaseUrl, outDir: 'docs/community', documents: ['CONTRIBUTING.md'], // Plugin behavior - noRuntimeDownloads: false, // Download automatically when building - performCleanup: true, // Clean up files after build + noRuntimeDownloads: false, + performCleanup: true, // Transform the content for this specific document modifyContent(filename, content) { @@ -30,8 +35,8 @@ export default [ sidebarPosition: 1, filename: 'CONTRIBUTING.md', newFilename: 'contribute.md', - repoUrl: 'https://github.com/llm-d/llm-d', - branch: 'dev', + repoUrl, + branch: repoConfig.branch, content, // Fix relative links in the content contentTransform: (content) => content diff --git a/remote-content/remote-sources/security.js b/remote-content/remote-sources/community/security.js similarity index 66% rename from remote-content/remote-sources/security.js rename to remote-content/remote-sources/community/security.js index 2f29110..b3b35b9 100644 --- a/remote-content/remote-sources/security.js +++ b/remote-content/remote-sources/community/security.js @@ -5,20 +5,25 @@ * and transforms it into docs/community/security.md */ -import { createContentWithSource } from './utils.js'; +import { createContentWithSource } from '../utils.js'; +import { findRepoConfig, generateRepoUrls } from '../component-configs.js'; + +// Get repository configuration from centralized config +const repoConfig = findRepoConfig('llm-d'); +const { repoUrl, sourceBaseUrl } = generateRepoUrls(repoConfig); export default [ 'docusaurus-plugin-remote-content', { - // Basic configuration + // Basic configuration - all URLs generated from centralized config name: 'security-policy', - sourceBaseUrl: 'https://raw.githubusercontent.com/llm-d/llm-d/dev/', + sourceBaseUrl, outDir: 'docs/community', documents: ['SECURITY.md'], // Plugin behavior - noRuntimeDownloads: false, // Download automatically when building - performCleanup: true, // Clean up files after build + noRuntimeDownloads: false, + performCleanup: true, // Transform the content for this specific document modifyContent(filename, content) { @@ -30,8 +35,8 @@ export default [ sidebarPosition: 3, filename: 'SECURITY.md', newFilename: 'security.md', - repoUrl: 'https://github.com/llm-d/llm-d', - branch: 'dev', + repoUrl, + branch: repoConfig.branch, content, // No additional content transformations needed for SECURITY.md contentTransform: (content) => content diff --git a/remote-content/remote-sources/sigs.js b/remote-content/remote-sources/community/sigs.js similarity index 54% rename from remote-content/remote-sources/sigs.js rename to remote-content/remote-sources/community/sigs.js index 44a5649..605571f 100644 --- a/remote-content/remote-sources/sigs.js +++ b/remote-content/remote-sources/community/sigs.js @@ -5,21 +5,26 @@ * and transforms it into docs/community/sigs.md */ -import { createContentWithSource } from './utils.js'; -import { getRepoTransform } from './repo-transforms.js'; +import { createContentWithSource, createStandardTransform } from '../utils.js'; +import { findRepoConfig, generateRepoUrls } from '../component-configs.js'; + +// Get repository configuration from centralized config +const repoConfig = findRepoConfig('llm-d'); +const { repoUrl, sourceBaseUrl } = generateRepoUrls(repoConfig); +const contentTransform = createStandardTransform('llm-d'); export default [ 'docusaurus-plugin-remote-content', { - // Basic configuration + // Basic configuration - all URLs generated from centralized config name: 'sigs-guide', - sourceBaseUrl: 'https://raw.githubusercontent.com/llm-d/llm-d/dev/', + sourceBaseUrl, outDir: 'docs/community', documents: ['SIGS.md'], // Plugin behavior - noRuntimeDownloads: false, // Download automatically when building - performCleanup: true, // Clean up files after build + noRuntimeDownloads: false, + performCleanup: true, // Transform the content for this specific document modifyContent(filename, content) { @@ -31,17 +36,10 @@ export default [ sidebarPosition: 2, filename: 'SIGS.md', newFilename: 'sigs.md', - repoUrl: 'https://github.com/llm-d/llm-d', - branch: 'dev', + repoUrl, + branch: repoConfig.branch, content, - // Transform content using repository-specific logic - contentTransform: (content) => { - const transform = getRepoTransform('llm-d', 'llm-d'); - return transform(content, { - repoUrl: 'https://github.com/llm-d/llm-d', - branch: 'dev' - }); - } + contentTransform }); } return undefined; diff --git a/remote-content/remote-sources/component-configs.js b/remote-content/remote-sources/component-configs.js index 8e7af73..1c87b1c 100644 --- a/remote-content/remote-sources/component-configs.js +++ b/remote-content/remote-sources/component-configs.js @@ -6,6 +6,53 @@ * consistency across different generators. */ +/** + * Common repository configurations for remote content sources + * These are frequently used repos that don't fit the component pattern + */ +export const COMMON_REPO_CONFIGS = { + 'llm-d-main': { + name: 'llm-d', + org: 'llm-d', + branch: 'dev', + description: 'Main llm-d repository with core architecture and documentation' + }, + 'llm-d-infra': { + name: 'llm-d-infra', + org: 'llm-d-incubation', + branch: 'main', + description: 'Examples, Helm charts, and release assets for llm-d infrastructure' + } +}; + +/** + * Find repository configuration by name from either components or common repos + * @param {string} repoName - Repository name to find + * @returns {Object|null} Repository configuration object + */ +export function findRepoConfig(repoName) { + // Check components first + const componentConfig = COMPONENT_CONFIGS.find(config => config.name === repoName); + if (componentConfig) return componentConfig; + + // Check common repos + const commonConfig = Object.values(COMMON_REPO_CONFIGS).find(config => config.name === repoName); + return commonConfig || null; +} + +/** + * Generate repository URLs from configuration + * @param {Object} repoConfig - Repository configuration + * @returns {Object} Object with repoUrl and sourceBaseUrl + */ +export function generateRepoUrls(repoConfig) { + const { org, name, branch } = repoConfig; + return { + repoUrl: `https://github.com/${org}/${name}`, + sourceBaseUrl: `https://raw.githubusercontent.com/${org}/${name}/${branch}/` + }; +} + export const COMPONENT_CONFIGS = [ { name: 'llm-d-inference-scheduler', diff --git a/remote-content/remote-sources/example-readme.js.template b/remote-content/remote-sources/example-readme.js.template index 87aa18d..411a4b8 100644 --- a/remote-content/remote-sources/example-readme.js.template +++ b/remote-content/remote-sources/example-readme.js.template @@ -1,41 +1,91 @@ /** - * Example: Project README Remote Content + * Example: Remote Content Template * - * This is an example of how to set up remote content for a README file. - * Copy this file, rename it (remove .template), and modify the values. + * This template shows how to create remote content sources in the new directory structure. + * Files should be placed in subdirectories based on their final documentation location: + * + * - architecture/ β†’ docs/architecture + * - guide/ β†’ docs/guide (and docs/guide/Installation) + * - community/ β†’ docs/community + * + * USAGE: + * 1. Copy this file to the appropriate subdirectory (architecture/, guide/, or community/) + * 2. Rename it (remove .template) + * 3. Update the import paths and configuration values */ -import { createContentWithSource } from './utils.js'; +// IMPORTANT: Update import paths based on your subdirectory location +// From architecture/, guide/, or community/ subdirectories, use: +import { createContentWithSource, createStandardTransform } from '../utils.js'; +import { findRepoConfig, generateRepoUrls } from '../component-configs.js'; + +// OPTION 1: Use centralized repo configuration (recommended) +const repoConfig = findRepoConfig('YOUR-REPO-NAME'); // Change: use repo name from component-configs.js +const { repoUrl, sourceBaseUrl } = generateRepoUrls(repoConfig); +const contentTransform = createStandardTransform('YOUR-REPO-NAME'); export default [ 'docusaurus-plugin-remote-content', { - // Basic configuration - name: 'project-overview', // Change: unique name for CLI commands - sourceBaseUrl: 'https://raw.githubusercontent.com/YOUR-ORG/YOUR-REPO/main/', // Change: your repo URL - outDir: 'docs/overview', // Change: where to put the files + // Basic configuration - URLs auto-generated from centralized config + name: 'your-content-name', // Change: unique name for CLI commands + sourceBaseUrl, // Generated from repo config + outDir: 'docs/YOUR-SECTION', // Change: docs/architecture, docs/guide, docs/community, etc. documents: ['README.md'], // Change: which files to download // Plugin behavior - noRuntimeDownloads: false, // false = auto-download, true = CLI only - performCleanup: true, // true = clean up after build + noRuntimeDownloads: false, // false = auto-download, true = CLI only + performCleanup: true, // true = clean up after build // Transform the content using utilities modifyContent(filename, content) { if (filename === 'README.md') { return createContentWithSource({ - title: 'Project Overview', // Change: your page title - description: 'Overview of the project', // Change: your description - sidebarLabel: 'Overview', // Change: sidebar label + title: 'Your Content Title', // Change: your page title + description: 'Description of content', // Change: your description + sidebarLabel: 'Sidebar Label', // Change: sidebar label sidebarPosition: 1, // Change: sidebar position filename: 'README.md', // Original filename - newFilename: 'overview.md', // Change: new filename - repoUrl: 'https://github.com/YOUR-ORG/YOUR-REPO', // Change: your repo URL - branch: 'main', // Change: your branch - content + newFilename: 'your-file.md', // Change: new filename + repoUrl, // Generated from repo config + branch: repoConfig.branch, // Generated from repo config + content, + contentTransform // Apply standard transforms }); } return undefined; }, }, -]; \ No newline at end of file +]; + +/* + * OPTION 2: Manual configuration (if not using centralized config) + * + * export default [ + * 'docusaurus-plugin-remote-content', + * { + * name: 'your-content-name', + * sourceBaseUrl: 'https://raw.githubusercontent.com/YOUR-ORG/YOUR-REPO/main/', + * outDir: 'docs/YOUR-SECTION', + * documents: ['README.md'], + * noRuntimeDownloads: false, + * performCleanup: true, + * modifyContent(filename, content) { + * if (filename === 'README.md') { + * return createContentWithSource({ + * title: 'Your Content Title', + * description: 'Description of content', + * sidebarLabel: 'Sidebar Label', + * sidebarPosition: 1, + * filename: 'README.md', + * newFilename: 'your-file.md', + * repoUrl: 'https://github.com/YOUR-ORG/YOUR-REPO', + * branch: 'main', + * content + * }); + * } + * return undefined; + * }, + * }, + * ]; + */ \ No newline at end of file diff --git a/remote-content/remote-sources/guide-examples.js b/remote-content/remote-sources/guide/guide-examples.js similarity index 66% rename from remote-content/remote-sources/guide-examples.js rename to remote-content/remote-sources/guide/guide-examples.js index 66d9280..1812a60 100644 --- a/remote-content/remote-sources/guide-examples.js +++ b/remote-content/remote-sources/guide/guide-examples.js @@ -5,21 +5,26 @@ * and transforms it into docs/guide/guide.md (landing page) */ -import { createContentWithSource } from './utils.js'; -import { getRepoTransform } from './repo-transforms.js'; +import { createContentWithSource, createStandardTransform } from '../utils.js'; +import { findRepoConfig, generateRepoUrls } from '../component-configs.js'; + +// Get repository configuration from centralized config +const repoConfig = findRepoConfig('llm-d-infra'); +const { repoUrl, sourceBaseUrl } = generateRepoUrls(repoConfig); +const standardTransform = createStandardTransform('llm-d-infra'); export default [ 'docusaurus-plugin-remote-content', { - // Basic configuration + // Basic configuration - all URLs generated from centralized config name: 'guide-examples', - sourceBaseUrl: 'https://raw.githubusercontent.com/llm-d-incubation/llm-d-infra/main/', + sourceBaseUrl, outDir: 'docs/guide', documents: ['quickstart/examples/README.md'], // Plugin behavior - noRuntimeDownloads: false, // Download automatically when building - performCleanup: true, // Clean up files after build + noRuntimeDownloads: false, + performCleanup: true, // Transform the content for this specific document modifyContent(filename, content) { @@ -31,10 +36,10 @@ export default [ sidebarPosition: 1, filename: 'quickstart/examples/README.md', newFilename: 'guide.md', - repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', - branch: 'main', + repoUrl, + branch: repoConfig.branch, content, - // Transform content using repository-specific logic + // Transform content with custom logic plus standard transforms contentTransform: (content) => { // Add what is llm-d section before the main content const withIntro = content.replace(/^# /, `**What is llm-d?** @@ -46,13 +51,7 @@ llm-d is an open source project providing distributed inferencing for GenAI runt # `); // Apply repository-specific transforms (all links go to GitHub) - const transform = getRepoTransform('llm-d-incubation', 'llm-d-infra'); - return transform(withIntro, { - repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', - branch: 'main', - org: 'llm-d-incubation', - name: 'llm-d-infra' - }); + return standardTransform(withIntro); } }); } diff --git a/remote-content/remote-sources/guide-inference-scheduling.js b/remote-content/remote-sources/guide/guide-inference-scheduling.js similarity index 54% rename from remote-content/remote-sources/guide-inference-scheduling.js rename to remote-content/remote-sources/guide/guide-inference-scheduling.js index 05552a6..412047e 100644 --- a/remote-content/remote-sources/guide-inference-scheduling.js +++ b/remote-content/remote-sources/guide/guide-inference-scheduling.js @@ -5,22 +5,27 @@ * and transforms it into docs/guide/Installation/inference-scheduling.md */ -import { createContentWithSource } from './utils.js'; -import { getRepoTransform } from './repo-transforms.js'; +import { createContentWithSource, createStandardTransform } from '../utils.js'; +import { findRepoConfig, generateRepoUrls } from '../component-configs.js'; + +// Get repository configuration from centralized config +const repoConfig = findRepoConfig('llm-d-infra'); +const { repoUrl, sourceBaseUrl } = generateRepoUrls(repoConfig); +const contentTransform = createStandardTransform('llm-d-infra'); export default [ 'docusaurus-plugin-remote-content', { - // Basic configuration + // Basic configuration - all URLs generated from centralized config name: 'guide-inference-scheduling', - sourceBaseUrl: 'https://raw.githubusercontent.com/llm-d-incubation/llm-d-infra/main/', + sourceBaseUrl, outDir: 'docs/guide/Installation', documents: ['quickstart/examples/inference-scheduling/README.md'], // Plugin behavior - noRuntimeDownloads: false, // Download automatically when building - performCleanup: true, // Clean up files after build - + noRuntimeDownloads: false, + performCleanup: true, + // Transform the content for this specific document modifyContent(filename, content) { if (filename === 'quickstart/examples/inference-scheduling/README.md') { @@ -31,19 +36,10 @@ export default [ sidebarPosition: 2, filename: 'quickstart/examples/inference-scheduling/README.md', newFilename: 'inference-scheduling.md', - repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', - branch: 'main', + repoUrl, + branch: repoConfig.branch, content, - // Transform content using repository-specific logic - contentTransform: (content) => { - const transform = getRepoTransform('llm-d-incubation', 'llm-d-infra'); - return transform(content, { - repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', - branch: 'main', - org: 'llm-d-incubation', - name: 'llm-d-infra' - }); - } + contentTransform }); } return undefined; diff --git a/remote-content/remote-sources/guide-pd-disaggregation.js b/remote-content/remote-sources/guide/guide-pd-disaggregation.js similarity index 55% rename from remote-content/remote-sources/guide-pd-disaggregation.js rename to remote-content/remote-sources/guide/guide-pd-disaggregation.js index 118ea44..aa389aa 100644 --- a/remote-content/remote-sources/guide-pd-disaggregation.js +++ b/remote-content/remote-sources/guide/guide-pd-disaggregation.js @@ -5,21 +5,26 @@ * and transforms it into docs/guide/Installation/pd-disaggregation.md */ -import { createContentWithSource } from './utils.js'; -import { getRepoTransform } from './repo-transforms.js'; +import { createContentWithSource, createStandardTransform } from '../utils.js'; +import { findRepoConfig, generateRepoUrls } from '../component-configs.js'; + +// Get repository configuration from centralized config +const repoConfig = findRepoConfig('llm-d-infra'); +const { repoUrl, sourceBaseUrl } = generateRepoUrls(repoConfig); +const contentTransform = createStandardTransform('llm-d-infra'); export default [ 'docusaurus-plugin-remote-content', { - // Basic configuration + // Basic configuration - all URLs generated from centralized config name: 'guide-pd-disaggregation', - sourceBaseUrl: 'https://raw.githubusercontent.com/llm-d-incubation/llm-d-infra/main/', + sourceBaseUrl, outDir: 'docs/guide/Installation', documents: ['quickstart/examples/pd-disaggregation/README.md'], // Plugin behavior - noRuntimeDownloads: false, // Download automatically when building - performCleanup: true, // Clean up files after build + noRuntimeDownloads: false, + performCleanup: true, // Transform the content for this specific document modifyContent(filename, content) { @@ -31,19 +36,10 @@ export default [ sidebarPosition: 3, filename: 'quickstart/examples/pd-disaggregation/README.md', newFilename: 'pd-disaggregation.md', - repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', - branch: 'main', + repoUrl, + branch: repoConfig.branch, content, - // Transform content using repository-specific logic - contentTransform: (content) => { - const transform = getRepoTransform('llm-d-incubation', 'llm-d-infra'); - return transform(content, { - repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', - branch: 'main', - org: 'llm-d-incubation', - name: 'llm-d-infra' - }); - } + contentTransform }); } return undefined; diff --git a/remote-content/remote-sources/guide-prerequisites.js b/remote-content/remote-sources/guide/guide-prerequisites.js similarity index 50% rename from remote-content/remote-sources/guide-prerequisites.js rename to remote-content/remote-sources/guide/guide-prerequisites.js index f95bbc2..110818a 100644 --- a/remote-content/remote-sources/guide-prerequisites.js +++ b/remote-content/remote-sources/guide/guide-prerequisites.js @@ -5,22 +5,27 @@ * and transforms it into docs/guide/Installation/prerequisites.md */ -import { createContentWithSource } from './utils.js'; -import { getRepoTransform } from './repo-transforms.js'; +import { createContentWithSource, createStandardTransform } from '../utils.js'; +import { findRepoConfig, generateRepoUrls } from '../component-configs.js'; + +// Get repository configuration from centralized config +const repoConfig = findRepoConfig('llm-d-infra'); +const { repoUrl, sourceBaseUrl } = generateRepoUrls(repoConfig); +const contentTransform = createStandardTransform('llm-d-infra'); export default [ 'docusaurus-plugin-remote-content', { - // Basic configuration + // Basic configuration - all URLs generated from centralized config name: 'guide-prerequisites', - sourceBaseUrl: 'https://raw.githubusercontent.com/llm-d-incubation/llm-d-infra/main/', + sourceBaseUrl, outDir: 'docs/guide/Installation', documents: ['quickstart/README.md'], // Plugin behavior - noRuntimeDownloads: false, // Download automatically when building - performCleanup: true, // Clean up files after build - + noRuntimeDownloads: false, + performCleanup: true, + // Transform the content for this specific document modifyContent(filename, content) { if (filename === 'quickstart/README.md') { @@ -31,19 +36,10 @@ export default [ sidebarPosition: 1, filename: 'quickstart/README.md', newFilename: 'prerequisites.md', - repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', - branch: 'main', + repoUrl, + branch: repoConfig.branch, content, - // Transform content using repository-specific logic - contentTransform: (content) => { - const transform = getRepoTransform('llm-d-incubation', 'llm-d-infra'); - return transform(content, { - repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', - branch: 'main', - org: 'llm-d-incubation', - name: 'llm-d-infra' - }); - } + contentTransform }); } return undefined; diff --git a/remote-content/remote-sources/guide-wide-ep-lws.js b/remote-content/remote-sources/guide/guide-wide-ep-lws.js similarity index 53% rename from remote-content/remote-sources/guide-wide-ep-lws.js rename to remote-content/remote-sources/guide/guide-wide-ep-lws.js index 047b9d1..71f18a5 100644 --- a/remote-content/remote-sources/guide-wide-ep-lws.js +++ b/remote-content/remote-sources/guide/guide-wide-ep-lws.js @@ -5,21 +5,26 @@ * and transforms it into docs/guide/Installation/wide-ep-lws.md */ -import { createContentWithSource } from './utils.js'; -import { getRepoTransform } from './repo-transforms.js'; +import { createContentWithSource, createStandardTransform } from '../utils.js'; +import { findRepoConfig, generateRepoUrls } from '../component-configs.js'; + +// Get repository configuration from centralized config +const repoConfig = findRepoConfig('llm-d-infra'); +const { repoUrl, sourceBaseUrl } = generateRepoUrls(repoConfig); +const contentTransform = createStandardTransform('llm-d-infra'); export default [ 'docusaurus-plugin-remote-content', { - // Basic configuration + // Basic configuration - all URLs generated from centralized config name: 'guide-wide-ep-lws', - sourceBaseUrl: 'https://raw.githubusercontent.com/llm-d-incubation/llm-d-infra/main/', + sourceBaseUrl, outDir: 'docs/guide/Installation', documents: ['quickstart/examples/wide-ep-lws/README.md'], // Plugin behavior - noRuntimeDownloads: false, // Download automatically when building - performCleanup: true, // Clean up files after build + noRuntimeDownloads: false, + performCleanup: true, // Transform the content for this specific document modifyContent(filename, content) { @@ -31,19 +36,10 @@ export default [ sidebarPosition: 4, filename: 'quickstart/examples/wide-ep-lws/README.md', newFilename: 'wide-ep-lws.md', - repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', - branch: 'main', + repoUrl, + branch: repoConfig.branch, content, - // Transform content using repository-specific logic - contentTransform: (content) => { - const transform = getRepoTransform('llm-d-incubation', 'llm-d-infra'); - return transform(content, { - repoUrl: 'https://github.com/llm-d-incubation/llm-d-infra', - branch: 'main', - org: 'llm-d-incubation', - name: 'llm-d-infra' - }); - } + contentTransform }); } return undefined; diff --git a/remote-content/remote-sources/utils.js b/remote-content/remote-sources/utils.js index bce3b27..a274c93 100644 --- a/remote-content/remote-sources/utils.js +++ b/remote-content/remote-sources/utils.js @@ -4,6 +4,27 @@ * Helper functions to maintain consistency across remote content transformations */ +import { findRepoConfig, generateRepoUrls } from './component-configs.js'; +import { getRepoTransform } from './repo-transforms.js'; + +/** + * Create a standardized content transform function using centralized repo configs + * @param {string} repoName - Repository name from COMPONENT_CONFIGS or COMMON_REPO_CONFIGS + * @returns {Function} Content transform function + */ +export function createStandardTransform(repoName) { + const repoConfig = findRepoConfig(repoName); + if (!repoConfig) { + throw new Error(`Repository configuration not found for: ${repoName}`); + } + + const { org, name, branch } = repoConfig; + const { repoUrl } = generateRepoUrls(repoConfig); + const transform = getRepoTransform(org, name); + + return (content) => transform(content, { repoUrl, branch, org, name }); +} + /** * Generate a source callout for remote content * @param {string} filename - The original filename From 36f968ebcf97a7cfc0bc62e6cca3947915654eb9 Mon Sep 17 00:00:00 2001 From: Pete Cheslock Date: Thu, 31 Jul 2025 12:12:06 -0400 Subject: [PATCH 04/11] Refactor remote content imports to improve organization Signed-off-by: Pete Cheslock --- remote-content/remote-content.js | 35 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/remote-content/remote-content.js b/remote-content/remote-content.js index 476a629..83da15b 100644 --- a/remote-content/remote-content.js +++ b/remote-content/remote-content.js @@ -1,21 +1,21 @@ // @ts-check -// Import individual remote content sources -import contributeSource from './remote-sources/contribute.js'; -import codeOfConductSource from './remote-sources/code-of-conduct.js'; -import securitySource from './remote-sources/security.js'; -import sigsSource from './remote-sources/sigs.js'; +// Import community remote content sources +import contributeSource from './remote-sources/community/contribute.js'; +import codeOfConductSource from './remote-sources/community/code-of-conduct.js'; +import securitySource from './remote-sources/community/security.js'; +import sigsSource from './remote-sources/community/sigs.js'; // Import architecture remote content sources -import architectureMainSource from './remote-sources/architecture-main.js'; -import componentSources from './remote-sources/components-generator.js'; +import architectureMainSource from './remote-sources/architecture/architecture-main.js'; +import componentSources from './remote-sources/architecture/components-generator.js'; // Import guide remote content sources -import guideExamplesSource from './remote-sources/guide-examples.js'; -import guidePrerequisitesSource from './remote-sources/guide-prerequisites.js'; -import guideInferenceSchedulingSource from './remote-sources/guide-inference-scheduling.js'; -import guidePdDisaggregationSource from './remote-sources/guide-pd-disaggregation.js'; -import guideWideEpLwsSource from './remote-sources/guide-wide-ep-lws.js'; +import guideExamplesSource from './remote-sources/guide/guide-examples.js'; +import guidePrerequisitesSource from './remote-sources/guide/guide-prerequisites.js'; +import guideInferenceSchedulingSource from './remote-sources/guide/guide-inference-scheduling.js'; +import guidePdDisaggregationSource from './remote-sources/guide/guide-pd-disaggregation.js'; +import guideWideEpLwsSource from './remote-sources/guide/guide-wide-ep-lws.js'; /** * Remote Content Plugin System @@ -24,8 +24,8 @@ import guideWideEpLwsSource from './remote-sources/guide-wide-ep-lws.js'; * It only manages remote content sources and can scale independently. * * To add new remote content: - * 1. Create a new file in remote-sources/ - * 2. Import it below + * 1. Create a new file in remote-sources/DIRECTORY/ (architecture/, guide/, or community/) + * 2. Import it below in the appropriate section * 3. Add it to the remoteContentPlugins array * * Users can manage their own plugins separately in docusaurus.config.js @@ -36,23 +36,24 @@ import guideWideEpLwsSource from './remote-sources/guide-wide-ep-lws.js'; * Add new remote sources here as you create them */ const remoteContentPlugins = [ + // Community remote content sources (docs/community/) contributeSource, codeOfConductSource, securitySource, sigsSource, - // Architecture remote content sources + // Architecture remote content sources (docs/architecture/) architectureMainSource, ...componentSources, // Spread all dynamically generated component sources - // Guide remote content sources + // Guide remote content sources (docs/guide/) guideExamplesSource, guidePrerequisitesSource, guideInferenceSchedulingSource, guidePdDisaggregationSource, guideWideEpLwsSource, - // Add more remote sources here + // Add more remote sources here in the appropriate section above ]; export default remoteContentPlugins; \ No newline at end of file From 814f50bc77dbb0aee1fa02050b870ffffd09fff7 Mon Sep 17 00:00:00 2001 From: Pete Cheslock Date: Thu, 31 Jul 2025 12:50:05 -0400 Subject: [PATCH 05/11] Refactor repository transformation functions for consistency - Renamed and unified transformation functions to ensure all relative links point back to the source repository. - Updated documentation comments for clarity and accuracy. - Deprecated previous transform functions in favor of a single, cohesive implementation. Signed-off-by: Pete Cheslock --- .../remote-sources/repo-transforms.js | 41 +++++++------------ 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/remote-content/remote-sources/repo-transforms.js b/remote-content/remote-sources/repo-transforms.js index 9b3c964..5aef56e 100644 --- a/remote-content/remote-sources/repo-transforms.js +++ b/remote-content/remote-sources/repo-transforms.js @@ -1,9 +1,8 @@ /** - * Repository-Specific Transformation System + * Repository Content Transformation System * - * Two repository types: - * 1. Main llm-d/llm-d repository (keeps docs/ links local) - * 2. Component repositories (all links point to source repo) + * Unified transformation that links all relative references back to the source repository. + * This ensures consistency across all content and prevents broken links. */ /** @@ -45,27 +44,10 @@ function fixImages(content, repoUrl, branch) { } /** - * Transform content from the main llm-d/llm-d repository - * Keeps docs/ links pointing to our local docs site + * Unified transform function for all repositories + * All relative links point back to the source repository on GitHub */ -export function transformMainRepo(content, { repoUrl, branch }) { - return fixImages(applyBasicMdxFixes(content), repoUrl, branch) - // Keep docs/ links local (inline format) - .replace(/\]\(docs\//g, '](/docs/architecture/') - .replace(/\]\(\.\/docs\//g, '](/docs/architecture/') - // Keep docs/ links local (reference format) - .replace(/^\[([^\]]+)\]:docs\//gm, `[$1]:/docs/architecture/`) - .replace(/^\[([^\]]+)\]:\.\/docs\//gm, `[$1]:/docs/architecture/`) - // All other relative links go to GitHub - .replace(/\]\((?!http|https|#|\/docs|\/blog|mailto:)([^)]+)\)/g, `](${repoUrl}/blob/${branch}/$1)`) - .replace(/^\[([^\]]+)\]:(?!http|https|#|mailto:|\/docs|\/blog)([^\s]+)/gm, `[$1]:${repoUrl}/blob/${branch}/$2`); -} - -/** - * Transform content from component repositories - * All relative links point back to the source repository - */ -export function transformComponentRepo(content, { repoUrl, branch }) { +export function transformRepo(content, { repoUrl, branch }) { return fixImages(applyBasicMdxFixes(content), repoUrl, branch) // All relative links go to source repository (inline format) .replace(/\]\((?!http|https|#|mailto:)([^)]+)\)/g, (match, path) => { @@ -80,8 +62,13 @@ export function transformComponentRepo(content, { repoUrl, branch }) { } /** - * Get the appropriate transform function for a repository + * Get the transform function for any repository + * Now returns the same unified transform for all repositories */ export function getRepoTransform(org, name) { - return (org === 'llm-d' && name === 'llm-d') ? transformMainRepo : transformComponentRepo; -} \ No newline at end of file + return transformRepo; +} + +// Backward compatibility exports (deprecated - use transformRepo instead) +export const transformMainRepo = transformRepo; +export const transformComponentRepo = transformRepo; \ No newline at end of file From d5d7967df87d3ce5e4d7ffae4639c38831cd6936 Mon Sep 17 00:00:00 2001 From: Pete Cheslock Date: Thu, 31 Jul 2025 12:59:38 -0400 Subject: [PATCH 06/11] Enhance README.md with detailed architecture and processing flow diagrams - Added a comprehensive overview of the Remote Content Plugin System, including file organization and processing flow. - Introduced mermaid diagrams to illustrate the system architecture and detailed content transformation steps. - Expanded documentation to clarify the auto-generation of component documentation and integration with Docusaurus. Signed-off-by: Pete Cheslock --- remote-content/README.md | 311 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 311 insertions(+) diff --git a/remote-content/README.md b/remote-content/README.md index c3e7ddc..11a55e7 100644 --- a/remote-content/README.md +++ b/remote-content/README.md @@ -61,6 +61,317 @@ npm start ## πŸ—οΈ Architecture +### System Overview + +```mermaid +flowchart TD + A["`**πŸ—οΈ Remote Content Plugin System** + Automatically syncs documentation from GitHub repositories`"] --> B["`**πŸ“ File Organization**`"] + + B --> B1["`**remote-content/remote-content.js** + 🎯 Main entry point - imports all sources`"] + B --> B2["`**remote-sources/[category]/[name].js** + βš™οΈ Individual content configurations`"] + B --> B3["`**component-configs.js** + πŸ“‹ Central repository definitions`"] + B --> B4["`**utils.js + repo-transforms.js** + πŸ”§ Content transformation utilities`"] + + B1 --> C["`**πŸ”„ Processing Flow**`"] + + C --> C1["`**1. Configuration Resolution** + πŸ“ Find repo details from component-configs.js + πŸ”— Generate GitHub URLs (raw & blob)`"] + + C1 --> C2["`**2. Content Fetching** + πŸ“₯ Download files from GitHub Raw API + πŸ“„ Usually README.md files`"] + + C2 --> C3["`**3. Content Transformation** + πŸ› οΈ Apply multiple transformation layers`"] + + C3 --> C3a["`**MDX Compatibility** + β€’
β†’
+ β€’ Fix unclosed HTML tags + β€’ Escape JSX expressions`"] + + C3a --> C3b["`**Link & Image Fixing** + β€’ ./docs/file.md β†’ github.com/org/repo/blob/main/docs/file.md + β€’ ./image.png β†’ github.com/org/repo/raw/main/image.png`"] + + C3b --> C3c["`**Frontmatter Addition** + β€’ title, description, sidebar config + β€’ Auto-generated from repo metadata`"] + + C3c --> C3d["`**Source Attribution** + β€’ 'Content Source' callout boxes + β€’ Edit links back to GitHub + β€’ Issue reporting links`"] + + C3d --> D["`**πŸ“„ Output Generation**`"] + + D --> D1["`**docs/architecture/** + β€’ architecture.mdx (main repo) + β€’ Components/[name].md (auto-generated)`"] + + D --> D2["`**docs/guide/** + β€’ Installation guides + β€’ Examples and tutorials`"] + + D --> D3["`**docs/community/** + β€’ Contributing guidelines + β€’ Code of conduct + β€’ Security policies`"] + + D1 --> E["`**🌐 Final Website** + Docusaurus renders all content with consistent styling and navigation`"] + D2 --> E + D3 --> E + + style A fill:#e3f2fd,stroke:#1976d2,stroke-width:3px + style B fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px + style C fill:#fff3e0,stroke:#f57c00,stroke-width:2px + style C3 fill:#e8f5e8,stroke:#388e3c,stroke-width:2px + style D fill:#fce4ec,stroke:#c2185b,stroke-width:2px + style E fill:#f1f8e9,stroke:#689f38,stroke-width:3px +``` + +### Detailed Processing Flow + +Here's how a single content source gets transformed from GitHub into your documentation: + +```mermaid +graph TD + A["`**GitHub Repository** + e.g., llm-d/llm-d-inference-scheduler`"] --> B["`**Source Configuration** + e.g., architecture/component.js`"] + + B --> C["`**Configuration Lookup** + component-configs.js`"] + + C --> D["`**Repository Details** + org: 'llm-d'
+ name: 'llm-d-inference-scheduler'
+ branch: 'main'
+ description: 'vLLM-optimized...'`"] + + D --> E["`**URL Generation** + generateRepoUrls()`"] + + E --> F["`**Generated URLs** + repoUrl: https://github.com/llm-d/llm-d-inference-scheduler
+ sourceBaseUrl: https://raw.githubusercontent.com/.../main/`"] + + F --> G["`**Content Fetch** + Download README.md from sourceBaseUrl`"] + + G --> H["`**Raw Content** + Original markdown from repository`"] + + H --> I["`**Transform Pipeline** + modifyContent() function`"] + + I --> I1["`**Step 1: MDX Fixes** + repo-transforms.js
+ β€’ Fix
tags β†’

+ β€’ Fix unclosed HTML tags
+ β€’ Escape JSX expressions`"] + + I1 --> I2["`**Step 2: Image Resolution** + repo-transforms.js
+ β€’ ![alt](./path) β†’ ![alt](github-raw-url)
+ β€’ β†’ `"] + + I2 --> I3["`**Step 3: Link Resolution** + repo-transforms.js
+ β€’ [text](./file.md) β†’ [text](github-blob-url)
+ β€’ [label]: ./path β†’ [label]: github-blob-url`"] + + I3 --> I4["`**Step 4: Content Wrapping** + utils.js - createContentWithSource()
+ β€’ Generate frontmatter
+ β€’ Add source attribution callout`"] + + I4 --> J["`**Transformed Content** + ---
+ title: Inference Scheduler
+ description: vLLM-optimized...
+ sidebar_label: Inference Scheduler
+ sidebar_position: 1
+ ---

+ [TRANSFORMED CONTENT]

+ :::info Content Source
+ This content is automatically synced...
+ :::`"] + + J --> K["`**File Output** + docs/architecture/Components/inference-scheduler.md`"] + + K --> L["`**Docusaurus Processing** + Renders as website page`"] + + style A fill:#e3f2fd + style D fill:#f3e5f5 + style H fill:#fff3e0 + style I1 fill:#e8f5e8 + style I2 fill:#e8f5e8 + style I3 fill:#e8f5e8 + style I4 fill:#e8f5e8 + style J fill:#fce4ec + style K fill:#f1f8e9 + style L fill:#e1f5fe +``` + +### Technical Architecture + +```mermaid +graph TB + subgraph DOCUSAURUS["**Docusaurus Integration**"] + DC["`**docusaurus.config.js** + plugins: [...remoteContentPlugins]`"] + end + + subgraph MAIN["**Main Entry Point**"] + RC["`**remote-content.js** + β€’ Imports all source configs
+ β€’ Exports plugin array
+ β€’ Central orchestration`"] + end + + subgraph CONFIG["**Configuration Layer**"] + CC["`**component-configs.js** + β€’ COMPONENT_CONFIGS array
+ β€’ COMMON_REPO_CONFIGS
+ β€’ findRepoConfig()
+ β€’ generateRepoUrls()`"] + + RT["`**repo-transforms.js** + β€’ applyBasicMdxFixes()
+ β€’ fixImages()
+ β€’ transformRepo()
+ β€’ getRepoTransform()`"] + + UT["`**utils.js** + β€’ createStandardTransform()
+ β€’ createSourceCallout()
+ β€’ createContentWithSource()`"] + end + + subgraph SOURCES["**Content Source Configurations**"] + subgraph ARCH["**Architecture Sources**"] + AM["`**architecture-main.js** + Main repo README β†’ architecture.mdx`"] + CG["`**components-generator.js** + Auto-generates component docs`"] + end + + subgraph GUIDE["**Guide Sources**"] + GE["`**guide-examples.js** + Examples landing page`"] + GP["`**guide-prerequisites.js** + Installation prerequisites`"] + GI["`**guide-inference-scheduling.js** + Inference scheduling guide`"] + GW["`**guide-wide-ep-lws.js** + Wide endpoint guide`"] + GD["`**guide-pd-disaggregation.js** + PD disaggregation guide`"] + end + + subgraph COMM["**Community Sources**"] + CO["`**contribute.js** + Contributing guidelines`"] + CC2["`**code-of-conduct.js** + Code of conduct`"] + SE["`**security.js** + Security policy`"] + SI["`**sigs.js** + Special interest groups`"] + end + end + + subgraph OUTPUT["**Generated Documentation**"] + subgraph DOCS_ARCH["**docs/architecture/**"] + DA1["`**architecture.mdx** + Main architecture doc`"] + DA2["`**Components/** + Auto-generated component docs`"] + end + + subgraph DOCS_GUIDE["**docs/guide/**"] + DG1["`**Installation/** + Installation guides`"] + DG2["`**examples.md** + Examples page`"] + end + + subgraph DOCS_COMM["**docs/community/**"] + DC1["`**contribute.md** + Contributing guide`"] + DC2["`**code-of-conduct.md** + Code of conduct`"] + DC3["`**security.md** + Security policy`"] + DC4["`**sigs.md** + SIG information`"] + end + end + + %% Main connections + DC --> RC + RC --> AM + RC --> CG + RC --> GE + RC --> GP + RC --> GI + RC --> GW + RC --> GD + RC --> CO + RC --> CC2 + RC --> SE + RC --> SI + + %% Config dependencies + AM --> CC + AM --> UT + AM --> RT + CG --> CC + CG --> UT + CG --> RT + + %% Similar pattern for guides and community + GE --> CC + GE --> UT + GE --> RT + GP --> CC + GP --> UT + GP --> RT + + CO --> CC + CO --> UT + CO --> RT + + %% Output generation + AM --> DA1 + CG --> DA2 + GE --> DG2 + GP --> DG1 + GI --> DG1 + GW --> DG1 + GD --> DG1 + CO --> DC1 + CC2 --> DC2 + SE --> DC3 + SI --> DC4 + + %% Styling + style DOCUSAURUS fill:#e1f5fe,stroke:#01579b,stroke-width:2px + style MAIN fill:#f3e5f5,stroke:#4a148c,stroke-width:2px + style CONFIG fill:#fff3e0,stroke:#e65100,stroke-width:2px + style SOURCES fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px + style OUTPUT fill:#fce4ec,stroke:#880e4f,stroke-width:2px +``` + ### Component Auto-Generation The system automatically generates documentation for all components listed in `component-configs.js`. This includes: From 1dffcc060fc9f296be9a92e10e57ddd1e3c66d2d Mon Sep 17 00:00:00 2001 From: Pete Cheslock Date: Thu, 31 Jul 2025 13:03:58 -0400 Subject: [PATCH 07/11] Update README.md to fix mermaid escaping issues Signed-off-by: Pete Cheslock --- remote-content/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/remote-content/README.md b/remote-content/README.md index 11a55e7..2070134 100644 --- a/remote-content/README.md +++ b/remote-content/README.md @@ -70,7 +70,7 @@ flowchart TD B --> B1["`**remote-content/remote-content.js** 🎯 Main entry point - imports all sources`"] - B --> B2["`**remote-sources/[category]/[name].js** + B --> B2["`**remote-sources/[category]/[name].js** βš™οΈ Individual content configurations`"] B --> B3["`**component-configs.js** πŸ“‹ Central repository definitions`"] @@ -112,7 +112,7 @@ flowchart TD D --> D1["`**docs/architecture/** β€’ architecture.mdx (main repo) - β€’ Components/[name].md (auto-generated)`"] + β€’ Components/[name].md (auto-generated)`"] D --> D2["`**docs/guide/** β€’ Installation guides @@ -159,8 +159,8 @@ graph TD generateRepoUrls()`"] E --> F["`**Generated URLs** - repoUrl: https://github.com/llm-d/llm-d-inference-scheduler
- sourceBaseUrl: https://raw.githubusercontent.com/.../main/`"] + repoUrl: github.com/llm-d/llm-d-inference-scheduler
+ sourceBaseUrl: raw.githubusercontent.com/.../main/`"] F --> G["`**Content Fetch** Download README.md from sourceBaseUrl`"] @@ -179,13 +179,13 @@ graph TD I1 --> I2["`**Step 2: Image Resolution** repo-transforms.js
- β€’ ![alt](./path) β†’ ![alt](github-raw-url)
- β€’ β†’ `"] + β€’ ![alt](./path) β†’ ![alt](github-raw-url)
+ β€’ <img src='./path'> β†’ <img src='github-raw-url'>`"] I2 --> I3["`**Step 3: Link Resolution** repo-transforms.js
- β€’ [text](./file.md) β†’ [text](github-blob-url)
- β€’ [label]: ./path β†’ [label]: github-blob-url`"] + β€’ [text](./file.md) β†’ [text](github-blob-url)
+ β€’ [label]: ./path β†’ [label]: github-blob-url`"] I3 --> I4["`**Step 4: Content Wrapping** utils.js - createContentWithSource()
@@ -199,7 +199,7 @@ graph TD sidebar_label: Inference Scheduler
sidebar_position: 1
---

- [TRANSFORMED CONTENT]

+ [TRANSFORMED CONTENT]

:::info Content Source
This content is automatically synced...
:::`"] @@ -228,7 +228,7 @@ graph TD graph TB subgraph DOCUSAURUS["**Docusaurus Integration**"] DC["`**docusaurus.config.js** - plugins: [...remoteContentPlugins]`"] + plugins: [...remoteContentPlugins]`"] end subgraph MAIN["**Main Entry Point**"] From eac6305ebc82748e72a36addcd08bf09258583a9 Mon Sep 17 00:00:00 2001 From: Pete Cheslock Date: Thu, 31 Jul 2025 13:08:14 -0400 Subject: [PATCH 08/11] Update README.md to fix formatting issues Signed-off-by: Pete Cheslock --- remote-content/README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/remote-content/README.md b/remote-content/README.md index 2070134..08367ca 100644 --- a/remote-content/README.md +++ b/remote-content/README.md @@ -70,7 +70,7 @@ flowchart TD B --> B1["`**remote-content/remote-content.js** 🎯 Main entry point - imports all sources`"] - B --> B2["`**remote-sources/[category]/[name].js** + B --> B2["`**remote-sources/category/name.js** βš™οΈ Individual content configurations`"] B --> B3["`**component-configs.js** πŸ“‹ Central repository definitions`"] @@ -91,13 +91,13 @@ flowchart TD πŸ› οΈ Apply multiple transformation layers`"] C3 --> C3a["`**MDX Compatibility** - β€’
β†’
- β€’ Fix unclosed HTML tags + β€’ Fix HTML tag formatting + β€’ Close unclosed HTML tags β€’ Escape JSX expressions`"] C3a --> C3b["`**Link & Image Fixing** - β€’ ./docs/file.md β†’ github.com/org/repo/blob/main/docs/file.md - β€’ ./image.png β†’ github.com/org/repo/raw/main/image.png`"] + β€’ Convert relative links to GitHub URLs + β€’ Convert image paths to GitHub raw URLs`"] C3b --> C3c["`**Frontmatter Addition** β€’ title, description, sidebar config @@ -112,7 +112,7 @@ flowchart TD D --> D1["`**docs/architecture/** β€’ architecture.mdx (main repo) - β€’ Components/[name].md (auto-generated)`"] + β€’ Components/component-name.md (auto-generated)`"] D --> D2["`**docs/guide/** β€’ Installation guides @@ -173,19 +173,19 @@ graph TD I --> I1["`**Step 1: MDX Fixes** repo-transforms.js
- β€’ Fix
tags β†’

+ β€’ Fix HTML tag formatting
β€’ Fix unclosed HTML tags
β€’ Escape JSX expressions`"] I1 --> I2["`**Step 2: Image Resolution** repo-transforms.js
- β€’ ![alt](./path) β†’ ![alt](github-raw-url)
- β€’ <img src='./path'> β†’ <img src='github-raw-url'>`"] + β€’ Markdown images to GitHub raw URLs
+ β€’ HTML img tags to GitHub raw URLs`"] I2 --> I3["`**Step 3: Link Resolution** repo-transforms.js
- β€’ [text](./file.md) β†’ [text](github-blob-url)
- β€’ [label]: ./path β†’ [label]: github-blob-url`"] + β€’ Relative links to GitHub blob URLs
+ β€’ Reference links to GitHub blob URLs`"] I3 --> I4["`**Step 4: Content Wrapping** utils.js - createContentWithSource()
@@ -199,7 +199,7 @@ graph TD sidebar_label: Inference Scheduler
sidebar_position: 1
---

- [TRANSFORMED CONTENT]

+ TRANSFORMED CONTENT

:::info Content Source
This content is automatically synced...
:::`"] @@ -228,7 +228,7 @@ graph TD graph TB subgraph DOCUSAURUS["**Docusaurus Integration**"] DC["`**docusaurus.config.js** - plugins: [...remoteContentPlugins]`"] + plugins: ...remoteContentPlugins`"] end subgraph MAIN["**Main Entry Point**"] @@ -260,7 +260,7 @@ graph TB subgraph SOURCES["**Content Source Configurations**"] subgraph ARCH["**Architecture Sources**"] AM["`**architecture-main.js** - Main repo README β†’ architecture.mdx`"] + Main repo README to architecture.mdx`"] CG["`**components-generator.js** Auto-generates component docs`"] end From 81b3fdf7d46e3b20e94feeb3f4f426bc3ae00764 Mon Sep 17 00:00:00 2001 From: Pete Cheslock Date: Thu, 31 Jul 2025 16:22:11 -0400 Subject: [PATCH 09/11] Add guide-precise-prefix-cache-aware remote content source - Introduced a new remote content source for the precise prefix cache aware guide, enabling automatic fetching and transformation of the README.md from the llm-d-infra repository. - Updated remote-content.js to include the new source in the plugin system. Signed-off-by: Pete Cheslock --- remote-content/remote-content.js | 2 + .../guide/guide-precise-prefix-cache-aware.js | 48 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 remote-content/remote-sources/guide/guide-precise-prefix-cache-aware.js diff --git a/remote-content/remote-content.js b/remote-content/remote-content.js index 83da15b..0e60a67 100644 --- a/remote-content/remote-content.js +++ b/remote-content/remote-content.js @@ -16,6 +16,7 @@ import guidePrerequisitesSource from './remote-sources/guide/guide-prerequisites import guideInferenceSchedulingSource from './remote-sources/guide/guide-inference-scheduling.js'; import guidePdDisaggregationSource from './remote-sources/guide/guide-pd-disaggregation.js'; import guideWideEpLwsSource from './remote-sources/guide/guide-wide-ep-lws.js'; +import guidePrecisePrefixCacheAwareSource from './remote-sources/guide/guide-precise-prefix-cache-aware.js'; /** * Remote Content Plugin System @@ -52,6 +53,7 @@ const remoteContentPlugins = [ guideInferenceSchedulingSource, guidePdDisaggregationSource, guideWideEpLwsSource, + guidePrecisePrefixCacheAwareSource, // Add more remote sources here in the appropriate section above ]; diff --git a/remote-content/remote-sources/guide/guide-precise-prefix-cache-aware.js b/remote-content/remote-sources/guide/guide-precise-prefix-cache-aware.js new file mode 100644 index 0000000..3310313 --- /dev/null +++ b/remote-content/remote-sources/guide/guide-precise-prefix-cache-aware.js @@ -0,0 +1,48 @@ +/** + * Guide Precise Prefix Cache Aware Remote Content + * + * Downloads the precise-prefix-cache-aware README.md file from the llm-d-infra repository + * and transforms it into docs/guide/Installation/precise-prefix-cache-aware.md + */ + +import { createContentWithSource, createStandardTransform } from '../utils.js'; +import { findRepoConfig, generateRepoUrls } from '../component-configs.js'; + +// Get repository configuration from centralized config +const repoConfig = findRepoConfig('llm-d-infra'); +const { repoUrl, sourceBaseUrl } = generateRepoUrls(repoConfig); +const contentTransform = createStandardTransform('llm-d-infra'); + +export default [ + 'docusaurus-plugin-remote-content', + { + // Basic configuration - all URLs generated from centralized config + name: 'guide-precise-prefix-cache-aware', + sourceBaseUrl, + outDir: 'docs/guide/Installation', + documents: ['quickstart/examples/precise-prefix-cache-aware/README.md'], + + // Plugin behavior + noRuntimeDownloads: false, + performCleanup: true, + + // Transform the content for this specific document + modifyContent(filename, content) { + if (filename === 'quickstart/examples/precise-prefix-cache-aware/README.md') { + return createContentWithSource({ + title: 'Precise Prefix Cache Aware Example', + description: 'Example implementation of precise prefix cache awareness in llm-d', + sidebarLabel: 'Precise Prefix Cache Aware', + sidebarPosition: 5, + filename: 'quickstart/examples/precise-prefix-cache-aware/README.md', + newFilename: 'precise-prefix-cache-aware.md', + repoUrl, + branch: repoConfig.branch, + content, + contentTransform + }); + } + return undefined; + }, + }, +]; \ No newline at end of file From df687fab01cb320f080183e0a27e4670df665f30 Mon Sep 17 00:00:00 2001 From: Pete Cheslock Date: Thu, 31 Jul 2025 17:20:33 -0400 Subject: [PATCH 10/11] Update sync to capture source directory for relative links. - Updated the `fixImages` function to accept a `sourceDir` parameter, allowing for correct resolution of relative paths based on the source file's directory. - Modified the `transformRepo` function to pass the `sourcePath` to the image and link transformation functions, ensuring all relative links point accurately to the source repository. - Adjusted content transformation logic in the guide examples to accommodate the new `sourcePath` parameter. Signed-off-by: Pete Cheslock --- .../remote-sources/guide/guide-examples.js | 4 +-- .../remote-sources/repo-transforms.js | 25 +++++++++++++------ remote-content/remote-sources/utils.js | 4 +-- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/remote-content/remote-sources/guide/guide-examples.js b/remote-content/remote-sources/guide/guide-examples.js index 1812a60..d498385 100644 --- a/remote-content/remote-sources/guide/guide-examples.js +++ b/remote-content/remote-sources/guide/guide-examples.js @@ -40,7 +40,7 @@ export default [ branch: repoConfig.branch, content, // Transform content with custom logic plus standard transforms - contentTransform: (content) => { + contentTransform: (content, sourcePath) => { // Add what is llm-d section before the main content const withIntro = content.replace(/^# /, `**What is llm-d?** @@ -51,7 +51,7 @@ llm-d is an open source project providing distributed inferencing for GenAI runt # `); // Apply repository-specific transforms (all links go to GitHub) - return standardTransform(withIntro); + return standardTransform(withIntro, sourcePath); } }); } diff --git a/remote-content/remote-sources/repo-transforms.js b/remote-content/remote-sources/repo-transforms.js index 5aef56e..718d34f 100644 --- a/remote-content/remote-sources/repo-transforms.js +++ b/remote-content/remote-sources/repo-transforms.js @@ -31,15 +31,19 @@ function applyBasicMdxFixes(content) { /** * Fix all images to point to GitHub raw URLs */ -function fixImages(content, repoUrl, branch) { +function fixImages(content, repoUrl, branch, sourceDir = '') { return content .replace(/!\[([^\]]*)\]\((?!http)([^)]+)\)/g, (match, alt, path) => { const cleanPath = path.replace(/^\.\//, ''); - return `![${alt}](${repoUrl}/raw/${branch}/${cleanPath})`; + // Resolve relative path relative to the source file's directory + const fullPath = sourceDir ? `${sourceDir}/${cleanPath}` : cleanPath; + return `![${alt}](${repoUrl}/raw/${branch}/${fullPath})`; }) .replace(/]*?)src=["'](?!http)([^"']+)["']([^>]*?)>/g, (match, before, path, after) => { const cleanPath = path.replace(/^\.\//, ''); - return ``; + // Resolve relative path relative to the source file's directory + const fullPath = sourceDir ? `${sourceDir}/${cleanPath}` : cleanPath; + return ``; }); } @@ -47,17 +51,24 @@ function fixImages(content, repoUrl, branch) { * Unified transform function for all repositories * All relative links point back to the source repository on GitHub */ -export function transformRepo(content, { repoUrl, branch }) { - return fixImages(applyBasicMdxFixes(content), repoUrl, branch) +export function transformRepo(content, { repoUrl, branch, sourcePath = '' }) { + // Get the directory of the source file to resolve relative paths correctly + const sourceDir = sourcePath ? sourcePath.split('/').slice(0, -1).join('/') : ''; + + return fixImages(applyBasicMdxFixes(content), repoUrl, branch, sourceDir) // All relative links go to source repository (inline format) .replace(/\]\((?!http|https|#|mailto:)([^)]+)\)/g, (match, path) => { const cleanPath = path.replace(/^\]\(/, '').replace(/^\.\//, ''); - return `](${repoUrl}/blob/${branch}/${cleanPath})`; + // Resolve relative path relative to the source file's directory + const fullPath = sourceDir ? `${sourceDir}/${cleanPath}` : cleanPath; + return `](${repoUrl}/blob/${branch}/${fullPath})`; }) // All relative links go to source repository (reference format) .replace(/^\[([^\]]+)\]:(?!http|https|#|mailto:)([^\s]+)/gm, (match, label, path) => { const cleanPath = path.replace(/^\.\//, ''); - return `[${label}]:${repoUrl}/blob/${branch}/${cleanPath}`; + // Resolve relative path relative to the source file's directory + const fullPath = sourceDir ? `${sourceDir}/${cleanPath}` : cleanPath; + return `[${label}]:${repoUrl}/blob/${branch}/${fullPath}`; }); } diff --git a/remote-content/remote-sources/utils.js b/remote-content/remote-sources/utils.js index a274c93..8be063f 100644 --- a/remote-content/remote-sources/utils.js +++ b/remote-content/remote-sources/utils.js @@ -22,7 +22,7 @@ export function createStandardTransform(repoName) { const { repoUrl } = generateRepoUrls(repoConfig); const transform = getRepoTransform(org, name); - return (content) => transform(content, { repoUrl, branch, org, name }); + return (content, sourcePath) => transform(content, { repoUrl, branch, org, name, sourcePath }); } /** @@ -85,7 +85,7 @@ sidebar_position: ${sidebarPosition} const sourceCallout = createSourceCallout(filename, repoUrl, branch); // Apply any additional content transformations - const transformedContent = contentTransform ? contentTransform(content) : content; + const transformedContent = contentTransform ? contentTransform(content, filename) : content; return { filename: newFilename, From 5233f5b96805e504b10751fdd05912ab38c84523 Mon Sep 17 00:00:00 2001 From: Pete Cheslock Date: Thu, 31 Jul 2025 17:50:52 -0400 Subject: [PATCH 11/11] Reorder the way we render links to happen before adding more content Signed-off-by: Pete Cheslock --- remote-content/remote-sources/guide/guide-examples.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/remote-content/remote-sources/guide/guide-examples.js b/remote-content/remote-sources/guide/guide-examples.js index d498385..f009299 100644 --- a/remote-content/remote-sources/guide/guide-examples.js +++ b/remote-content/remote-sources/guide/guide-examples.js @@ -41,8 +41,12 @@ export default [ content, // Transform content with custom logic plus standard transforms contentTransform: (content, sourcePath) => { - // Add what is llm-d section before the main content - const withIntro = content.replace(/^# /, `**What is llm-d?** + // Apply repository-specific transforms first (converts repo-relative links to GitHub) + const transformedContent = standardTransform(content, sourcePath); + + // Then add what is llm-d section before the main content + // This way our site-relative links don't get converted to GitHub URLs + const withIntro = transformedContent.replace(/^# /, `**What is llm-d?** llm-d is an open source project providing distributed inferencing for GenAI runtimes on any Kubernetes cluster. Its highly performant, scalable architecture helps reduce costs through a spectrum of hardware efficiency improvements. The project prioritizes ease of deployment+use as well as SRE needs + day 2 operations associated with running large GPU clusters. @@ -50,8 +54,7 @@ llm-d is an open source project providing distributed inferencing for GenAI runt # `); - // Apply repository-specific transforms (all links go to GitHub) - return standardTransform(withIntro, sourcePath); + return withIntro; } }); }