UNPKG

@gguf/claw

Version:

Multi-channel AI gateway with extensible messaging integrations

159 lines (155 loc) 4.33 kB
import { l as escapeRegExp } from "./utils-CP9YLh6M.js"; import { t as registerBrowserRoutes } from "./routes-DIQa_0pt.js"; import os from "node:os"; import { execFile } from "node:child_process"; import { promisify } from "node:util"; //#region src/infra/machine-name.ts const execFileAsync = promisify(execFile); let cachedPromise = null; async function tryScutil(key) { try { const { stdout } = await execFileAsync("/usr/sbin/scutil", ["--get", key], { timeout: 1e3, windowsHide: true }); const value = String(stdout ?? "").trim(); return value.length > 0 ? value : null; } catch { return null; } } function fallbackHostName() { return os.hostname().replace(/\.local$/i, "").trim() || "openclaw"; } async function getMachineDisplayName() { if (cachedPromise) return cachedPromise; cachedPromise = (async () => { if (process.env.VITEST || false) return fallbackHostName(); if (process.platform === "darwin") { const computerName = await tryScutil("ComputerName"); if (computerName) return computerName; const localHostName = await tryScutil("LocalHostName"); if (localHostName) return localHostName; } return fallbackHostName(); })(); return cachedPromise; } //#endregion //#region src/browser/routes/dispatcher.ts function compileRoute(path) { const paramNames = []; const parts = path.split("/").map((part) => { if (part.startsWith(":")) { const name = part.slice(1); paramNames.push(name); return "([^/]+)"; } return escapeRegExp(part); }); return { regex: new RegExp(`^${parts.join("/")}$`), paramNames }; } function createRegistry() { const routes = []; const register = (method) => (path, handler) => { const { regex, paramNames } = compileRoute(path); routes.push({ method, path, regex, paramNames, handler }); }; return { routes, router: { get: register("GET"), post: register("POST"), delete: register("DELETE") } }; } function normalizePath(path) { if (!path) return "/"; return path.startsWith("/") ? path : `/${path}`; } function createBrowserRouteDispatcher(ctx) { const registry = createRegistry(); registerBrowserRoutes(registry.router, ctx); return { dispatch: async (req) => { const method = req.method; const path = normalizePath(req.path); const query = req.query ?? {}; const body = req.body; const signal = req.signal; const match = registry.routes.find((route) => { if (route.method !== method) return false; return route.regex.test(path); }); if (!match) return { status: 404, body: { error: "Not Found" } }; const exec = match.regex.exec(path); const params = {}; if (exec) for (const [idx, name] of match.paramNames.entries()) { const value = exec[idx + 1]; if (typeof value === "string") params[name] = decodeURIComponent(value); } let status = 200; let payload = void 0; const res = { status(code) { status = code; return res; }, json(bodyValue) { payload = bodyValue; } }; try { await match.handler({ params, query, body, signal }, res); } catch (err) { return { status: 500, body: { error: String(err) } }; } return { status, body: payload }; } }; } //#endregion //#region src/node-host/with-timeout.ts async function withTimeout(work, timeoutMs, label) { const resolved = typeof timeoutMs === "number" && Number.isFinite(timeoutMs) ? Math.max(1, Math.floor(timeoutMs)) : void 0; if (!resolved) return await work(void 0); const abortCtrl = new AbortController(); const timeoutError = /* @__PURE__ */ new Error(`${label ?? "request"} timed out`); const timer = setTimeout(() => abortCtrl.abort(timeoutError), resolved); timer.unref?.(); let abortListener; const abortPromise = abortCtrl.signal.aborted ? Promise.reject(abortCtrl.signal.reason ?? timeoutError) : new Promise((_, reject) => { abortListener = () => reject(abortCtrl.signal.reason ?? timeoutError); abortCtrl.signal.addEventListener("abort", abortListener, { once: true }); }); try { return await Promise.race([work(abortCtrl.signal), abortPromise]); } finally { clearTimeout(timer); if (abortListener) abortCtrl.signal.removeEventListener("abort", abortListener); } } //#endregion export { createBrowserRouteDispatcher as n, getMachineDisplayName as r, withTimeout as t };