## Summary - Add `WEBMCP_ENABLED` setting and guarded `webmcp-tools.js` loader on public pages - Register navigation tools (`list_services`, `get_page_content`, `navigate_to_service`, `open_contact_with_subject`) and contact tool (`submit_contact_inquiry`) - Annotate contact form with declarative WebMCP attributes for Lighthouse form coverage - Extend `PUBLIC_PAGE_ENTRIES` with summaries shared by SEO and WebMCP tools - Add `docs/webmcp.md`, update `docs/agentic-browsing.md`, and regression tests Closes #9 ## Test plan - [x] `python manage.py test public.tests` — 20 tests pass - [ ] Set `WEBMCP_ENABLED=True`, enable Chrome experimental web platform features flag - [ ] Verify homepage HTML includes `webmcp-config` and `webmcp-tools.js` - [ ] Verify `/contact` form has `toolname="submit_contact_inquiry"` - [ ] Run Lighthouse agentic-browsing on `/` and `/contact` with experimental flag - [ ] Call `list_services` from WebMCP-capable Chrome on homepage - [ ] Call `submit_contact_inquiry` on `/contact` with `DEBUG=True` (reCAPTCHA bypass) Reviewed-on: #12
This commit was merged in pull request #12.
This commit is contained in:
+112
-14
@@ -5,21 +5,119 @@ from django.template.loader import render_to_string
|
||||
from django.urls import reverse
|
||||
|
||||
# Public marketing pages included in sitemap and llms.txt.
|
||||
# Tuple: (url_name, title, changefreq, priority, summary)
|
||||
PUBLIC_PAGE_ENTRIES = (
|
||||
("public_index", "Home", "weekly", "1.0"),
|
||||
("forward_deployed", "Forward-Deployed AI", "monthly", "0.9"),
|
||||
("bot", "AI Agents", "monthly", "0.9"),
|
||||
("ml_model", "ML Models", "monthly", "0.8"),
|
||||
("chat", "Secure AI Chat", "monthly", "0.8"),
|
||||
("ai_sensor", "AI Sensor Algorithms", "monthly", "0.7"),
|
||||
("ai_education", "AI Education", "monthly", "0.7"),
|
||||
("computers", "Computer Builds", "monthly", "0.7"),
|
||||
("file_hosting", "File Hosting", "monthly", "0.7"),
|
||||
("web_design", "Web Design and Hosting", "monthly", "0.8"),
|
||||
("contact", "Contact", "monthly", "0.9"),
|
||||
("terms_of_service", "Terms of Service and Privacy", "yearly", "0.3"),
|
||||
(
|
||||
"public_index",
|
||||
"Home",
|
||||
"weekly",
|
||||
"1.0",
|
||||
"Company homepage with an overview of AI ML Operations services.",
|
||||
),
|
||||
(
|
||||
"forward_deployed",
|
||||
"Forward-Deployed AI",
|
||||
"monthly",
|
||||
"0.9",
|
||||
"Embedded AI engineering — we work inside your environment to build production systems.",
|
||||
),
|
||||
(
|
||||
"bot",
|
||||
"AI Agents",
|
||||
"monthly",
|
||||
"0.9",
|
||||
"Custom AI agents and agentic workflows tailored to your operational bottlenecks.",
|
||||
),
|
||||
(
|
||||
"ml_model",
|
||||
"ML Models",
|
||||
"monthly",
|
||||
"0.8",
|
||||
"Machine learning model development, training, and deployment for production use.",
|
||||
),
|
||||
(
|
||||
"chat",
|
||||
"Secure AI Chat",
|
||||
"monthly",
|
||||
"0.8",
|
||||
"Private, hosted AI chat deployments with enterprise-grade security.",
|
||||
),
|
||||
(
|
||||
"ai_sensor",
|
||||
"AI Sensor Algorithms",
|
||||
"monthly",
|
||||
"0.7",
|
||||
"Computer vision and sensor-fusion algorithms for real-world sensing applications.",
|
||||
),
|
||||
(
|
||||
"ai_education",
|
||||
"AI Education",
|
||||
"monthly",
|
||||
"0.7",
|
||||
"Hands-on AI training and workshops for teams adopting agentic workflows.",
|
||||
),
|
||||
(
|
||||
"computers",
|
||||
"Computer Builds",
|
||||
"monthly",
|
||||
"0.7",
|
||||
"Custom workstation and server builds optimized for AI and ML workloads.",
|
||||
),
|
||||
(
|
||||
"file_hosting",
|
||||
"File Hosting",
|
||||
"monthly",
|
||||
"0.7",
|
||||
"Managed file hosting and storage for teams that need reliable data access.",
|
||||
),
|
||||
(
|
||||
"web_design",
|
||||
"Web Design and Hosting",
|
||||
"monthly",
|
||||
"0.8",
|
||||
"Web design, development, and managed hosting for business sites and apps.",
|
||||
),
|
||||
(
|
||||
"contact",
|
||||
"Contact",
|
||||
"monthly",
|
||||
"0.9",
|
||||
"Contact form to inquire about forward-deployed AI engineering services.",
|
||||
),
|
||||
(
|
||||
"terms_of_service",
|
||||
"Terms of Service and Privacy",
|
||||
"yearly",
|
||||
"0.3",
|
||||
"Terms of service and privacy policy for AI ML Operations, LLC.",
|
||||
),
|
||||
)
|
||||
|
||||
SERVICE_URL_NAMES = frozenset({
|
||||
"forward_deployed",
|
||||
"bot",
|
||||
"ml_model",
|
||||
"chat",
|
||||
"ai_sensor",
|
||||
"ai_education",
|
||||
"computers",
|
||||
"file_hosting",
|
||||
"web_design",
|
||||
})
|
||||
|
||||
|
||||
def get_service_entries():
|
||||
"""Return service page metadata for WebMCP navigation tools."""
|
||||
return [
|
||||
{
|
||||
"slug": url_name,
|
||||
"name": title,
|
||||
"summary": summary,
|
||||
}
|
||||
for url_name, title, _changefreq, _priority, summary in PUBLIC_PAGE_ENTRIES
|
||||
if url_name in SERVICE_URL_NAMES
|
||||
]
|
||||
|
||||
|
||||
def _absolute_url(request, url_name):
|
||||
return request.build_absolute_uri(reverse(url_name))
|
||||
@@ -41,7 +139,7 @@ def sitemap_xml(request):
|
||||
"changefreq": changefreq,
|
||||
"priority": priority,
|
||||
}
|
||||
for url_name, _title, changefreq, priority in PUBLIC_PAGE_ENTRIES
|
||||
for url_name, _title, changefreq, priority, _summary in PUBLIC_PAGE_ENTRIES
|
||||
]
|
||||
content = render_to_string("public/sitemap.xml", {"pages": pages})
|
||||
return HttpResponse(content, content_type="application/xml; charset=utf-8")
|
||||
@@ -53,7 +151,7 @@ def llms_txt(request):
|
||||
"title": title,
|
||||
"url": _absolute_url(request, url_name),
|
||||
}
|
||||
for url_name, title, _changefreq, _priority in PUBLIC_PAGE_ENTRIES
|
||||
for url_name, title, _changefreq, _priority, _summary in PUBLIC_PAGE_ENTRIES
|
||||
]
|
||||
content = render_to_string(
|
||||
"public/llms.txt",
|
||||
|
||||
Reference in New Issue
Block a user