From 28fd230ab4733249e4cc6acdb51fcc2c9381663b Mon Sep 17 00:00:00 2001 From: Haihan Jiang Date: Sun, 14 Jun 2026 02:35:46 -0700 Subject: [PATCH] Fix llms.txt documentation links --- .../dev/utils/check_llms_txt_links.py | 85 +++++++++++++++++++ llms.txt | 40 ++++----- 2 files changed, 105 insertions(+), 20 deletions(-) create mode 100755 contributing/dev/utils/check_llms_txt_links.py diff --git a/contributing/dev/utils/check_llms_txt_links.py b/contributing/dev/utils/check_llms_txt_links.py new file mode 100755 index 00000000000..f0a2a2897b5 --- /dev/null +++ b/contributing/dev/utils/check_llms_txt_links.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Check that URLs referenced from llms.txt resolve successfully.""" + +from __future__ import annotations + +import argparse +from pathlib import Path +import re +import sys +import urllib.error +import urllib.request + +URL_RE = re.compile(r"https?://[^\s)\]>]+") + + +def extract_urls(path: Path) -> list[str]: + """Returns sorted unique URLs from a markdown/text file.""" + urls = set(URL_RE.findall(path.read_text(encoding="utf-8"))) + return sorted(url for url in urls if ".git@" not in url) + + +def check_url(url: str, timeout: float) -> str | None: + request = urllib.request.Request( + url, + method="GET", + headers={"User-Agent": "adk-python-llms-link-checker"}, + ) + try: + with urllib.request.urlopen(request, timeout=timeout) as response: + if response.status == 200: + return None + return f"{response.status} {response.reason}" + except urllib.error.HTTPError as exc: + return f"{exc.code} {exc.reason}" + except urllib.error.URLError as exc: + return str(exc.reason) + + +def main() -> int: + parser = argparse.ArgumentParser( + description="Validate that every URL in llms.txt returns HTTP 200." + ) + parser.add_argument( + "path", + nargs="?", + default=Path("llms.txt"), + type=Path, + help="Path to llms.txt.", + ) + parser.add_argument("--timeout", default=20.0, type=float) + args = parser.parse_args() + + urls = extract_urls(args.path) + failures: list[tuple[str, str]] = [] + for url in urls: + failure = check_url(url, args.timeout) + if failure: + failures.append((url, failure)) + + if failures: + for url, failure in failures: + print(f"FAILED {failure}: {url}", file=sys.stderr) + print(f"FAILED: {len(failures)} broken URLs out of {len(urls)}") + return 1 + + print(f"OK: {len(urls)} URLs checked") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/llms.txt b/llms.txt index 9522b266e9d..86b9123c475 100644 --- a/llms.txt +++ b/llms.txt @@ -170,8 +170,8 @@ Happy Agent Building! - [Custom agents](https://github.com/google/adk-docs/blob/main/docs/agents/custom-agents.md) - [Agents](https://github.com/google/adk-docs/blob/main/docs/agents/index.md) - [LLM Agent](https://github.com/google/adk-docs/blob/main/docs/agents/llm-agents.md) -- [Using Different Models with ADK](https://github.com/google/adk-docs/blob/main/docs/agents/models.md) -- [Multi-Agent Systems in ADK](https://github.com/google/adk-docs/blob/main/docs/agents/multi-agents.md) +- [Using Different Models with ADK](https://github.com/google/adk-docs/blob/main/docs/agents/models/index.md) +- [Multi-Agent Systems in ADK](https://github.com/google/adk-docs/blob/main/docs/workflows/index.md) - [Workflow Agents](https://github.com/google/adk-docs/blob/main/docs/agents/workflow-agents/index.md) - [Loop agents](https://github.com/google/adk-docs/blob/main/docs/agents/workflow-agents/loop-agents.md) - [Parallel agents](https://github.com/google/adk-docs/blob/main/docs/agents/workflow-agents/parallel-agents.md) @@ -181,10 +181,10 @@ Happy Agent Building! - [Design Patterns and Best Practices for Callbacks](https://github.com/google/adk-docs/blob/main/docs/callbacks/design-patterns-and-best-practices.md) - [Callbacks: Observe, Customize, and Control Agent Behavior](https://github.com/google/adk-docs/blob/main/docs/callbacks/index.md) - [Types of Callbacks](https://github.com/google/adk-docs/blob/main/docs/callbacks/types-of-callbacks.md) -- [Community Resources](https://github.com/google/adk-docs/blob/main/docs/community.md) +- [Community Resources](https://github.com/google/adk-docs/blob/main/docs/community/index.md) - [Context](https://github.com/google/adk-docs/blob/main/docs/context/index.md) -- [1. [`google/adk-python`](https://github.com/google/adk-python)](https://github.com/google/adk-docs/blob/main/docs/contributing-guide.md) -- [Deploy to Vertex AI Agent Engine](https://github.com/google/adk-docs/blob/main/docs/deploy/agent-engine.md) +- [Contribution guide](https://github.com/google/adk-docs/blob/main/docs/community/contributing-guide.md) +- [Deploy to Vertex AI Agent Engine](https://github.com/google/adk-docs/blob/main/docs/deploy/agent-runtime/index.md) - [Deploy to Cloud Run](https://github.com/google/adk-docs/blob/main/docs/deploy/cloud-run.md) - [Deploy to GKE](https://github.com/google/adk-docs/blob/main/docs/deploy/gke.md) - [Deploying Your Agent](https://github.com/google/adk-docs/blob/main/docs/deploy/index.md) @@ -193,36 +193,36 @@ Happy Agent Building! - [Agent Development Kit (ADK)](https://github.com/google/adk-docs/blob/main/docs/get-started/about.md) - [Get Started](https://github.com/google/adk-docs/blob/main/docs/get-started/index.md) - [Installing ADK](https://github.com/google/adk-docs/blob/main/docs/get-started/installation.md) -- [Quickstart](https://github.com/google/adk-docs/blob/main/docs/get-started/quickstart.md) +- [Quickstart](https://github.com/google/adk-docs/blob/main/docs/get-started/python.md) - [Streaming Quickstarts](https://github.com/google/adk-docs/blob/main/docs/get-started/streaming/index.md) - [Quickstart (Streaming / Java) {#adk-streaming-quickstart-java}](https://github.com/google/adk-docs/blob/main/docs/get-started/streaming/quickstart-streaming-java.md) - [Quickstart (Streaming / Python) {#adk-streaming-quickstart}](https://github.com/google/adk-docs/blob/main/docs/get-started/streaming/quickstart-streaming.md) -- [Testing your Agents](https://github.com/google/adk-docs/blob/main/docs/get-started/testing.md) +- [Testing your Agents](https://github.com/google/adk-docs/blob/main/docs/evaluate/index.md) - [What is Agent Development Kit?](https://github.com/google/adk-docs/blob/main/docs/index.md) - [Model Context Protocol (MCP)](https://github.com/google/adk-docs/blob/main/docs/mcp/index.md) -- [Agent Observability with Arize AX](https://github.com/google/adk-docs/blob/main/docs/observability/arize-ax.md) -- [Agent Observability with Phoenix](https://github.com/google/adk-docs/blob/main/docs/observability/phoenix.md) +- [Agent Observability with Arize AX](https://github.com/google/adk-docs/blob/main/docs/integrations/arize-ax.md) +- [Agent Observability with Phoenix](https://github.com/google/adk-docs/blob/main/docs/integrations/phoenix.md) - [Runtime](https://github.com/google/adk-docs/blob/main/docs/runtime/index.md) - [Runtime Configuration](https://github.com/google/adk-docs/blob/main/docs/runtime/runconfig.md) - [Safety & Security for AI Agents](https://github.com/google/adk-docs/blob/main/docs/safety/index.md) - [Introduction to Conversational Context: Session, State, and Memory](https://github.com/google/adk-docs/blob/main/docs/sessions/index.md) - [Memory: Long-Term Knowledge with `MemoryService`](https://github.com/google/adk-docs/blob/main/docs/sessions/memory.md) -- [Session: Tracking Individual Conversations](https://github.com/google/adk-docs/blob/main/docs/sessions/session.md) +- [Session: Tracking Individual Conversations](https://github.com/google/adk-docs/blob/main/docs/sessions/session/index.md) - [State: The Session's Scratchpad](https://github.com/google/adk-docs/blob/main/docs/sessions/state.md) - [Configurating streaming behaviour](https://github.com/google/adk-docs/blob/main/docs/streaming/configuration.md) -- [Custom Audio Streaming app (WebSocket) {#custom-streaming-websocket}](https://github.com/google/adk-docs/blob/main/docs/streaming/custom-streaming-ws.md) -- [Custom Audio Streaming app (SSE) {#custom-streaming}](https://github.com/google/adk-docs/blob/main/docs/streaming/custom-streaming.md) +- [Custom Audio Streaming app (WebSocket) {#custom-streaming-websocket}](https://github.com/google/adk-docs/blob/main/docs/streaming/index.md) +- [Custom Audio Streaming app (SSE) {#custom-streaming}](https://github.com/google/adk-docs/blob/main/docs/streaming/index.md) - [ADK Bidi-streaming development guide: Part 1 - Introduction](https://github.com/google/adk-docs/blob/main/docs/streaming/dev-guide/part1.md) - [Bidi-streaming(live) in ADK](https://github.com/google/adk-docs/blob/main/docs/streaming/index.md) - [Streaming Tools](https://github.com/google/adk-docs/blob/main/docs/streaming/streaming-tools.md) -- [Authenticating with Tools](https://github.com/google/adk-docs/blob/main/docs/tools/authentication.md) -- [Built-in tools](https://github.com/google/adk-docs/blob/main/docs/tools/built-in-tools.md) -- [Function tools](https://github.com/google/adk-docs/blob/main/docs/tools/function-tools.md) -- [Google Cloud Tools](https://github.com/google/adk-docs/blob/main/docs/tools/google-cloud-tools.md) -- [Tools](https://github.com/google/adk-docs/blob/main/docs/tools/index.md) -- [Model Context Protocol Tools](https://github.com/google/adk-docs/blob/main/docs/tools/mcp-tools.md) -- [OpenAPI Integration](https://github.com/google/adk-docs/blob/main/docs/tools/openapi-tools.md) -- [Third Party Tools](https://github.com/google/adk-docs/blob/main/docs/tools/third-party-tools.md) +- [Authenticating with Tools](https://github.com/google/adk-docs/blob/main/docs/tools-custom/authentication.md) +- [Built-in tools](https://github.com/google/adk-docs/blob/main/docs/integrations/index.md) +- [Function tools](https://github.com/google/adk-docs/blob/main/docs/tools-custom/function-tools.md) +- [Google Cloud Tools](https://github.com/google/adk-docs/blob/main/docs/integrations/index.md) +- [Tools](https://github.com/google/adk-docs/blob/main/docs/tools-custom/index.md) +- [Model Context Protocol Tools](https://github.com/google/adk-docs/blob/main/docs/tools-custom/mcp-tools.md) +- [OpenAPI Integration](https://github.com/google/adk-docs/blob/main/docs/tools-custom/openapi-tools.md) +- [Third Party Tools](https://github.com/google/adk-docs/blob/main/docs/integrations/index.md) - [Build Your First Intelligent Agent Team: A Progressive Weather Bot with ADK](https://github.com/google/adk-docs/blob/main/docs/tutorials/agent-team.md) - [ADK Tutorials!](https://github.com/google/adk-docs/blob/main/docs/tutorials/index.md) - [Python API Reference](https://github.com/google/adk-docs/blob/main/docs/api-reference/python/)