CI / test (push) Failing after 6m43s
docs/llmgw-intro.pdf is a 21-slide presentation: what llmgw adds on premise, screens from a running cluster, and how it compares with LiteLLM, Kong AI Gateway, Agent Router, llm-d, NVIDIA Dynamo and vLLM production-stack from their own documentation. The /about page and the published site link to it in the repository, so the binary does not carry it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
102 lines
3.3 KiB
Go
102 lines
3.3 KiB
Go
package web
|
|
|
|
import (
|
|
"embed"
|
|
"html/template"
|
|
"io"
|
|
"net/http"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// The page about llmgw itself: what it is, how to install it, where to get
|
|
// it. It is the project's website, carried by every gateway so an operator
|
|
// has it where they already are, and served without a key like the landing
|
|
// page — it says nothing about this installation, only about the software.
|
|
//
|
|
// The same template renders the published website (Site), which differs in
|
|
// three ways: fonts from Google rather than from this binary, no link back to
|
|
// a gateway, and features on main marked as coming in the next release.
|
|
|
|
// proxyConfigs are the reverse proxy configurations the page shows. They are
|
|
// copies of deploy/proxy, which the release attaches; embed cannot reach
|
|
// outside this package, and TestAboutProxyConfigsMatchDeploy keeps the two
|
|
// the same.
|
|
//
|
|
//go:embed proxy
|
|
var proxyConfigs embed.FS
|
|
|
|
// AboutData is what the page is rendered with.
|
|
type AboutData struct {
|
|
// Version is what this build calls itself; Release is the same when it is
|
|
// a released version, and empty for a development build, which has no
|
|
// files to download.
|
|
Version, Release string
|
|
// Download is where the release's files are, or for a development build
|
|
// the proxy configurations on main.
|
|
Download string
|
|
// Date is the release date, when it is known. A binary does not know it.
|
|
Date string
|
|
Caddy, Nginx string
|
|
Site bool
|
|
}
|
|
|
|
// InstallURL is the install guide: on a gateway its /install, on the website
|
|
// the page beside this one.
|
|
func (d AboutData) InstallURL() string {
|
|
if d.Site {
|
|
return "install.html"
|
|
}
|
|
return "/install"
|
|
}
|
|
|
|
// DeckURL is the introduction for decision makers, as a PDF. It lives in the
|
|
// repository rather than in the binary, so every gateway does not carry a
|
|
// megabyte of slides; gateway and website link to the same file.
|
|
func (AboutData) DeckURL() string {
|
|
return repoURL + "/raw/branch/main/docs/llmgw-intro.pdf"
|
|
}
|
|
|
|
// Still is a screen of the install guide's recording, for the steps here.
|
|
func (d AboutData) Still(name string) template.HTML {
|
|
return InstallData{Site: d.Site}.Still(name)
|
|
}
|
|
|
|
// releaseTag is a version the releases page has files for.
|
|
var releaseTag = regexp.MustCompile(`^v\d+\.\d+\.\d+$`)
|
|
|
|
const repoURL = "https://gitea.mynodes.xyz/ilker/llmgw"
|
|
|
|
// NewAboutData fills the page's data for a version.
|
|
func NewAboutData(version string) AboutData {
|
|
d := AboutData{Version: version, Download: repoURL + "/raw/branch/main/deploy/proxy"}
|
|
if releaseTag.MatchString(version) {
|
|
d.Release = version
|
|
d.Download = repoURL + "/releases/download/" + version
|
|
}
|
|
d.Caddy = proxyConfig("Caddyfile")
|
|
d.Nginx = proxyConfig("nginx.conf")
|
|
return d
|
|
}
|
|
|
|
func proxyConfig(name string) string {
|
|
b, err := proxyConfigs.ReadFile("proxy/" + name)
|
|
if err != nil {
|
|
panic("web: the proxy configuration " + name + " is missing from the binary: " + err.Error())
|
|
}
|
|
return strings.TrimRight(string(b), "\n")
|
|
}
|
|
|
|
// RenderAbout writes the page, for the website's build as much as for About.
|
|
func RenderAbout(w io.Writer, d AboutData) error {
|
|
return tmpl.ExecuteTemplate(w, "about", d)
|
|
}
|
|
|
|
// About serves the page at /about.
|
|
func About(version string) http.HandlerFunc {
|
|
d := NewAboutData(version)
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
render(w, r, "about", d)
|
|
}
|
|
}
|