Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions contributing/dev/utils/check_llms_txt_links.py
Original file line number Diff line number Diff line change
@@ -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())
40 changes: 20 additions & 20 deletions llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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/)