feat: finish the ai plugin (B18)

This commit is contained in:
LukeGus committed 2026-09-24 13:43:26 -05:00
1 parent 6b4d1432ab
commit 21937a6b02
193 files changed
+23429 -4244

No files matched your search

-1
View File
@@ -27,7 +27,6 @@ export function hostToSSHHost(h: Host): SSHHost {
enableTunnel: h.enableTunnel ?? false,
enableFileManager: h.enableFileManager ?? false,
enableTerminalToolbar: h.enableTerminalToolbar ?? true,
enableAiAssistant: h.enableAiAssistant ?? false,
enableWebUi: h.enableWebUi ?? false,
webUiConfig: (h.pluginSettings?.["web-endpoint"]?.webUiConfig as
SSHHost["webUiConfig"] | undefined) ?? { endpoints: [] },
+27
View File
@@ -20,6 +20,7 @@ import type { AxiosInstance } from "axios";
import { authApi, createRemoteOriginApiInstance } from "@/main-axios";
import { getBasePath } from "@/lib/base-path";
import { isElectron } from "@/lib/electron";
import { getDeviceId } from "@/lib/device-id";
import { websocketAuthProtocols } from "@/lib/ws-auth";
import {
buildOriginWsUrl,
@@ -75,6 +76,32 @@ export function createPluginApi(pluginId: string): AxiosInstance {
}) as AxiosInstance;
}
/**
* A raw fetch on this plugin's /plugin-api mount point, for a response the
* caller reads as a stream (server-sent events). axios buffers the whole
* body, so it cannot. Sends the same auth the shared client does.
*/
export function pluginFetch(
pluginId: string,
path: string,
init: RequestInit = {},
): Promise<Response> {
const base = (authApi.defaults.baseURL ?? "").replace(/\/+$/, "");
const headers = new Headers(init.headers);
const deviceId = getDeviceId();
if (deviceId) headers.set("X-Termix-Device-ID", deviceId);
if (isElectron()) {
headers.set("X-Electron-App", "true");
const jwt = localStorage.getItem("jwt");
if (jwt) headers.set("Authorization", `Bearer ${jwt}`);
}
return fetch(`${base}${pluginApiPath(pluginId, path)}`, {
credentials: "include",
...init,
headers,
});
}
const remotePluginApis = new Map<string, AxiosInstance>();
/**