From 8b052d9ab097e696513ac1764a5a26dabffb67b4 Mon Sep 17 00:00:00 2001 From: dadachann <185672915+dadachann@users.noreply.github.com> Date: Fri, 4 Sep 2026 12:31:27 +0000 Subject: [PATCH] fix: preserve Mintlify routes and localized navigation --- press.config.tsx | 71 +- scripts/generate-alternate-sitemap.mjs | 34 +- scripts/prepare-fumapress.mjs | 38 +- sitemap-alternates.xml | 1770 +++++++++++----------- tests/fixtures/legacy-sitemap-routes.txt | 480 ++++++ tests/fumapress-migration.test.mjs | 15 +- tests/fumapress-static-build.test.mjs | 55 +- 7 files changed, 1512 insertions(+), 951 deletions(-) create mode 100644 tests/fixtures/legacy-sitemap-routes.txt diff --git a/press.config.tsx b/press.config.tsx index 6a7ff2e0d..c19b28c30 100644 --- a/press.config.tsx +++ b/press.config.tsx @@ -8,7 +8,7 @@ import { update } from "fumadocs-core/source"; import { uiTranslations } from "fumadocs-ui/i18n"; import { defineDocs } from "fumadocs-mdx/macro"; import { createOpenAPI, type OpenAPIServer } from "fumadocs-openapi/server"; -import { readdirSync } from "node:fs"; +import { readFileSync, readdirSync } from "node:fs"; import path from "node:path"; const SITE_URL = "https://docs.langbot.dev"; @@ -16,17 +16,27 @@ const LOCALES = ["en", "zh", "ja"] as const; const MINTLIFY_LOCALE = { en: "en", zh: "cn", ja: "jp" } as const; const HREFLANG = { en: "en", zh: "zh-CN", ja: "ja" } as const; const mintlifyDocs = readMintlifyDocs(); -const translations = defineMintlifyI18n(mintlifyDocs, { +const i18n = defineMintlifyI18n(mintlifyDocs, { localeMap: { en: "en", cn: "zh", jp: "ja" }, -}).translations() +}); +const translations = i18n.translations() .extend(uiTranslations()) .add({ en: { displayName: "English" }, zh: { displayName: "简体中文" }, ja: { displayName: "日本語" }, }); +// Fumapress stores translations.config as its runtime i18n config. Preserve +// the Mintlify adapter's locale bridge there so navigation.languages selects +// the matching English, Chinese, or Japanese tree instead of always using en. +Object.assign(translations.config, { + _getMintlifyLanguage: (i18n as typeof i18n & { + _getMintlifyLanguage?: (locale: string) => string | undefined; + })._getMintlifyLanguage, +}); // Locale-only files must not inherit the English storage and create indexed // pages in locales where no canonical source translation exists. +i18n.fallbackLanguage = null; translations.config.fallbackLanguage = null; function collectRouteLocales() { @@ -70,6 +80,42 @@ const enOpenAPI = createOpenAPI({ input: ["openapi/service-api-en.json"] }); const zhOpenAPI = createOpenAPI({ input: ["openapi/service-api-zh.json"] }); const jaOpenAPI = createOpenAPI({ input: ["openapi/service-api-ja.json"] }); +function legacyOpenApiSlug(value: string) { + return value.replace(/\s+/g, "-").toLowerCase(); +} + +const legacyOpenApiLayout = { + groupBy: "tag" as const, + name: (entry: { info: { title: string } }) => legacyOpenApiSlug(entry.info.title), +}; + +function encodeRoute(route: string) { + return route.split("/").map((segment) => encodeURIComponent(segment)).join("/"); +} + +const openApiAlternates = new Map>>(); +for (const locale of LOCALES) { + const spec = JSON.parse(readFileSync(`openapi/service-api-${locale}.json`, "utf8")); + for (const [apiPath, pathItem] of Object.entries(spec.paths ?? {}) as [string, Record][]) { + for (const [method, operation] of Object.entries(pathItem)) { + if (!/^(?:get|post|put|patch|delete|head|options)$/i.test(method) || !operation?.summary) continue; + const tag = operation.tags?.[0] ?? "unknown"; + const route = encodeRoute(`api-reference/${legacyOpenApiSlug(tag)}/${legacyOpenApiSlug(operation.summary)}`); + const key = `${method.toLowerCase()} ${apiPath}`; + const alternates = openApiAlternates.get(key) ?? {}; + alternates[locale] = route; + openApiAlternates.set(key, alternates); + } + } +} +const openApiAlternatesByRoute = new Map>>(); +for (const alternates of openApiAlternates.values()) { + for (const locale of LOCALES) { + const route = alternates[locale]; + if (route) openApiAlternatesByRoute.set(`${locale}:${route}`, alternates); + } +} + function localizeOpenAPISource( source: Awaited>, locale: string, @@ -103,18 +149,19 @@ export default defineConfig({ content: { docs: docs.toFumadocsSource(), openapiEn: localizeOpenAPISource( - await enOpenAPI.staticSource({ baseDir: "en/api-reference" }), + await enOpenAPI.staticSource({ baseDir: "en/api-reference", ...legacyOpenApiLayout }), "en", ), openapiZh: localizeOpenAPISource( - await zhOpenAPI.staticSource({ baseDir: "zh/api-reference" }), + await zhOpenAPI.staticSource({ baseDir: "zh/api-reference", ...legacyOpenApiLayout }), "zh", ), openapiJa: localizeOpenAPISource( - await jaOpenAPI.staticSource({ baseDir: "ja/api-reference" }), + await jaOpenAPI.staticSource({ baseDir: "ja/api-reference", ...legacyOpenApiLayout }), "ja", ), }, + i18n, translations, defaultLayoutProps: ({ lang }) => ({ links: localizedNavbar(lang), @@ -123,10 +170,10 @@ export default defineConfig({ page: (page) => { const locale = page.locale as (typeof LOCALES)[number]; const route = page.slugs.join("/"); - const available = route.startsWith("api-reference/") - ? new Set(LOCALES) - : routeLocales.get(route) ?? new Set([locale]); - const alternates = LOCALES.filter((candidate) => available.has(candidate)); + const localizedRoutes = route.startsWith("api-reference/") + ? openApiAlternatesByRoute.get(`${locale}:${route}`) ?? { [locale]: route } + : Object.fromEntries([...routeLocales.get(route) ?? new Set([locale])].map((candidate) => [candidate, route])); + const alternates = LOCALES.filter((candidate) => localizedRoutes[candidate]); const defaultLocale = alternates.includes("en") ? "en" : alternates[0]; return <> @@ -135,14 +182,14 @@ export default defineConfig({ key={candidate} rel="alternate" hrefLang={HREFLANG[candidate]} - href={`${SITE_URL}/${candidate}/${route}`.replace(/\/$/, "")} + href={`${SITE_URL}/${candidate}/${localizedRoutes[candidate]}`.replace(/\/$/, "")} /> ))} {defaultLocale && ( )} ; diff --git a/scripts/generate-alternate-sitemap.mjs b/scripts/generate-alternate-sitemap.mjs index 228171a7e..730f12136 100644 --- a/scripts/generate-alternate-sitemap.mjs +++ b/scripts/generate-alternate-sitemap.mjs @@ -27,7 +27,7 @@ function decodeXml(value) { .replaceAll("'", "'"); } -export function renderAlternateSitemap(sitemap, base = BASE) { +export function renderAlternateSitemap(sitemap, base = BASE, explicitGroups = []) { const urls = [...sitemap.matchAll(/([^<]+)<\/loc>/g)].map((match) => decodeXml(match[1])); const groups = new Map(); for (const url of urls) { @@ -42,6 +42,8 @@ export function renderAlternateSitemap(sitemap, base = BASE) { } } + for (const group of explicitGroups) groups.set(`explicit:${group.en}`, group); + const shared = [...groups.values()] .filter((group) => LOCALES.every((locale) => group[locale])) .sort((left, right) => left.en.localeCompare(right.en)); @@ -66,6 +68,33 @@ export function renderAlternateSitemap(sitemap, base = BASE) { return { xml: `${lines.join("\n")}\n`, groups: shared.length }; } +function legacyOpenApiSlug(value) { + return value.replace(/\s+/g, "-").toLowerCase(); +} + +function encodeRoute(route) { + return route.split("/").map((segment) => encodeURIComponent(segment)).join("/"); +} + +async function collectOpenApiAlternateGroups(root = ROOT, base = BASE) { + const groups = new Map(); + for (const locale of LOCALES) { + const spec = JSON.parse(await readFile(path.join(root, `openapi/service-api-${locale}.json`), "utf8")); + for (const [apiPath, pathItem] of Object.entries(spec.paths ?? {})) { + for (const [method, operation] of Object.entries(pathItem)) { + if (!/^(?:get|post|put|patch|delete|head|options)$/i.test(method) || !operation?.summary) continue; + const tag = operation.tags?.[0] ?? "unknown"; + const route = encodeRoute(`api-reference/${legacyOpenApiSlug(tag)}/${legacyOpenApiSlug(operation.summary)}`); + const key = `${method.toLowerCase()} ${apiPath}`; + const group = groups.get(key) ?? {}; + group[locale] = `${base}/${locale}/${route}`; + groups.set(key, group); + } + } + } + return [...groups.values()]; +} + async function loadSource(source) { if (/^https?:\/\//.test(source)) { const response = await fetch(source, { headers: { "user-agent": "LangBot docs alternate-sitemap generator" } }); @@ -77,7 +106,8 @@ async function loadSource(source) { async function main() { const source = process.env.SITEMAP_SOURCE ?? path.join(ROOT, "dist/public/sitemap.xml"); - const { xml, groups } = renderAlternateSitemap(await loadSource(source)); + const openApiGroups = await collectOpenApiAlternateGroups(); + const { xml, groups } = renderAlternateSitemap(await loadSource(source), BASE, openApiGroups); const outputs = process.env.SITEMAP_OUTPUT ? [path.resolve(process.env.SITEMAP_OUTPUT)] : [path.join(ROOT, "dist/public/sitemap-alternates.xml"), path.join(ROOT, "sitemap-alternates.xml")]; diff --git a/scripts/prepare-fumapress.mjs b/scripts/prepare-fumapress.mjs index e2a2b2e88..1fe97827b 100644 --- a/scripts/prepare-fumapress.mjs +++ b/scripts/prepare-fumapress.mjs @@ -115,33 +115,15 @@ function cloudflarePattern(value, destination = false) { return value.replace(/:([A-Za-z][A-Za-z0-9_]*)\*/g, destination ? ":splat" : "*"); } -function slugifyOpenApiSummary(value) { - return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, ""); -} - -export function collectOpenApiRedirectTargets(spec) { - const targets = new Map(); - for (const [apiPath, pathItem] of Object.entries(spec?.paths ?? {})) { - for (const [method, operation] of Object.entries(pathItem)) { - if (!/^(?:get|post|put|patch|delete|head|options)$/i.test(method) || !operation?.summary) continue; - const summarySlug = slugifyOpenApiSummary(operation.summary); - const routePath = apiPath.replaceAll("{", "").replaceAll("}", ""); - targets.set(summarySlug, `/en/api-reference${routePath}/${method.toLowerCase()}`); - } - } - return targets; -} - -export function renderCloudflareRedirects(docs, englishOpenApiSpec) { - const apiTargets = collectOpenApiRedirectTargets(englishOpenApiSpec); - const lines = ["/ /en/insight/guide 302"]; +export function renderCloudflareRedirects(docs) { + const lines = [ + "/ /en/insight/guide 302", + "/zh/develop/adapter/discord /zh/develop/adapter/discord/README 308", + "/scripts/README-blog-articles /en/articles 308", + ]; for (const redirect of docs.redirects ?? []) { const status = redirect.permanent === false ? 307 : 308; - const destinationSlug = redirect.destination.match(/^\/en\/api-reference\/[^/]+\/([^/:*]+)$/)?.[1]; - const destination = destinationSlug && apiTargets.get(destinationSlug) - ? apiTargets.get(destinationSlug) - : redirect.destination; - lines.push(`${cloudflarePattern(redirect.source)} ${cloudflarePattern(destination, true)} ${status}`); + lines.push(`${cloudflarePattern(redirect.source)} ${cloudflarePattern(redirect.destination, true)} ${status}`); } return `${lines.join("\n")}\n`; } @@ -159,8 +141,6 @@ export async function prepareFumapress({ root = ROOT, outRoot = root } = {}) { if (openapi.length !== LOCALES.length) { throw new Error(`Expected one nested OpenAPI source per locale, found ${openapi.length}`); } - const englishOpenApi = JSON.parse(await readFile(path.join(root, openapi.find((item) => item.locale === "en").source), "utf8")); - const contentRoot = path.join(outRoot, "content"); const publicRoot = path.join(outRoot, "public"); await rm(contentRoot, { recursive: true, force: true }); @@ -200,13 +180,13 @@ export async function prepareFumapress({ root = ROOT, outRoot = root } = {}) { } await cp(path.join(root, "robots.txt"), path.join(publicRoot, "robots.txt"), { force: true }); - await writeFile(path.join(publicRoot, "_redirects"), renderCloudflareRedirects(docs, englishOpenApi)); + await writeFile(path.join(publicRoot, "_redirects"), renderCloudflareRedirects(docs)); return { documents: documents.length, fallbackDefaults: 0, localeOnlyDocuments, - redirects: (docs.redirects?.length ?? 0) + 1, + redirects: (docs.redirects?.length ?? 0) + 3, locales: [...LOCALES], openapi, }; diff --git a/sitemap-alternates.xml b/sitemap-alternates.xml index a2cad6fbe..831768400 100644 --- a/sitemap-alternates.xml +++ b/sitemap-alternates.xml @@ -1,1243 +1,1243 @@ - https://docs.langbot.dev/en/api-reference/api/v1/files/documents/post - - - - + https://docs.langbot.dev/en/api-reference/bots/create-a-bot + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/files/documents/post - - - - + https://docs.langbot.dev/zh/api-reference/%E6%9C%BA%E5%99%A8%E4%BA%BA/%E5%88%9B%E5%BB%BA%E6%9C%BA%E5%99%A8%E4%BA%BA + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/files/documents/post - - - - + https://docs.langbot.dev/ja/api-reference/bots/%E5%88%9B%E5%BB%BA%E6%9C%BA%E5%99%A8%E4%BA%BA + + + + - https://docs.langbot.dev/en/api-reference/api/v1/files/images/post - - - - + https://docs.langbot.dev/en/api-reference/bots/delete-a-bot + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/files/images/post - - - - + https://docs.langbot.dev/zh/api-reference/%E6%9C%BA%E5%99%A8%E4%BA%BA/%E5%88%A0%E9%99%A4%E6%9C%BA%E5%99%A8%E4%BA%BA + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/files/images/post - - - - + https://docs.langbot.dev/ja/api-reference/bots/%E5%88%A0%E9%99%A4%E6%9C%BA%E5%99%A8%E4%BA%BA + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/bases/get - - - - + https://docs.langbot.dev/en/api-reference/bots/get-a-bot + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/bases/get - - - - + https://docs.langbot.dev/zh/api-reference/%E6%9C%BA%E5%99%A8%E4%BA%BA/%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E6%9C%BA%E5%99%A8%E4%BA%BA + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/bases/get - - - - + https://docs.langbot.dev/ja/api-reference/bots/%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E6%9C%BA%E5%99%A8%E4%BA%BA + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/bases/kb_uuid/delete - - - - + https://docs.langbot.dev/en/api-reference/bots/get-bot-event-logs + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/bases/kb_uuid/delete - - - - + https://docs.langbot.dev/zh/api-reference/%E6%9C%BA%E5%99%A8%E4%BA%BA/%E8%8E%B7%E5%8F%96%E6%9C%BA%E5%99%A8%E4%BA%BA%E4%BA%8B%E4%BB%B6%E6%97%A5%E5%BF%97 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/bases/kb_uuid/delete - - - - + https://docs.langbot.dev/ja/api-reference/bots/%E8%8E%B7%E5%8F%96%E6%9C%BA%E5%99%A8%E4%BA%BA%E4%BA%8B%E4%BB%B6%E6%97%A5%E5%BF%97 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/bases/kb_uuid/files/file_id/delete - - - - + https://docs.langbot.dev/en/api-reference/bots/list-all-bots + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/bases/kb_uuid/files/file_id/delete - - - - + https://docs.langbot.dev/zh/api-reference/%E6%9C%BA%E5%99%A8%E4%BA%BA/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E6%9C%BA%E5%99%A8%E4%BA%BA + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/bases/kb_uuid/files/file_id/delete - - - - + https://docs.langbot.dev/ja/api-reference/bots/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E6%9C%BA%E5%99%A8%E4%BA%BA + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/bases/kb_uuid/files/get - - - - + https://docs.langbot.dev/en/api-reference/bots/send-a-message-through-a-bot + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/bases/kb_uuid/files/get - - - - + https://docs.langbot.dev/zh/api-reference/%E6%9C%BA%E5%99%A8%E4%BA%BA/%E9%80%9A%E8%BF%87%E6%9C%BA%E5%99%A8%E4%BA%BA%E5%8F%91%E9%80%81%E6%B6%88%E6%81%AF + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/bases/kb_uuid/files/get - - - - + https://docs.langbot.dev/ja/api-reference/bots/%E9%80%9A%E8%BF%87%E6%9C%BA%E5%99%A8%E4%BA%BA%E5%8F%91%E9%80%81%E6%B6%88%E6%81%AF + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/bases/kb_uuid/files/post - - - - + https://docs.langbot.dev/en/api-reference/bots/update-a-bot + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/bases/kb_uuid/files/post - - - - + https://docs.langbot.dev/zh/api-reference/%E6%9C%BA%E5%99%A8%E4%BA%BA/%E6%9B%B4%E6%96%B0%E6%9C%BA%E5%99%A8%E4%BA%BA + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/bases/kb_uuid/files/post - - - - + https://docs.langbot.dev/ja/api-reference/bots/%E6%9B%B4%E6%96%B0%E6%9C%BA%E5%99%A8%E4%BA%BA + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/bases/kb_uuid/get - - - - + https://docs.langbot.dev/en/api-reference/embedding-models/create-an-embedding-model + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/bases/kb_uuid/get - - - - + https://docs.langbot.dev/zh/api-reference/%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B/%E5%88%9B%E5%BB%BA%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/bases/kb_uuid/get - - - - + https://docs.langbot.dev/ja/api-reference/embedding-models/%E5%88%9B%E5%BB%BA%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/bases/kb_uuid/put - - - - + https://docs.langbot.dev/en/api-reference/embedding-models/delete-an-embedding-model + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/bases/kb_uuid/put - - - - + https://docs.langbot.dev/zh/api-reference/%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B/%E5%88%A0%E9%99%A4%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/bases/kb_uuid/put - - - - + https://docs.langbot.dev/ja/api-reference/embedding-models/%E5%88%A0%E9%99%A4%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/bases/kb_uuid/retrieve/post - - - - + https://docs.langbot.dev/en/api-reference/embedding-models/get-an-embedding-model + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/bases/kb_uuid/retrieve/post - - - - + https://docs.langbot.dev/zh/api-reference/%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B/%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/bases/kb_uuid/retrieve/post - - - - + https://docs.langbot.dev/ja/api-reference/embedding-models/%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/bases/post - - - - + https://docs.langbot.dev/en/api-reference/embedding-models/list-all-embedding-models + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/bases/post - - - - + https://docs.langbot.dev/zh/api-reference/%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/bases/post - - - - + https://docs.langbot.dev/ja/api-reference/embedding-models/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/engines/get - - - - + https://docs.langbot.dev/en/api-reference/embedding-models/test-an-embedding-model + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/engines/get - - - - + https://docs.langbot.dev/zh/api-reference/%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B/%E6%B5%8B%E8%AF%95%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/engines/get - - - - + https://docs.langbot.dev/ja/api-reference/embedding-models/%E6%B5%8B%E8%AF%95%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/engines/plugin_id/creation-schema/get - - - - + https://docs.langbot.dev/en/api-reference/embedding-models/update-an-embedding-model + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/engines/plugin_id/creation-schema/get - - - - + https://docs.langbot.dev/zh/api-reference/%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B/%E6%9B%B4%E6%96%B0%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/engines/plugin_id/creation-schema/get - - - - + https://docs.langbot.dev/ja/api-reference/embedding-models/%E6%9B%B4%E6%96%B0%E5%90%91%E9%87%8F%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/engines/plugin_id/retrieval-schema/get - - - - + https://docs.langbot.dev/en/api-reference/files/upload-a-document + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/engines/plugin_id/retrieval-schema/get - - - - + https://docs.langbot.dev/zh/api-reference/%E6%96%87%E4%BB%B6/%E4%B8%8A%E4%BC%A0%E6%96%87%E6%A1%A3 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/engines/plugin_id/retrieval-schema/get - - - - + https://docs.langbot.dev/ja/api-reference/files/%E4%B8%8A%E4%BC%A0%E6%96%87%E6%A1%A3 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/knowledge/parsers/get - - - - + https://docs.langbot.dev/en/api-reference/files/upload-an-image + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/knowledge/parsers/get - - - - + https://docs.langbot.dev/zh/api-reference/%E6%96%87%E4%BB%B6/%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/knowledge/parsers/get - - - - + https://docs.langbot.dev/ja/api-reference/files/%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/pipelines/_/metadata/get - - - - + https://docs.langbot.dev/en/api-reference/knowledge-bases/add-a-file-to-a-knowledge-base + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/pipelines/_/metadata/get - - - - + https://docs.langbot.dev/zh/api-reference/%E7%9F%A5%E8%AF%86%E5%BA%93/%E5%B0%86%E6%96%87%E4%BB%B6%E5%AD%98%E5%85%A5%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/pipelines/_/metadata/get - - - - + https://docs.langbot.dev/ja/api-reference/knowledge-bases/%E5%B0%86%E6%96%87%E4%BB%B6%E5%AD%98%E5%85%A5%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/pipelines/get - - - - + https://docs.langbot.dev/en/api-reference/knowledge-bases/create-a-knowledge-base + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/pipelines/get - - - - + https://docs.langbot.dev/zh/api-reference/%E7%9F%A5%E8%AF%86%E5%BA%93/%E5%88%9B%E5%BB%BA%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/pipelines/get - - - - + https://docs.langbot.dev/ja/api-reference/knowledge-bases/%E5%88%9B%E5%BB%BA%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/pipelines/pipeline_uuid/copy/post - - - - + https://docs.langbot.dev/en/api-reference/knowledge-bases/delete-a-knowledge-base + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/pipelines/pipeline_uuid/copy/post - - - - + https://docs.langbot.dev/zh/api-reference/%E7%9F%A5%E8%AF%86%E5%BA%93/%E5%88%A0%E9%99%A4%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/pipelines/pipeline_uuid/copy/post - - - - + https://docs.langbot.dev/ja/api-reference/knowledge-bases/%E5%88%A0%E9%99%A4%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/pipelines/pipeline_uuid/delete - - - - + https://docs.langbot.dev/en/api-reference/knowledge-bases/get-a-knowledge-base + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/pipelines/pipeline_uuid/delete - - - - + https://docs.langbot.dev/zh/api-reference/%E7%9F%A5%E8%AF%86%E5%BA%93/%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/pipelines/pipeline_uuid/delete - - - - + https://docs.langbot.dev/ja/api-reference/knowledge-bases/%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/pipelines/pipeline_uuid/extensions/get - - - - + https://docs.langbot.dev/en/api-reference/knowledge-bases/list-all-knowledge-bases + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/pipelines/pipeline_uuid/extensions/get - - - - + https://docs.langbot.dev/zh/api-reference/%E7%9F%A5%E8%AF%86%E5%BA%93/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/pipelines/pipeline_uuid/extensions/get - - - - + https://docs.langbot.dev/ja/api-reference/knowledge-bases/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/pipelines/pipeline_uuid/extensions/put - - - - + https://docs.langbot.dev/en/api-reference/knowledge-bases/list-knowledge-base-files + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/pipelines/pipeline_uuid/extensions/put - - - - + https://docs.langbot.dev/zh/api-reference/%E7%9F%A5%E8%AF%86%E5%BA%93/%E8%8E%B7%E5%8F%96%E7%9F%A5%E8%AF%86%E5%BA%93%E6%96%87%E4%BB%B6%E5%88%97%E8%A1%A8 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/pipelines/pipeline_uuid/extensions/put - - - - + https://docs.langbot.dev/ja/api-reference/knowledge-bases/%E8%8E%B7%E5%8F%96%E7%9F%A5%E8%AF%86%E5%BA%93%E6%96%87%E4%BB%B6%E5%88%97%E8%A1%A8 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/pipelines/pipeline_uuid/get - - - - + https://docs.langbot.dev/en/api-reference/knowledge-bases/remove-a-file-from-a-knowledge-base + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/pipelines/pipeline_uuid/get - - - - + https://docs.langbot.dev/zh/api-reference/%E7%9F%A5%E8%AF%86%E5%BA%93/%E4%BB%8E%E7%9F%A5%E8%AF%86%E5%BA%93%E5%88%A0%E9%99%A4%E6%96%87%E4%BB%B6 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/pipelines/pipeline_uuid/get - - - - + https://docs.langbot.dev/ja/api-reference/knowledge-bases/%E4%BB%8E%E7%9F%A5%E8%AF%86%E5%BA%93%E5%88%A0%E9%99%A4%E6%96%87%E4%BB%B6 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/pipelines/pipeline_uuid/put - - - - + https://docs.langbot.dev/en/api-reference/knowledge-bases/retrieve-from-a-knowledge-base + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/pipelines/pipeline_uuid/put - - - - + https://docs.langbot.dev/zh/api-reference/%E7%9F%A5%E8%AF%86%E5%BA%93/%E6%A3%80%E7%B4%A2%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/pipelines/pipeline_uuid/put - - - - + https://docs.langbot.dev/ja/api-reference/knowledge-bases/%E6%A3%80%E7%B4%A2%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/pipelines/post - - - - + https://docs.langbot.dev/en/api-reference/knowledge-bases/update-a-knowledge-base + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/pipelines/post - - - - + https://docs.langbot.dev/zh/api-reference/%E7%9F%A5%E8%AF%86%E5%BA%93/%E6%9B%B4%E6%96%B0%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/pipelines/post - - - - + https://docs.langbot.dev/ja/api-reference/knowledge-bases/%E6%9B%B4%E6%96%B0%E7%9F%A5%E8%AF%86%E5%BA%93 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/platform/bots/bot_uuid/delete - - - - + https://docs.langbot.dev/en/api-reference/knowledge-engines/get-the-knowledge-engine-creation-schema + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/platform/bots/bot_uuid/delete - - - - + https://docs.langbot.dev/zh/api-reference/%E7%9F%A5%E8%AF%86%E5%BC%95%E6%93%8E/%E8%8E%B7%E5%8F%96%E7%9F%A5%E8%AF%86%E5%BC%95%E6%93%8E%E5%88%9B%E5%BB%BA%E9%85%8D%E7%BD%AE%E6%A8%A1%E5%BC%8F + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/platform/bots/bot_uuid/delete - - - - + https://docs.langbot.dev/ja/api-reference/knowledge-engines/%E8%8E%B7%E5%8F%96%E7%9F%A5%E8%AF%86%E5%BC%95%E6%93%8E%E5%88%9B%E5%BB%BA%E9%85%8D%E7%BD%AE%E6%A8%A1%E5%BC%8F + + + + - https://docs.langbot.dev/en/api-reference/api/v1/platform/bots/bot_uuid/get - - - - + https://docs.langbot.dev/en/api-reference/knowledge-engines/get-the-knowledge-engine-retrieval-schema + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/platform/bots/bot_uuid/get - - - - + https://docs.langbot.dev/zh/api-reference/%E7%9F%A5%E8%AF%86%E5%BC%95%E6%93%8E/%E8%8E%B7%E5%8F%96%E7%9F%A5%E8%AF%86%E5%BC%95%E6%93%8E%E6%A3%80%E7%B4%A2%E9%85%8D%E7%BD%AE%E6%A8%A1%E5%BC%8F + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/platform/bots/bot_uuid/get - - - - + https://docs.langbot.dev/ja/api-reference/knowledge-engines/%E8%8E%B7%E5%8F%96%E7%9F%A5%E8%AF%86%E5%BC%95%E6%93%8E%E6%A3%80%E7%B4%A2%E9%85%8D%E7%BD%AE%E6%A8%A1%E5%BC%8F + + + + - https://docs.langbot.dev/en/api-reference/api/v1/platform/bots/bot_uuid/logs/post - - - - + https://docs.langbot.dev/en/api-reference/knowledge-engines/list-available-knowledge-engines + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/platform/bots/bot_uuid/logs/post - - - - + https://docs.langbot.dev/zh/api-reference/%E7%9F%A5%E8%AF%86%E5%BC%95%E6%93%8E/%E8%8E%B7%E5%8F%96%E5%8F%AF%E7%94%A8%E7%9F%A5%E8%AF%86%E5%BC%95%E6%93%8E%E5%88%97%E8%A1%A8 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/platform/bots/bot_uuid/logs/post - - - - + https://docs.langbot.dev/ja/api-reference/knowledge-engines/%E8%8E%B7%E5%8F%96%E5%8F%AF%E7%94%A8%E7%9F%A5%E8%AF%86%E5%BC%95%E6%93%8E%E5%88%97%E8%A1%A8 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/platform/bots/bot_uuid/put - - - - + https://docs.langbot.dev/en/api-reference/llm-models/create-an-llm-model + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/platform/bots/bot_uuid/put - - - - + https://docs.langbot.dev/zh/api-reference/%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B/%E5%88%9B%E5%BB%BA-llm-%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/platform/bots/bot_uuid/put - - - - + https://docs.langbot.dev/ja/api-reference/llm-models/%E5%88%9B%E5%BB%BA-llm-%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/en/api-reference/api/v1/platform/bots/bot_uuid/send_message/post - - - - + https://docs.langbot.dev/en/api-reference/llm-models/delete-an-llm-model + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/platform/bots/bot_uuid/send_message/post - - - - + https://docs.langbot.dev/zh/api-reference/%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B/%E5%88%A0%E9%99%A4-llm-%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/platform/bots/bot_uuid/send_message/post - - - - + https://docs.langbot.dev/ja/api-reference/llm-models/%E5%88%A0%E9%99%A4-llm-%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/en/api-reference/api/v1/platform/bots/get - - - - + https://docs.langbot.dev/en/api-reference/llm-models/get-an-llm-model + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/platform/bots/get - - - - + https://docs.langbot.dev/zh/api-reference/%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B/%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA-llm-%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/platform/bots/get - - - - + https://docs.langbot.dev/ja/api-reference/llm-models/%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA-llm-%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/en/api-reference/api/v1/platform/bots/post - - - - + https://docs.langbot.dev/en/api-reference/llm-models/list-all-llm-models + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/platform/bots/post - - - - + https://docs.langbot.dev/zh/api-reference/%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89-llm-%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/platform/bots/post - - - - + https://docs.langbot.dev/ja/api-reference/llm-models/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89-llm-%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/en/api-reference/api/v1/plugins/author/plugin_name/config/get - - - - + https://docs.langbot.dev/en/api-reference/llm-models/test-an-llm-model + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/plugins/author/plugin_name/config/get - - - - + https://docs.langbot.dev/zh/api-reference/%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B/%E6%B5%8B%E8%AF%95-llm-%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/plugins/author/plugin_name/config/get - - - - + https://docs.langbot.dev/ja/api-reference/llm-models/%E6%B5%8B%E8%AF%95-llm-%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/en/api-reference/api/v1/plugins/author/plugin_name/config/put - - - - + https://docs.langbot.dev/en/api-reference/llm-models/update-an-llm-model + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/plugins/author/plugin_name/config/put - - - - + https://docs.langbot.dev/zh/api-reference/%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B/%E6%9B%B4%E6%96%B0-llm-%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/plugins/author/plugin_name/config/put - - - - + https://docs.langbot.dev/ja/api-reference/llm-models/%E6%9B%B4%E6%96%B0-llm-%E6%A8%A1%E5%9E%8B + + + + - https://docs.langbot.dev/en/api-reference/api/v1/plugins/author/plugin_name/delete - - - - + https://docs.langbot.dev/en/api-reference/model-providers/create-a-model-provider + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/plugins/author/plugin_name/delete - - - - + https://docs.langbot.dev/zh/api-reference/%E6%A8%A1%E5%9E%8B%E4%BE%9B%E5%BA%94%E5%95%86/%E5%88%9B%E5%BB%BA%E4%BE%9B%E5%BA%94%E5%95%86 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/plugins/author/plugin_name/delete - - - - + https://docs.langbot.dev/ja/api-reference/model-providers/%E5%88%9B%E5%BB%BA%E4%BE%9B%E5%BA%94%E5%95%86 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/plugins/author/plugin_name/get - - - - + https://docs.langbot.dev/en/api-reference/model-providers/delete-a-model-provider + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/plugins/author/plugin_name/get - - - - + https://docs.langbot.dev/zh/api-reference/%E6%A8%A1%E5%9E%8B%E4%BE%9B%E5%BA%94%E5%95%86/%E5%88%A0%E9%99%A4%E4%BE%9B%E5%BA%94%E5%95%86 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/plugins/author/plugin_name/get - - - - + https://docs.langbot.dev/ja/api-reference/model-providers/%E5%88%A0%E9%99%A4%E4%BE%9B%E5%BA%94%E5%95%86 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/plugins/author/plugin_name/upgrade/post - - - - + https://docs.langbot.dev/en/api-reference/model-providers/get-a-model-provider + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/plugins/author/plugin_name/upgrade/post - - - - + https://docs.langbot.dev/zh/api-reference/%E6%A8%A1%E5%9E%8B%E4%BE%9B%E5%BA%94%E5%95%86/%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E4%BE%9B%E5%BA%94%E5%95%86 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/plugins/author/plugin_name/upgrade/post - - - - + https://docs.langbot.dev/ja/api-reference/model-providers/%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E4%BE%9B%E5%BA%94%E5%95%86 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/plugins/get - - - - + https://docs.langbot.dev/en/api-reference/model-providers/list-all-model-providers + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/plugins/get - - - - + https://docs.langbot.dev/zh/api-reference/%E6%A8%A1%E5%9E%8B%E4%BE%9B%E5%BA%94%E5%95%86/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E4%BE%9B%E5%BA%94%E5%95%86 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/plugins/get - - - - + https://docs.langbot.dev/ja/api-reference/model-providers/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E4%BE%9B%E5%BA%94%E5%95%86 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/plugins/install/github/post - - - - + https://docs.langbot.dev/en/api-reference/model-providers/update-a-model-provider + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/plugins/install/github/post - - - - + https://docs.langbot.dev/zh/api-reference/%E6%A8%A1%E5%9E%8B%E4%BE%9B%E5%BA%94%E5%95%86/%E6%9B%B4%E6%96%B0%E4%BE%9B%E5%BA%94%E5%95%86 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/plugins/install/github/post - - - - + https://docs.langbot.dev/ja/api-reference/model-providers/%E6%9B%B4%E6%96%B0%E4%BE%9B%E5%BA%94%E5%95%86 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/plugins/install/marketplace/post - - - - + https://docs.langbot.dev/en/api-reference/parsers/list-available-parsers + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/plugins/install/marketplace/post - - - - + https://docs.langbot.dev/zh/api-reference/%E8%A7%A3%E6%9E%90%E5%99%A8/%E8%8E%B7%E5%8F%96%E5%8F%AF%E7%94%A8%E8%A7%A3%E6%9E%90%E5%99%A8%E5%88%97%E8%A1%A8 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/plugins/install/marketplace/post - - - - + https://docs.langbot.dev/ja/api-reference/parsers/%E8%8E%B7%E5%8F%96%E5%8F%AF%E7%94%A8%E8%A7%A3%E6%9E%90%E5%99%A8%E5%88%97%E8%A1%A8 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/models/embedding/get - - - - + https://docs.langbot.dev/en/api-reference/pipelines/copy-a-pipeline + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/models/embedding/get - - - - + https://docs.langbot.dev/zh/api-reference/%E6%B5%81%E6%B0%B4%E7%BA%BF/%E5%A4%8D%E5%88%B6%E6%B5%81%E6%B0%B4%E7%BA%BF + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/models/embedding/get - - - - + https://docs.langbot.dev/ja/api-reference/pipelines/%E5%A4%8D%E5%88%B6%E6%B5%81%E6%B0%B4%E7%BA%BF + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/models/embedding/model_uuid/delete - - - - + https://docs.langbot.dev/en/api-reference/pipelines/create-a-pipeline + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/models/embedding/model_uuid/delete - - - - + https://docs.langbot.dev/zh/api-reference/%E6%B5%81%E6%B0%B4%E7%BA%BF/%E5%88%9B%E5%BB%BA%E6%B5%81%E6%B0%B4%E7%BA%BF + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/models/embedding/model_uuid/delete - - - - + https://docs.langbot.dev/ja/api-reference/pipelines/%E5%88%9B%E5%BB%BA%E6%B5%81%E6%B0%B4%E7%BA%BF + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/models/embedding/model_uuid/get - - - - + https://docs.langbot.dev/en/api-reference/pipelines/delete-a-pipeline + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/models/embedding/model_uuid/get - - - - + https://docs.langbot.dev/zh/api-reference/%E6%B5%81%E6%B0%B4%E7%BA%BF/%E5%88%A0%E9%99%A4%E6%B5%81%E6%B0%B4%E7%BA%BF + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/models/embedding/model_uuid/get - - - - + https://docs.langbot.dev/ja/api-reference/pipelines/%E5%88%A0%E9%99%A4%E6%B5%81%E6%B0%B4%E7%BA%BF + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/models/embedding/model_uuid/put - - - - + https://docs.langbot.dev/en/api-reference/pipelines/get-a-pipeline + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/models/embedding/model_uuid/put - - - - + https://docs.langbot.dev/zh/api-reference/%E6%B5%81%E6%B0%B4%E7%BA%BF/%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E6%B5%81%E6%B0%B4%E7%BA%BF + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/models/embedding/model_uuid/put - - - - + https://docs.langbot.dev/ja/api-reference/pipelines/%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E6%B5%81%E6%B0%B4%E7%BA%BF + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/models/embedding/model_uuid/test/post - - - - + https://docs.langbot.dev/en/api-reference/pipelines/get-pipeline-extension-configuration + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/models/embedding/model_uuid/test/post - - - - + https://docs.langbot.dev/zh/api-reference/%E6%B5%81%E6%B0%B4%E7%BA%BF/%E8%8E%B7%E5%8F%96%E6%B5%81%E6%B0%B4%E7%BA%BF%E6%89%A9%E5%B1%95%E9%85%8D%E7%BD%AE + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/models/embedding/model_uuid/test/post - - - - + https://docs.langbot.dev/ja/api-reference/pipelines/%E8%8E%B7%E5%8F%96%E6%B5%81%E6%B0%B4%E7%BA%BF%E6%89%A9%E5%B1%95%E9%85%8D%E7%BD%AE + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/models/embedding/post - - - - + https://docs.langbot.dev/en/api-reference/pipelines/get-pipeline-metadata + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/models/embedding/post - - - - + https://docs.langbot.dev/zh/api-reference/%E6%B5%81%E6%B0%B4%E7%BA%BF/%E8%8E%B7%E5%8F%96%E6%B5%81%E6%B0%B4%E7%BA%BF%E5%85%83%E6%95%B0%E6%8D%AE + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/models/embedding/post - - - - + https://docs.langbot.dev/ja/api-reference/pipelines/%E8%8E%B7%E5%8F%96%E6%B5%81%E6%B0%B4%E7%BA%BF%E5%85%83%E6%95%B0%E6%8D%AE + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/models/llm/get - - - - + https://docs.langbot.dev/en/api-reference/pipelines/list-all-pipelines + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/models/llm/get - - - - + https://docs.langbot.dev/zh/api-reference/%E6%B5%81%E6%B0%B4%E7%BA%BF/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E6%B5%81%E6%B0%B4%E7%BA%BF + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/models/llm/get - - - - + https://docs.langbot.dev/ja/api-reference/pipelines/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E6%B5%81%E6%B0%B4%E7%BA%BF + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/models/llm/model_uuid/delete - - - - + https://docs.langbot.dev/en/api-reference/pipelines/update-a-pipeline + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/models/llm/model_uuid/delete - - - - + https://docs.langbot.dev/zh/api-reference/%E6%B5%81%E6%B0%B4%E7%BA%BF/%E6%9B%B4%E6%96%B0%E6%B5%81%E6%B0%B4%E7%BA%BF + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/models/llm/model_uuid/delete - - - - + https://docs.langbot.dev/ja/api-reference/pipelines/%E6%9B%B4%E6%96%B0%E6%B5%81%E6%B0%B4%E7%BA%BF + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/models/llm/model_uuid/get - - - - + https://docs.langbot.dev/en/api-reference/pipelines/update-pipeline-extension-configuration + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/models/llm/model_uuid/get - - - - + https://docs.langbot.dev/zh/api-reference/%E6%B5%81%E6%B0%B4%E7%BA%BF/%E6%9B%B4%E6%96%B0%E6%B5%81%E6%B0%B4%E7%BA%BF%E6%89%A9%E5%B1%95%E9%85%8D%E7%BD%AE + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/models/llm/model_uuid/get - - - - + https://docs.langbot.dev/ja/api-reference/pipelines/%E6%9B%B4%E6%96%B0%E6%B5%81%E6%B0%B4%E7%BA%BF%E6%89%A9%E5%B1%95%E9%85%8D%E7%BD%AE + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/models/llm/model_uuid/put - - - - + https://docs.langbot.dev/en/api-reference/plugins/delete-a-plugin + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/models/llm/model_uuid/put - - - - + https://docs.langbot.dev/zh/api-reference/%E6%8F%92%E4%BB%B6/%E5%88%A0%E9%99%A4%E6%8F%92%E4%BB%B6 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/models/llm/model_uuid/put - - - - + https://docs.langbot.dev/ja/api-reference/plugins/%E5%88%A0%E9%99%A4%E6%8F%92%E4%BB%B6 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/models/llm/model_uuid/test/post - - - - + https://docs.langbot.dev/en/api-reference/plugins/get-plugin-configuration + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/models/llm/model_uuid/test/post - - - - + https://docs.langbot.dev/zh/api-reference/%E6%8F%92%E4%BB%B6/%E8%8E%B7%E5%8F%96%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/models/llm/model_uuid/test/post - - - - + https://docs.langbot.dev/ja/api-reference/plugins/%E8%8E%B7%E5%8F%96%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/models/llm/post - - - - + https://docs.langbot.dev/en/api-reference/plugins/get-plugin-details + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/models/llm/post - - - - + https://docs.langbot.dev/zh/api-reference/%E6%8F%92%E4%BB%B6/%E8%8E%B7%E5%8F%96%E6%8F%92%E4%BB%B6%E8%AF%A6%E6%83%85 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/models/llm/post - - - - + https://docs.langbot.dev/ja/api-reference/plugins/%E8%8E%B7%E5%8F%96%E6%8F%92%E4%BB%B6%E8%AF%A6%E6%83%85 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/providers/get - - - - + https://docs.langbot.dev/en/api-reference/plugins/install-a-plugin-from-github + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/providers/get - - - - + https://docs.langbot.dev/zh/api-reference/%E6%8F%92%E4%BB%B6/%E4%BB%8E-github-%E5%AE%89%E8%A3%85%E6%8F%92%E4%BB%B6 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/providers/get - - - - + https://docs.langbot.dev/ja/api-reference/plugins/%E4%BB%8E-github-%E5%AE%89%E8%A3%85%E6%8F%92%E4%BB%B6 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/providers/post - - - - + https://docs.langbot.dev/en/api-reference/plugins/install-a-plugin-from-marketplace + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/providers/post - - - - + https://docs.langbot.dev/zh/api-reference/%E6%8F%92%E4%BB%B6/%E4%BB%8E-marketplace-%E5%AE%89%E8%A3%85%E6%8F%92%E4%BB%B6 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/providers/post - - - - + https://docs.langbot.dev/ja/api-reference/plugins/%E4%BB%8E-marketplace-%E5%AE%89%E8%A3%85%E6%8F%92%E4%BB%B6 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/providers/provider_uuid/delete - - - - + https://docs.langbot.dev/en/api-reference/plugins/list-installed-plugins + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/providers/provider_uuid/delete - - - - + https://docs.langbot.dev/zh/api-reference/%E6%8F%92%E4%BB%B6/%E8%8E%B7%E5%8F%96%E5%B7%B2%E5%AE%89%E8%A3%85%E6%8F%92%E4%BB%B6%E5%88%97%E8%A1%A8 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/providers/provider_uuid/delete - - - - + https://docs.langbot.dev/ja/api-reference/plugins/%E8%8E%B7%E5%8F%96%E5%B7%B2%E5%AE%89%E8%A3%85%E6%8F%92%E4%BB%B6%E5%88%97%E8%A1%A8 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/providers/provider_uuid/get - - - - + https://docs.langbot.dev/en/api-reference/plugins/update-plugin-configuration + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/providers/provider_uuid/get - - - - + https://docs.langbot.dev/zh/api-reference/%E6%8F%92%E4%BB%B6/%E6%9B%B4%E6%96%B0%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/providers/provider_uuid/get - - - - + https://docs.langbot.dev/ja/api-reference/plugins/%E6%9B%B4%E6%96%B0%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE + + + + - https://docs.langbot.dev/en/api-reference/api/v1/provider/providers/provider_uuid/put - - - - + https://docs.langbot.dev/en/api-reference/plugins/upgrade-a-plugin + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/provider/providers/provider_uuid/put - - - - + https://docs.langbot.dev/zh/api-reference/%E6%8F%92%E4%BB%B6/%E5%8D%87%E7%BA%A7%E6%8F%92%E4%BB%B6 + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/provider/providers/provider_uuid/put - - - - + https://docs.langbot.dev/ja/api-reference/plugins/%E5%8D%87%E7%BA%A7%E6%8F%92%E4%BB%B6 + + + + - https://docs.langbot.dev/en/api-reference/api/v1/system/info/get - - - - + https://docs.langbot.dev/en/api-reference/system/get-system-information + + + + - https://docs.langbot.dev/zh/api-reference/api/v1/system/info/get - - - - + https://docs.langbot.dev/zh/api-reference/%E7%B3%BB%E7%BB%9F/%E8%8E%B7%E5%8F%96%E7%B3%BB%E7%BB%9F%E4%BF%A1%E6%81%AF + + + + - https://docs.langbot.dev/ja/api-reference/api/v1/system/info/get - - - - + https://docs.langbot.dev/ja/api-reference/system/%E8%8E%B7%E5%8F%96%E7%B3%BB%E7%BB%9F%E4%BF%A1%E6%81%AF + + + + - https://docs.langbot.dev/en/api-reference/getToolDetail - - - - + https://docs.langbot.dev/en/api-reference/tools/get-tool-detail + + + + - https://docs.langbot.dev/zh/api-reference/getToolDetail - - - - + https://docs.langbot.dev/zh/api-reference/%E5%B7%A5%E5%85%B7/%E8%8E%B7%E5%8F%96%E5%B7%A5%E5%85%B7%E8%AF%A6%E6%83%85 + + + + - https://docs.langbot.dev/ja/api-reference/getToolDetail - - - - + https://docs.langbot.dev/ja/api-reference/%E3%83%84%E3%83%BC%E3%83%AB/%E3%83%84%E3%83%BC%E3%83%AB%E8%A9%B3%E7%B4%B0%E3%82%92%E5%8F%96%E5%BE%97 + + + + - https://docs.langbot.dev/en/api-reference/listTools - - - - + https://docs.langbot.dev/en/api-reference/tools/list-all-available-tools + + + + - https://docs.langbot.dev/zh/api-reference/listTools - - - - + https://docs.langbot.dev/zh/api-reference/%E5%B7%A5%E5%85%B7/%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E5%8F%AF%E7%94%A8%E5%B7%A5%E5%85%B7 + + + + - https://docs.langbot.dev/ja/api-reference/listTools - - - - + https://docs.langbot.dev/ja/api-reference/%E3%83%84%E3%83%BC%E3%83%AB/%E5%88%A9%E7%94%A8%E5%8F%AF%E8%83%BD%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB%E4%B8%80%E8%A6%A7%E3%82%92%E5%8F%96%E5%BE%97 + + + + https://docs.langbot.dev/en/articles diff --git a/tests/fixtures/legacy-sitemap-routes.txt b/tests/fixtures/legacy-sitemap-routes.txt new file mode 100644 index 000000000..839a98913 --- /dev/null +++ b/tests/fixtures/legacy-sitemap-routes.txt @@ -0,0 +1,480 @@ +/en/api-reference/bots/create-a-bot +/en/api-reference/bots/delete-a-bot +/en/api-reference/bots/get-a-bot +/en/api-reference/bots/get-bot-event-logs +/en/api-reference/bots/list-all-bots +/en/api-reference/bots/send-a-message-through-a-bot +/en/api-reference/bots/update-a-bot +/en/api-reference/embedding-models/create-an-embedding-model +/en/api-reference/embedding-models/delete-an-embedding-model +/en/api-reference/embedding-models/get-an-embedding-model +/en/api-reference/embedding-models/list-all-embedding-models +/en/api-reference/embedding-models/test-an-embedding-model +/en/api-reference/embedding-models/update-an-embedding-model +/en/api-reference/files/upload-a-document +/en/api-reference/files/upload-an-image +/en/api-reference/knowledge-bases/add-a-file-to-a-knowledge-base +/en/api-reference/knowledge-bases/create-a-knowledge-base +/en/api-reference/knowledge-bases/delete-a-knowledge-base +/en/api-reference/knowledge-bases/get-a-knowledge-base +/en/api-reference/knowledge-bases/list-all-knowledge-bases +/en/api-reference/knowledge-bases/list-knowledge-base-files +/en/api-reference/knowledge-bases/remove-a-file-from-a-knowledge-base +/en/api-reference/knowledge-bases/retrieve-from-a-knowledge-base +/en/api-reference/knowledge-bases/update-a-knowledge-base +/en/api-reference/knowledge-engines/get-the-knowledge-engine-creation-schema +/en/api-reference/knowledge-engines/get-the-knowledge-engine-retrieval-schema +/en/api-reference/knowledge-engines/list-available-knowledge-engines +/en/api-reference/llm-models/create-an-llm-model +/en/api-reference/llm-models/delete-an-llm-model +/en/api-reference/llm-models/get-an-llm-model +/en/api-reference/llm-models/list-all-llm-models +/en/api-reference/llm-models/test-an-llm-model +/en/api-reference/llm-models/update-an-llm-model +/en/api-reference/model-providers/create-a-model-provider +/en/api-reference/model-providers/delete-a-model-provider +/en/api-reference/model-providers/get-a-model-provider +/en/api-reference/model-providers/list-all-model-providers +/en/api-reference/model-providers/update-a-model-provider +/en/api-reference/parsers/list-available-parsers +/en/api-reference/pipelines/copy-a-pipeline +/en/api-reference/pipelines/create-a-pipeline +/en/api-reference/pipelines/delete-a-pipeline +/en/api-reference/pipelines/get-a-pipeline +/en/api-reference/pipelines/get-pipeline-extension-configuration +/en/api-reference/pipelines/get-pipeline-metadata +/en/api-reference/pipelines/list-all-pipelines +/en/api-reference/pipelines/update-a-pipeline +/en/api-reference/pipelines/update-pipeline-extension-configuration +/en/api-reference/plugins/delete-a-plugin +/en/api-reference/plugins/get-plugin-configuration +/en/api-reference/plugins/get-plugin-details +/en/api-reference/plugins/install-a-plugin-from-github +/en/api-reference/plugins/install-a-plugin-from-marketplace +/en/api-reference/plugins/list-installed-plugins +/en/api-reference/plugins/update-plugin-configuration +/en/api-reference/plugins/upgrade-a-plugin +/en/api-reference/system/get-system-information +/en/api-reference/tools/get-tool-detail +/en/api-reference/tools/list-all-available-tools +/en/articles +/en/articles/connect-deepseek-to-wechat +/en/articles/deploy-ai-bot-in-5-minutes +/en/articles/dify-agent-discord-telegram-slack +/en/articles/dify-langbot-rag-knowledge-base +/en/articles/langbot-cloud-multi-user-workspaces +/en/articles/langbot-plugin-system-deep-dive +/en/articles/langbot-v4100-sandbox-skills +/en/articles/langbot-v490-rag-plugin-architecture +/en/articles/langflow-drag-and-drop-ai-bot +/en/articles/langtars-remote-pc-control-dify-n8n +/en/articles/n8n-multi-platform-ai-chatbot +/en/articles/welcome +/en/deploy/command +/en/deploy/langbot/docker +/en/deploy/langbot/kubernetes +/en/deploy/langbot/manual +/en/deploy/langbot/one-click/1panel +/en/deploy/langbot/one-click/bt +/en/deploy/langbot/package +/en/deploy/settings +/en/deploy/update +/en/develop/agent-context +/en/develop/comp-arch +/en/develop/dev-config +/en/develop/plugin-runtime +/en/insight/community +/en/insight/data-collection-policy +/en/insight/features +/en/insight/guide +/en/insight/platform-features +/en/insight/troubleshooting +/en/plugin/compatibility +/en/plugin/dev/apis/common +/en/plugin/dev/apis/messages +/en/plugin/dev/apis/pipeline-events +/en/plugin/dev/apis/tech-details +/en/plugin/dev/basic-info +/en/plugin/dev/components/add +/en/plugin/dev/components/command +/en/plugin/dev/components/event-listener +/en/plugin/dev/components/knowledge-engine +/en/plugin/dev/components/knowledge-retriever +/en/plugin/dev/components/page +/en/plugin/dev/components/parser +/en/plugin/dev/components/tool +/en/plugin/dev/directory-structure +/en/plugin/dev/migration +/en/plugin/dev/publish/github +/en/plugin/dev/publish/market +/en/plugin/dev/style +/en/plugin/dev/tutor +/en/plugin/plugin-intro +/en/tags/readme +/en/tags/webhook +/en/usage/knowledge/readme +/en/usage/mcp/readme +/en/usage/models/readme +/en/usage/pipelines/coze +/en/usage/pipelines/deerflow +/en/usage/pipelines/dify +/en/usage/pipelines/langflow +/en/usage/pipelines/n8n +/en/usage/pipelines/readme +/en/usage/pipelines/weknora +/en/usage/platforms/dingtalk +/en/usage/platforms/discord +/en/usage/platforms/http-bot +/en/usage/platforms/kook +/en/usage/platforms/lark +/en/usage/platforms/line +/en/usage/platforms/qq/aiocqhttp/lagrange +/en/usage/platforms/qq/aiocqhttp/llonebot +/en/usage/platforms/qq/aiocqhttp/napcat +/en/usage/platforms/qq/official_webhook +/en/usage/platforms/readme +/en/usage/platforms/satori/llonebot +/en/usage/platforms/slack +/en/usage/platforms/telegram +/en/usage/platforms/webpage +/en/usage/platforms/wechat/weixin +/en/usage/platforms/wecom/wecom +/en/usage/platforms/wecom/wecombot +/en/usage/platforms/wecom/wecomcs +/en/usage/platforms/wxoa +/en/usage/sandbox/config +/en/usage/sandbox/readme +/en/usage/sandbox/runtime-relationships +/en/usage/skills/readme +/en/workshop/302ai-integration +/en/workshop/impl-platform-adapter +/en/workshop/mcp-details +/en/workshop/network-details +/en/workshop/newapi-integration +/en/workshop/ppio-integration +/en/workshop/production/proxy-and-ssl +/ja/api-reference/bots/创建机器人 +/ja/api-reference/bots/删除机器人 +/ja/api-reference/bots/更新机器人 +/ja/api-reference/bots/获取单个机器人 +/ja/api-reference/bots/获取所有机器人 +/ja/api-reference/bots/获取机器人事件日志 +/ja/api-reference/bots/通过机器人发送消息 +/ja/api-reference/embedding-models/创建向量模型 +/ja/api-reference/embedding-models/删除向量模型 +/ja/api-reference/embedding-models/更新向量模型 +/ja/api-reference/embedding-models/测试向量模型 +/ja/api-reference/embedding-models/获取单个向量模型 +/ja/api-reference/embedding-models/获取所有向量模型 +/ja/api-reference/files/上传图片 +/ja/api-reference/files/上传文档 +/ja/api-reference/knowledge-bases/从知识库删除文件 +/ja/api-reference/knowledge-bases/创建知识库 +/ja/api-reference/knowledge-bases/删除知识库 +/ja/api-reference/knowledge-bases/将文件存入知识库 +/ja/api-reference/knowledge-bases/更新知识库 +/ja/api-reference/knowledge-bases/检索知识库 +/ja/api-reference/knowledge-bases/获取单个知识库 +/ja/api-reference/knowledge-bases/获取所有知识库 +/ja/api-reference/knowledge-bases/获取知识库文件列表 +/ja/api-reference/knowledge-engines/获取可用知识引擎列表 +/ja/api-reference/knowledge-engines/获取知识引擎创建配置模式 +/ja/api-reference/knowledge-engines/获取知识引擎检索配置模式 +/ja/api-reference/llm-models/创建-llm-模型 +/ja/api-reference/llm-models/删除-llm-模型 +/ja/api-reference/llm-models/更新-llm-模型 +/ja/api-reference/llm-models/测试-llm-模型 +/ja/api-reference/llm-models/获取单个-llm-模型 +/ja/api-reference/llm-models/获取所有-llm-模型 +/ja/api-reference/model-providers/创建供应商 +/ja/api-reference/model-providers/删除供应商 +/ja/api-reference/model-providers/更新供应商 +/ja/api-reference/model-providers/获取单个供应商 +/ja/api-reference/model-providers/获取所有供应商 +/ja/api-reference/parsers/获取可用解析器列表 +/ja/api-reference/pipelines/创建流水线 +/ja/api-reference/pipelines/删除流水线 +/ja/api-reference/pipelines/复制流水线 +/ja/api-reference/pipelines/更新流水线 +/ja/api-reference/pipelines/更新流水线扩展配置 +/ja/api-reference/pipelines/获取单个流水线 +/ja/api-reference/pipelines/获取所有流水线 +/ja/api-reference/pipelines/获取流水线元数据 +/ja/api-reference/pipelines/获取流水线扩展配置 +/ja/api-reference/plugins/从-github-安装插件 +/ja/api-reference/plugins/从-marketplace-安装插件 +/ja/api-reference/plugins/删除插件 +/ja/api-reference/plugins/升级插件 +/ja/api-reference/plugins/更新插件配置 +/ja/api-reference/plugins/获取已安装插件列表 +/ja/api-reference/plugins/获取插件详情 +/ja/api-reference/plugins/获取插件配置 +/ja/api-reference/system/获取系统信息 +/ja/api-reference/ツール/ツール詳細を取得 +/ja/api-reference/ツール/利用可能なツール一覧を取得 +/ja/articles +/ja/articles/connect-deepseek-to-wechat +/ja/articles/deploy-ai-bot-in-5-minutes +/ja/articles/dify-agent-discord-telegram-slack +/ja/articles/dify-langbot-rag-knowledge-base +/ja/articles/langbot-cloud-multi-user-workspaces +/ja/articles/langbot-plugin-system-deep-dive +/ja/articles/langbot-v4100-sandbox-skills +/ja/articles/langbot-v490-rag-plugin-architecture +/ja/articles/langflow-drag-and-drop-ai-bot +/ja/articles/langtars-remote-pc-control-dify-n8n +/ja/articles/n8n-multi-platform-ai-chatbot +/ja/articles/welcome +/ja/deploy/command +/ja/deploy/langbot/docker +/ja/deploy/langbot/kubernetes +/ja/deploy/langbot/manual +/ja/deploy/langbot/one-click/1panel +/ja/deploy/langbot/one-click/bt +/ja/deploy/langbot/package +/ja/deploy/settings +/ja/deploy/update +/ja/develop/agent-context +/ja/develop/comp-arch +/ja/develop/dev-config +/ja/develop/plugin-runtime +/ja/insight/community +/ja/insight/data-collection-policy +/ja/insight/features +/ja/insight/guide +/ja/insight/platform-features +/ja/insight/troubleshooting +/ja/plugin/compatibility +/ja/plugin/dev/apis/common +/ja/plugin/dev/apis/messages +/ja/plugin/dev/apis/pipeline-events +/ja/plugin/dev/apis/tech-details +/ja/plugin/dev/basic-info +/ja/plugin/dev/components/add +/ja/plugin/dev/components/command +/ja/plugin/dev/components/event-listener +/ja/plugin/dev/components/knowledge-engine +/ja/plugin/dev/components/knowledge-retriever +/ja/plugin/dev/components/page +/ja/plugin/dev/components/parser +/ja/plugin/dev/components/tool +/ja/plugin/dev/directory-structure +/ja/plugin/dev/migration +/ja/plugin/dev/publish/github +/ja/plugin/dev/publish/market +/ja/plugin/dev/style +/ja/plugin/dev/tutor +/ja/plugin/plugin-intro +/ja/tags/readme +/ja/tags/webhook +/ja/usage/knowledge/readme +/ja/usage/mcp/readme +/ja/usage/models/readme +/ja/usage/pipelines/coze +/ja/usage/pipelines/deerflow +/ja/usage/pipelines/dify +/ja/usage/pipelines/langflow +/ja/usage/pipelines/n8n +/ja/usage/pipelines/readme +/ja/usage/pipelines/weknora +/ja/usage/platforms/dingtalk +/ja/usage/platforms/discord +/ja/usage/platforms/http-bot +/ja/usage/platforms/kook +/ja/usage/platforms/lark +/ja/usage/platforms/line +/ja/usage/platforms/qq/aiocqhttp/lagrange +/ja/usage/platforms/qq/aiocqhttp/llonebot +/ja/usage/platforms/qq/aiocqhttp/napcat +/ja/usage/platforms/qq/official_webhook +/ja/usage/platforms/readme +/ja/usage/platforms/satori/llonebot +/ja/usage/platforms/slack +/ja/usage/platforms/telegram +/ja/usage/platforms/webpage +/ja/usage/platforms/wechat/weixin +/ja/usage/platforms/wecom/wecom +/ja/usage/platforms/wecom/wecombot +/ja/usage/platforms/wecom/wecomcs +/ja/usage/platforms/wxoa +/ja/usage/sandbox/config +/ja/usage/sandbox/readme +/ja/usage/sandbox/runtime-relationships +/ja/usage/skills/readme +/ja/workshop/302ai-integration +/ja/workshop/impl-platform-adapter +/ja/workshop/mcp-details +/ja/workshop/network-details +/ja/workshop/newapi-integration +/ja/workshop/ppio-integration +/ja/workshop/production/proxy-and-ssl +/scripts/README-blog-articles +/zh/api-reference/向量模型/创建向量模型 +/zh/api-reference/向量模型/删除向量模型 +/zh/api-reference/向量模型/更新向量模型 +/zh/api-reference/向量模型/测试向量模型 +/zh/api-reference/向量模型/获取单个向量模型 +/zh/api-reference/向量模型/获取所有向量模型 +/zh/api-reference/大语言模型/创建-llm-模型 +/zh/api-reference/大语言模型/删除-llm-模型 +/zh/api-reference/大语言模型/更新-llm-模型 +/zh/api-reference/大语言模型/测试-llm-模型 +/zh/api-reference/大语言模型/获取单个-llm-模型 +/zh/api-reference/大语言模型/获取所有-llm-模型 +/zh/api-reference/工具/获取工具详情 +/zh/api-reference/工具/获取所有可用工具 +/zh/api-reference/插件/从-github-安装插件 +/zh/api-reference/插件/从-marketplace-安装插件 +/zh/api-reference/插件/删除插件 +/zh/api-reference/插件/升级插件 +/zh/api-reference/插件/更新插件配置 +/zh/api-reference/插件/获取已安装插件列表 +/zh/api-reference/插件/获取插件详情 +/zh/api-reference/插件/获取插件配置 +/zh/api-reference/文件/上传图片 +/zh/api-reference/文件/上传文档 +/zh/api-reference/机器人/创建机器人 +/zh/api-reference/机器人/删除机器人 +/zh/api-reference/机器人/更新机器人 +/zh/api-reference/机器人/获取单个机器人 +/zh/api-reference/机器人/获取所有机器人 +/zh/api-reference/机器人/获取机器人事件日志 +/zh/api-reference/机器人/通过机器人发送消息 +/zh/api-reference/模型供应商/创建供应商 +/zh/api-reference/模型供应商/删除供应商 +/zh/api-reference/模型供应商/更新供应商 +/zh/api-reference/模型供应商/获取单个供应商 +/zh/api-reference/模型供应商/获取所有供应商 +/zh/api-reference/流水线/创建流水线 +/zh/api-reference/流水线/删除流水线 +/zh/api-reference/流水线/复制流水线 +/zh/api-reference/流水线/更新流水线 +/zh/api-reference/流水线/更新流水线扩展配置 +/zh/api-reference/流水线/获取单个流水线 +/zh/api-reference/流水线/获取所有流水线 +/zh/api-reference/流水线/获取流水线元数据 +/zh/api-reference/流水线/获取流水线扩展配置 +/zh/api-reference/知识库/从知识库删除文件 +/zh/api-reference/知识库/创建知识库 +/zh/api-reference/知识库/删除知识库 +/zh/api-reference/知识库/将文件存入知识库 +/zh/api-reference/知识库/更新知识库 +/zh/api-reference/知识库/检索知识库 +/zh/api-reference/知识库/获取单个知识库 +/zh/api-reference/知识库/获取所有知识库 +/zh/api-reference/知识库/获取知识库文件列表 +/zh/api-reference/知识引擎/获取可用知识引擎列表 +/zh/api-reference/知识引擎/获取知识引擎创建配置模式 +/zh/api-reference/知识引擎/获取知识引擎检索配置模式 +/zh/api-reference/系统/获取系统信息 +/zh/api-reference/解析器/获取可用解析器列表 +/zh/articles +/zh/articles/connect-deepseek-to-wechat +/zh/articles/deploy-ai-bot-in-5-minutes +/zh/articles/dify-agent-discord-telegram-slack +/zh/articles/dify-langbot-rag-knowledge-base +/zh/articles/langbot-cloud-multi-user-workspaces +/zh/articles/langbot-plugin-system-deep-dive +/zh/articles/langbot-v4100-sandbox-skills +/zh/articles/langbot-v490-rag-plugin-architecture +/zh/articles/langflow-drag-and-drop-ai-bot +/zh/articles/langtars-remote-pc-control-dify-n8n +/zh/articles/n8n-multi-platform-ai-chatbot +/zh/articles/welcome +/zh/deploy/command +/zh/deploy/langbot/docker +/zh/deploy/langbot/kubernetes +/zh/deploy/langbot/manual +/zh/deploy/langbot/one-click/1panel +/zh/deploy/langbot/one-click/bt +/zh/deploy/langbot/package +/zh/deploy/settings +/zh/deploy/update +/zh/develop/adapter/discord/README +/zh/develop/adapter/discord/api_reference +/zh/develop/adapter/discord/design +/zh/develop/adapter/discord/quick_start +/zh/develop/adapter/discord/troubleshooting +/zh/develop/agent-context +/zh/develop/comp-arch +/zh/develop/dev-config +/zh/develop/plugin-runtime +/zh/insight/community +/zh/insight/data-collection-policy +/zh/insight/features +/zh/insight/guide +/zh/insight/platform-features +/zh/insight/troubleshooting +/zh/plugin/compatibility +/zh/plugin/dev/apis/common +/zh/plugin/dev/apis/messages +/zh/plugin/dev/apis/pipeline-events +/zh/plugin/dev/apis/tech-details +/zh/plugin/dev/basic-info +/zh/plugin/dev/components/add +/zh/plugin/dev/components/command +/zh/plugin/dev/components/event-listener +/zh/plugin/dev/components/knowledge-engine +/zh/plugin/dev/components/knowledge-retriever +/zh/plugin/dev/components/page +/zh/plugin/dev/components/parser +/zh/plugin/dev/components/tool +/zh/plugin/dev/directory-structure +/zh/plugin/dev/migration +/zh/plugin/dev/publish/github +/zh/plugin/dev/publish/market +/zh/plugin/dev/style +/zh/plugin/dev/tutor +/zh/plugin/plugin-intro +/zh/tags/readme +/zh/tags/webhook +/zh/tob +/zh/tob/contact +/zh/tob/platform +/zh/tob/provider +/zh/usage/knowledge/readme +/zh/usage/mcp/readme +/zh/usage/models/readme +/zh/usage/pipelines/coze +/zh/usage/pipelines/deerflow +/zh/usage/pipelines/dify +/zh/usage/pipelines/langflow +/zh/usage/pipelines/n8n +/zh/usage/pipelines/readme +/zh/usage/pipelines/tbox +/zh/usage/pipelines/weknora +/zh/usage/platforms/dingtalk +/zh/usage/platforms/discord +/zh/usage/platforms/http-bot +/zh/usage/platforms/kook +/zh/usage/platforms/lark +/zh/usage/platforms/line +/zh/usage/platforms/qq/aiocqhttp/lagrange +/zh/usage/platforms/qq/aiocqhttp/llonebot +/zh/usage/platforms/qq/aiocqhttp/napcat +/zh/usage/platforms/qq/official +/zh/usage/platforms/qq/official_webhook +/zh/usage/platforms/readme +/zh/usage/platforms/satori/llonebot +/zh/usage/platforms/slack +/zh/usage/platforms/telegram +/zh/usage/platforms/webpage +/zh/usage/platforms/wechat/wechatpad +/zh/usage/platforms/wechat/weixin +/zh/usage/platforms/wecom/wecom +/zh/usage/platforms/wecom/wecombot +/zh/usage/platforms/wecom/wecomcs +/zh/usage/platforms/wxoa +/zh/usage/sandbox/config +/zh/usage/sandbox/readme +/zh/usage/sandbox/runtime-relationships +/zh/usage/skills/readme +/zh/workshop/302ai-integration +/zh/workshop/impl-platform-adapter +/zh/workshop/mcp-details +/zh/workshop/network-details +/zh/workshop/newapi-integration +/zh/workshop/ppio-integration +/zh/workshop/production/proxy-and-ssl +/zh/workshop/shengsuanyun-integration +/zh/workshop/tokenpony-integration diff --git a/tests/fumapress-migration.test.mjs b/tests/fumapress-migration.test.mjs index 087e2a4d8..aa37904d8 100644 --- a/tests/fumapress-migration.test.mjs +++ b/tests/fumapress-migration.test.mjs @@ -144,14 +144,15 @@ test("canonical MDX and nested OpenAPI sources are discovered", async () => { test("Cloudflare redirects preserve all Mintlify routes and add root", async () => { const docs = JSON.parse(await readFile(path.join(root, "docs.json"), "utf8")); - const spec = JSON.parse(await readFile(path.join(root, "openapi/service-api-en.json"), "utf8")); - const lines = renderCloudflareRedirects(docs, spec).trim().split("\n"); - assert.equal(lines.length, docs.redirects.length + 1); + const lines = renderCloudflareRedirects(docs).trim().split("\n"); + assert.equal(lines.length, docs.redirects.length + 3); assert.equal(lines[0], "/ /en/insight/guide 302"); assert.ok(lines.includes("/README_EN /en/insight/guide 308")); + assert.ok(lines.includes("/zh/develop/adapter/discord /zh/develop/adapter/discord/README 308")); + assert.ok(lines.includes("/scripts/README-blog-articles /en/articles 308")); assert.ok(lines.some((line) => line.startsWith("/en/deploy/platforms/* /en/usage/platforms/:splat "))); - assert.ok(lines.includes("/en/api-reference/system/获取系统信息 /en/api-reference/api/v1/system/info/get 308")); - assert.ok(lines.includes("/en/api-reference/model-providers/创建供应商 /en/api-reference/api/v1/provider/providers/post 308")); + assert.ok(lines.includes("/en/api-reference/system/获取系统信息 /en/api-reference/system/get-system-information 308")); + assert.ok(lines.includes("/en/api-reference/model-providers/创建供应商 /en/api-reference/model-providers/create-a-model-provider 308")); }); test("Fumapress config wires static localized docs, OpenAPI, and Mintlify support", async () => { @@ -165,6 +166,8 @@ test("Fumapress config wires static localized docs, OpenAPI, and Mintlify suppor assert.match(config, new RegExp(`input:[\\s\\S]*openapi/${filename}`)); assert.match(config, new RegExp(`staticSource\\(\\{\\s*baseDir:\\s*["']${locale}/api-reference["']`)); } + assert.match(config, /groupBy:\s*["']tag["']/); + assert.match(config, /legacyOpenApiSlug/); assert.match(config, /mintlifyPlugin\(/); assert.match(config, /openapiPlugin\(\{\s*server:\s*\w+OpenAPI\s*\}\)/); assert.match(config, /fumadocsMdx\(/); @@ -179,7 +182,7 @@ test("prebuild is deterministic and preserves local assets and SEO files", async assert.equal(first.documents, 302); assert.equal(first.fallbackDefaults, 0); assert.equal(first.localeOnlyDocuments, 14); - assert.equal(first.redirects, 102); + assert.equal(first.redirects, 104); assert.deepEqual(first.locales, ["en", "zh", "ja"]); await readFile(path.join(temp, "content/docs/insight/guide.mdx"), "utf8"); await readFile(path.join(temp, "content/docs/insight/guide.zh.mdx"), "utf8"); diff --git a/tests/fumapress-static-build.test.mjs b/tests/fumapress-static-build.test.mjs index 4d7047d70..29271a572 100644 --- a/tests/fumapress-static-build.test.mjs +++ b/tests/fumapress-static-build.test.mjs @@ -67,24 +67,36 @@ test("representative localized guides and canonical host are emitted", async () test("all locales emit the OpenAPI surface with endpoint semantics", async () => { const representatives = { - en: ["Get system information", "GET", "/api/v1/system/info"], - zh: ["获取系统信息", "GET", "/api/v1/system/info"], - ja: ["获取系统信息", "GET", "/api/v1/system/info"], + en: ["system/get-system-information", "Get system information", "GET", "/api/v1/system/info"], + zh: ["系统/获取系统信息", "获取系统信息", "GET", "/api/v1/system/info"], + ja: ["system/获取系统信息", "获取系统信息", "GET", "/api/v1/system/info"], }; const sitemap = await readFile(path.join(publicRoot, "sitemap.xml"), "utf8"); - for (const [locale, semantics] of Object.entries(representatives)) { + for (const [locale, [representativePath, ...semantics]] of Object.entries(representatives)) { const apiRoot = path.join(publicRoot, locale, "api-reference"); const routes = await collectHtmlRoutes(apiRoot); assert.ok(routes.length >= 50, `${locale} emitted only ${routes.length} API routes`); - const representative = path.join(apiRoot, "api/v1/system/info/get/index.html"); + const encodedRepresentativePath = representativePath.split("/").map((segment) => encodeURIComponent(segment)).join("/"); + const representative = path.join(apiRoot, encodedRepresentativePath, "index.html"); const html = await readFile(representative, "utf8"); for (const semantic of semantics) assert.ok(html.includes(semantic), `${locale} page is missing ${semantic}`); - assert.ok(sitemap.includes(`https://docs.langbot.dev/${locale}/api-reference/api/v1/system/info/get`)); + assert.ok(sitemap.includes(`https://docs.langbot.dev/${locale}/api-reference/${encodedRepresentativePath}`)); } }); +test("canonical sitemap routes match the legacy Mintlify directory structure", async () => { + const legacy = new Set((await readFile(path.join(root, "tests/fixtures/legacy-sitemap-routes.txt"), "utf8")) + .trim().split("\n").map((route) => route.replace(/\/$/, ""))); + // Mintlify accidentally indexed this repository maintenance note; preserve + // its URL as a redirect without treating it as public documentation. + legacy.delete("/scripts/README-blog-articles"); + const sitemap = await readFile(path.join(publicRoot, "sitemap.xml"), "utf8"); + const actual = new Set([...sitemap.matchAll(/https:\/\/docs\.langbot\.dev(\/[^<]+)<\/loc>/g)] + .map((match) => decodeURIComponent(match[1]).replace(/\/$/, ""))); + assert.deepEqual([...actual].sort(), [...legacy].sort()); +}); const locales = ["en", "zh", "ja"]; const hreflangByLocale = { en: "en", zh: "zh-CN", ja: "ja" }; @@ -120,11 +132,11 @@ function extractHeadLinks(html, rel) { })); } -test("rendered navbar uses each locale's docs.json labels and hrefs", async () => { +test("rendered navbar and documentation tree use each locale's docs.json labels", async () => { const expected = { - en: ["Home", "https://langbot.app/en", "Roadmap", "https://langbot.app/en/roadmap"], - zh: ["首页", "https://langbot.app/zh", "路线图", "https://langbot.app/zh/roadmap"], - ja: ["ホーム", "https://langbot.app/ja", "ロードマップ", "https://langbot.app/ja/roadmap"], + en: ["Home", "https://langbot.app/en", "Roadmap", "https://langbot.app/en/roadmap", "Guides", "Quick Start", "Installation", "Developers", "Articles", "API Reference"], + zh: ["首页", "https://langbot.app/zh", "路线图", "https://langbot.app/zh/roadmap", "指南", "快速开始", "安装部署", "开发者", "文章", "API 参考"], + ja: ["ホーム", "https://langbot.app/ja", "ロードマップ", "https://langbot.app/ja/roadmap", "ガイド", "クイックスタート", "インストール", "開発者", "記事", "API リファレンス"], }; for (const locale of locales) { const html = await readFile(path.join(publicRoot, locale, "insight/guide/index.html"), "utf8"); @@ -179,18 +191,27 @@ test("every page emits a canonical and reciprocal available hreflangs", async () const [, locale, ...suffixParts] = route.split("/"); const suffix = suffixParts.join("/"); - const expected = {}; - for (const candidate of locales) { - const candidateRoute = `/${candidate}/${suffix}`.replace(/\/$/, ""); - if (routes.has(candidateRoute)) expected[hreflangByLocale[candidate]] = `https://docs.langbot.dev${candidateRoute}`; - } - expected["x-default"] = expected.en ?? expected["zh-CN"] ?? expected.ja; const actual = Object.fromEntries( extractHeadLinks(html, "alternate") .filter((item) => item.hreflang) .map((item) => [item.hreflang, item.href]), ); - assert.deepEqual(actual, expected, route); + if (suffix.startsWith("api-reference/")) { + assert.deepEqual(Object.keys(actual).sort(), ["en", "ja", "x-default", "zh-CN"]); + assert.equal(actual["x-default"], actual.en); + for (const href of Object.values(actual)) { + const target = new URL(href).pathname.replace(/\/$/, ""); + assert.ok(routes.has(target), `${route} links to missing alternate ${target}`); + } + } else { + const expected = {}; + for (const candidate of locales) { + const candidateRoute = `/${candidate}/${suffix}`.replace(/\/$/, ""); + if (routes.has(candidateRoute)) expected[hreflangByLocale[candidate]] = `https://docs.langbot.dev${candidateRoute}`; + } + expected["x-default"] = expected.en ?? expected["zh-CN"] ?? expected.ja; + assert.deepEqual(actual, expected, route); + } } });