2026-05-08 15:31:52 +00:00
|
|
|
import type {
|
2026-07-13 13:11:46 +08:00
|
|
|
ApiServicePayload,
|
2026-06-13 20:08:18 +08:00
|
|
|
AutomationsPayload,
|
2026-06-14 18:24:59 +08:00
|
|
|
AutomationUpdatePayload,
|
2026-07-13 13:11:46 +08:00
|
|
|
ChannelConfigurePayload,
|
|
|
|
|
ChannelConnectPayload,
|
|
|
|
|
ChannelValidationPayload,
|
2026-05-08 15:31:52 +00:00
|
|
|
ChatSummary,
|
2026-05-22 22:25:12 +08:00
|
|
|
CliAppsPayload,
|
2026-06-06 19:49:33 +08:00
|
|
|
FilePreviewPayload,
|
2026-05-19 22:42:38 +08:00
|
|
|
ImageGenerationSettingsUpdate,
|
2026-05-24 13:38:37 +08:00
|
|
|
McpPresetsPayload,
|
2026-07-03 18:17:52 +08:00
|
|
|
NanobotFeaturesPayload,
|
2026-05-24 13:38:37 +08:00
|
|
|
ModelConfigurationCreate,
|
2026-05-29 03:42:53 +08:00
|
|
|
ModelConfigurationUpdate,
|
|
|
|
|
NetworkSafetySettingsUpdate,
|
2026-07-13 13:11:46 +08:00
|
|
|
PairingPayload,
|
2026-05-30 23:45:26 +08:00
|
|
|
ProviderModelsPayload,
|
2026-05-08 15:31:52 +00:00
|
|
|
ProviderSettingsUpdate,
|
2026-06-11 19:11:37 +08:00
|
|
|
SessionDeleteResult,
|
2026-06-06 19:49:33 +08:00
|
|
|
SessionAutomationsPayload,
|
2026-05-08 15:31:52 +00:00
|
|
|
SettingsPayload,
|
|
|
|
|
SettingsUpdate,
|
2026-05-19 22:42:38 +08:00
|
|
|
SidebarStatePayload,
|
2026-06-06 19:49:33 +08:00
|
|
|
SkillDetail,
|
|
|
|
|
SkillsPayload,
|
2026-05-08 15:31:52 +00:00
|
|
|
SlashCommand,
|
2026-07-07 14:01:07 +08:00
|
|
|
SlashCommandLifecycle,
|
2026-06-09 01:08:49 +08:00
|
|
|
TranscriptionSettingsUpdate,
|
2026-05-09 06:48:26 +00:00
|
|
|
WebSearchSettingsUpdate,
|
2026-05-29 03:42:53 +08:00
|
|
|
WorkspacesPayload,
|
2026-05-16 01:14:11 +08:00
|
|
|
WebuiThreadPersistedPayload,
|
2026-05-29 03:42:53 +08:00
|
|
|
WorkspaceScopePayload,
|
2026-05-08 15:31:52 +00:00
|
|
|
} from "./types";
|
2026-06-02 15:36:52 +08:00
|
|
|
import { fetchWithTimeout } from "./http";
|
|
|
|
|
|
|
|
|
|
const API_READ_TIMEOUT_MS = 20_000;
|
2026-07-07 14:01:07 +08:00
|
|
|
const SLASH_COMMAND_LIFECYCLES = new Set<SlashCommandLifecycle>([
|
|
|
|
|
"side_channel",
|
|
|
|
|
"finalize_active_turn",
|
|
|
|
|
"stop_active_turn",
|
|
|
|
|
"agent_turn",
|
|
|
|
|
"agent_turn_with_args",
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
function isSlashCommandLifecycle(value: unknown): value is SlashCommandLifecycle {
|
|
|
|
|
return (
|
|
|
|
|
typeof value === "string"
|
|
|
|
|
&& SLASH_COMMAND_LIFECYCLES.has(value as SlashCommandLifecycle)
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-07-13 13:11:46 +08:00
|
|
|
const CHANNEL_VALUES_HEADER = "X-Nanobot-Channel-Values";
|
|
|
|
|
const API_SERVICE_VALUES_HEADER = "X-Nanobot-API-Service-Values";
|
2026-04-18 18:51:53 +00:00
|
|
|
|
|
|
|
|
export class ApiError extends Error {
|
|
|
|
|
status: number;
|
|
|
|
|
constructor(status: number, message: string) {
|
|
|
|
|
super(message);
|
|
|
|
|
this.status = status;
|
|
|
|
|
this.name = "ApiError";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function request<T>(
|
|
|
|
|
url: string,
|
|
|
|
|
token: string,
|
|
|
|
|
init?: RequestInit,
|
2026-06-02 15:36:52 +08:00
|
|
|
timeoutMs: number = 0,
|
2026-04-18 18:51:53 +00:00
|
|
|
): Promise<T> {
|
2026-06-02 15:36:52 +08:00
|
|
|
const res = await fetchWithTimeout(
|
|
|
|
|
url,
|
|
|
|
|
{
|
|
|
|
|
...(init ?? {}),
|
|
|
|
|
headers: {
|
|
|
|
|
...(init?.headers ?? {}),
|
|
|
|
|
Authorization: `Bearer ${token}`,
|
|
|
|
|
},
|
|
|
|
|
credentials: "same-origin",
|
2026-04-18 18:51:53 +00:00
|
|
|
},
|
2026-06-02 15:36:52 +08:00
|
|
|
timeoutMs,
|
|
|
|
|
);
|
2026-04-18 18:51:53 +00:00
|
|
|
if (!res.ok) {
|
2026-05-29 14:14:56 +08:00
|
|
|
const text = typeof res.text === "function" ? (await res.text()).trim() : "";
|
|
|
|
|
throw new ApiError(res.status, text || `HTTP ${res.status}`);
|
2026-04-18 18:51:53 +00:00
|
|
|
}
|
2026-05-29 03:42:53 +08:00
|
|
|
const contentType = res.headers?.get?.("content-type") ?? "";
|
|
|
|
|
if (contentType && !contentType.toLowerCase().includes("application/json")) {
|
|
|
|
|
const text = typeof res.text === "function" ? await res.text() : "";
|
|
|
|
|
const isHtml = text.trimStart().toLowerCase().startsWith("<!doctype");
|
|
|
|
|
throw new ApiError(
|
|
|
|
|
res.status,
|
|
|
|
|
isHtml
|
|
|
|
|
? "Gateway returned WebUI HTML instead of JSON. Restart nanobot gateway and try again."
|
|
|
|
|
: "Gateway returned a non-JSON response.",
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-04-18 18:51:53 +00:00
|
|
|
return (await res.json()) as T;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-24 13:38:37 +08:00
|
|
|
function mcpValuesHeader(values: Record<string, unknown>): HeadersInit | undefined {
|
|
|
|
|
const payload: Record<string, unknown> = {};
|
|
|
|
|
Object.entries(values).forEach(([key, value]) => {
|
|
|
|
|
if (value === null || value === undefined) return;
|
|
|
|
|
if (typeof value === "string") {
|
|
|
|
|
const trimmed = value.trim();
|
|
|
|
|
if (trimmed) payload[key] = trimmed;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
payload[key] = value;
|
|
|
|
|
});
|
|
|
|
|
if (!Object.keys(payload).length) return undefined;
|
|
|
|
|
return { "X-Nanobot-MCP-Values": JSON.stringify(payload) };
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-15 15:14:24 +08:00
|
|
|
function automationValuesHeader(values: AutomationUpdatePayload): HeadersInit {
|
|
|
|
|
return { "X-Nanobot-Automation-Values": encodeURIComponent(JSON.stringify(values)) };
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-18 18:51:53 +00:00
|
|
|
function splitKey(key: string): { channel: string; chatId: string } {
|
|
|
|
|
const idx = key.indexOf(":");
|
|
|
|
|
if (idx === -1) return { channel: "", chatId: key };
|
|
|
|
|
return { channel: key.slice(0, idx), chatId: key.slice(idx + 1) };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function listSessions(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<ChatSummary[]> {
|
|
|
|
|
type Row = {
|
|
|
|
|
key: string;
|
|
|
|
|
created_at: string | null;
|
|
|
|
|
updated_at: string | null;
|
2026-05-06 14:15:36 +00:00
|
|
|
title?: string;
|
2026-04-18 18:51:53 +00:00
|
|
|
preview?: string;
|
2026-07-23 00:38:49 +08:00
|
|
|
model_preset?: string | null;
|
2026-05-19 22:42:38 +08:00
|
|
|
run_started_at?: number | null;
|
2026-05-29 03:42:53 +08:00
|
|
|
workspace_scope?: WorkspaceScopePayload | null;
|
2026-04-18 18:51:53 +00:00
|
|
|
};
|
|
|
|
|
const body = await request<{ sessions: Row[] }>(
|
|
|
|
|
`${base}/api/sessions`,
|
|
|
|
|
token,
|
2026-06-02 15:36:52 +08:00
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
2026-04-18 18:51:53 +00:00
|
|
|
);
|
|
|
|
|
return body.sessions.map((s) => ({
|
|
|
|
|
key: s.key,
|
|
|
|
|
...splitKey(s.key),
|
|
|
|
|
createdAt: s.created_at,
|
|
|
|
|
updatedAt: s.updated_at,
|
2026-05-06 14:15:36 +00:00
|
|
|
title: s.title ?? "",
|
2026-04-18 18:51:53 +00:00
|
|
|
preview: s.preview ?? "",
|
2026-07-23 00:38:49 +08:00
|
|
|
modelPreset: s.model_preset ?? null,
|
2026-05-19 22:42:38 +08:00
|
|
|
runStartedAt: s.run_started_at ?? null,
|
2026-05-29 03:42:53 +08:00
|
|
|
workspaceScope: s.workspace_scope ?? null,
|
2026-04-18 18:51:53 +00:00
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-16 01:14:11 +08:00
|
|
|
/** Disk-backed WebUI display thread snapshot (separate from agent session). */
|
2026-06-10 18:02:27 +08:00
|
|
|
export interface FetchWebuiThreadOptions {
|
|
|
|
|
limit?: number;
|
|
|
|
|
direction?: "latest";
|
|
|
|
|
before?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-16 01:14:11 +08:00
|
|
|
export async function fetchWebuiThread(
|
2026-04-18 18:51:53 +00:00
|
|
|
token: string,
|
|
|
|
|
key: string,
|
2026-06-10 18:02:27 +08:00
|
|
|
optionsOrBase?: FetchWebuiThreadOptions | string,
|
2026-04-18 18:51:53 +00:00
|
|
|
base: string = "",
|
2026-05-16 01:14:11 +08:00
|
|
|
): Promise<WebuiThreadPersistedPayload | null> {
|
2026-06-10 18:02:27 +08:00
|
|
|
const options = typeof optionsOrBase === "string" ? undefined : optionsOrBase;
|
|
|
|
|
const resolvedBase = typeof optionsOrBase === "string" ? optionsOrBase : base;
|
|
|
|
|
const params = new URLSearchParams();
|
|
|
|
|
if (options?.limit !== undefined) params.set("limit", String(options.limit));
|
|
|
|
|
if (options?.direction) params.set("direction", options.direction);
|
|
|
|
|
if (options?.before) params.set("before", options.before);
|
|
|
|
|
const query = params.toString();
|
|
|
|
|
const suffix = query ? `?${query}` : "";
|
|
|
|
|
const url = `${resolvedBase}/api/sessions/${encodeURIComponent(key)}/webui-thread${suffix}`;
|
2026-06-02 15:36:52 +08:00
|
|
|
const res = await fetchWithTimeout(url, {
|
2026-05-16 01:14:11 +08:00
|
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
|
|
|
credentials: "same-origin",
|
|
|
|
|
});
|
|
|
|
|
if (res.status === 404) return null;
|
|
|
|
|
if (!res.ok) throw new ApiError(res.status, `HTTP ${res.status}`);
|
|
|
|
|
return (await res.json()) as WebuiThreadPersistedPayload;
|
2026-04-18 18:51:53 +00:00
|
|
|
}
|
|
|
|
|
|
2026-06-06 19:49:33 +08:00
|
|
|
export async function fetchFilePreview(
|
|
|
|
|
token: string,
|
|
|
|
|
key: string,
|
|
|
|
|
path: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<FilePreviewPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("path", path);
|
|
|
|
|
return request<FilePreviewPayload>(
|
|
|
|
|
`${base}/api/sessions/${encodeURIComponent(key)}/file-preview?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-15 10:45:40 +08:00
|
|
|
export async function fetchFilePreviewAvailability(
|
|
|
|
|
token: string,
|
|
|
|
|
key: string,
|
|
|
|
|
path: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<boolean> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("path", path);
|
|
|
|
|
query.set("probe", "1");
|
|
|
|
|
const payload = await request<{ available?: boolean }>(
|
|
|
|
|
`${base}/api/sessions/${encodeURIComponent(key)}/file-preview?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
|
|
|
|
return payload.available !== false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-06 19:49:33 +08:00
|
|
|
export async function fetchSessionAutomations(
|
|
|
|
|
token: string,
|
|
|
|
|
key: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SessionAutomationsPayload> {
|
|
|
|
|
return request<SessionAutomationsPayload>(
|
|
|
|
|
`${base}/api/sessions/${encodeURIComponent(key)}/automations`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
2026-06-13 20:08:18 +08:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function fetchAutomations(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<AutomationsPayload> {
|
|
|
|
|
return request<AutomationsPayload>(
|
|
|
|
|
`${base}/api/webui/automations`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function runAutomationAction(
|
|
|
|
|
token: string,
|
|
|
|
|
action: "enable" | "disable" | "delete" | "run",
|
|
|
|
|
id: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<AutomationsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("id", id);
|
|
|
|
|
return request<AutomationsPayload>(
|
|
|
|
|
`${base}/api/webui/automations/${action}?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
2026-06-14 18:24:59 +08:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function updateAutomation(
|
|
|
|
|
token: string,
|
|
|
|
|
id: string,
|
|
|
|
|
values: AutomationUpdatePayload,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<AutomationsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("id", id);
|
|
|
|
|
return request<AutomationsPayload>(
|
|
|
|
|
`${base}/api/webui/automations/update?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
{
|
2026-06-15 15:14:24 +08:00
|
|
|
headers: automationValuesHeader(values),
|
2026-06-14 18:24:59 +08:00
|
|
|
},
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
2026-06-06 19:49:33 +08:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function fetchSkills(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SkillsPayload> {
|
|
|
|
|
return request<SkillsPayload>(
|
|
|
|
|
`${base}/api/webui/skills`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function fetchSkillDetail(
|
|
|
|
|
token: string,
|
|
|
|
|
name: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SkillDetail> {
|
|
|
|
|
return request<SkillDetail>(
|
|
|
|
|
`${base}/api/webui/skills/${encodeURIComponent(name)}`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-18 18:51:53 +00:00
|
|
|
export async function deleteSession(
|
|
|
|
|
token: string,
|
|
|
|
|
key: string,
|
2026-06-11 19:11:37 +08:00
|
|
|
optionsOrBase?: { deleteAutomations?: boolean } | string,
|
2026-04-18 18:51:53 +00:00
|
|
|
base: string = "",
|
2026-06-11 19:11:37 +08:00
|
|
|
): Promise<SessionDeleteResult> {
|
|
|
|
|
const options = typeof optionsOrBase === "string" ? undefined : optionsOrBase;
|
|
|
|
|
const resolvedBase = typeof optionsOrBase === "string" ? optionsOrBase : base;
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
if (options?.deleteAutomations) query.set("delete_automations", "true");
|
|
|
|
|
const suffix = query.toString() ? `?${query}` : "";
|
|
|
|
|
return request<SessionDeleteResult>(
|
|
|
|
|
`${resolvedBase}/api/sessions/${encodeURIComponent(key)}/delete${suffix}`,
|
2026-04-18 18:51:53 +00:00
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-04-25 18:05:06 +00:00
|
|
|
|
|
|
|
|
export async function fetchSettings(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SettingsPayload> {
|
2026-06-02 15:36:52 +08:00
|
|
|
return request<SettingsPayload>(
|
|
|
|
|
`${base}/api/settings`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
2026-04-25 18:05:06 +00:00
|
|
|
}
|
|
|
|
|
|
2026-06-06 19:49:33 +08:00
|
|
|
export async function fetchSettingsUsage(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<NonNullable<SettingsPayload["usage"]>> {
|
|
|
|
|
return request<NonNullable<SettingsPayload["usage"]>>(
|
|
|
|
|
`${base}/api/settings/usage`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-09 22:31:14 +08:00
|
|
|
export interface VersionCheckResult {
|
|
|
|
|
updateAvailable: {
|
|
|
|
|
currentVersion: string;
|
|
|
|
|
latestVersion: string;
|
|
|
|
|
pypiUrl?: string;
|
|
|
|
|
} | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function checkVersion(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<VersionCheckResult> {
|
|
|
|
|
return request<VersionCheckResult>(
|
|
|
|
|
`${base}/api/settings/version-check`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
10_000,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-29 03:42:53 +08:00
|
|
|
export async function fetchWorkspaces(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<WorkspacesPayload> {
|
2026-06-02 15:36:52 +08:00
|
|
|
return request<WorkspacesPayload>(
|
|
|
|
|
`${base}/api/workspaces`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
2026-05-29 03:42:53 +08:00
|
|
|
}
|
|
|
|
|
|
2026-05-22 22:25:12 +08:00
|
|
|
export async function fetchCliApps(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<CliAppsPayload> {
|
2026-06-02 15:36:52 +08:00
|
|
|
return request<CliAppsPayload>(
|
|
|
|
|
`${base}/api/settings/cli-apps`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
2026-05-22 22:25:12 +08:00
|
|
|
}
|
|
|
|
|
|
2026-06-13 13:26:49 +08:00
|
|
|
export async function fetchInstalledCliApps(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<CliAppsPayload> {
|
|
|
|
|
return request<CliAppsPayload>(
|
|
|
|
|
`${base}/api/settings/cli-apps?installed_only=1`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-03 18:17:52 +08:00
|
|
|
export async function fetchNanobotFeatures(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<NanobotFeaturesPayload> {
|
|
|
|
|
return request<NanobotFeaturesPayload>(
|
|
|
|
|
`${base}/api/settings/nanobot-features`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-13 13:11:46 +08:00
|
|
|
export async function fetchApiService(token: string, base: string = ""): Promise<ApiServicePayload> {
|
|
|
|
|
return request<ApiServicePayload>(`${base}/api/settings/api-service`, token);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function startApiService(
|
|
|
|
|
token: string,
|
|
|
|
|
values: { host: string; port: number; timeout: number; apiKey?: string },
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<ApiServicePayload> {
|
|
|
|
|
const query = new URLSearchParams({
|
|
|
|
|
host: values.host,
|
|
|
|
|
port: String(values.port),
|
|
|
|
|
timeout: String(values.timeout),
|
|
|
|
|
});
|
|
|
|
|
const headers = values.apiKey === undefined
|
|
|
|
|
? undefined
|
|
|
|
|
: { [API_SERVICE_VALUES_HEADER]: JSON.stringify({ api_key: values.apiKey }) };
|
|
|
|
|
return request<ApiServicePayload>(
|
|
|
|
|
`${base}/api/settings/api-service/start?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
{ headers },
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function stopApiService(token: string, base: string = ""): Promise<ApiServicePayload> {
|
|
|
|
|
return request<ApiServicePayload>(`${base}/api/settings/api-service/stop`, token);
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-03 18:17:52 +08:00
|
|
|
export async function enableNanobotFeature(
|
|
|
|
|
token: string,
|
|
|
|
|
name: string,
|
2026-07-13 13:11:46 +08:00
|
|
|
options: { instanceId?: string } = {},
|
2026-07-03 18:17:52 +08:00
|
|
|
base: string = "",
|
|
|
|
|
): Promise<NanobotFeaturesPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("name", name);
|
2026-07-13 13:11:46 +08:00
|
|
|
if (options.instanceId) query.set("instance_id", options.instanceId);
|
2026-07-03 18:17:52 +08:00
|
|
|
return request<NanobotFeaturesPayload>(
|
|
|
|
|
`${base}/api/settings/nanobot-features/enable?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function disableNanobotFeature(
|
|
|
|
|
token: string,
|
|
|
|
|
name: string,
|
2026-07-13 13:11:46 +08:00
|
|
|
options: { instanceId?: string } = {},
|
2026-07-03 18:17:52 +08:00
|
|
|
base: string = "",
|
|
|
|
|
): Promise<NanobotFeaturesPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("name", name);
|
2026-07-13 13:11:46 +08:00
|
|
|
if (options.instanceId) query.set("instance_id", options.instanceId);
|
2026-07-03 18:17:52 +08:00
|
|
|
return request<NanobotFeaturesPayload>(
|
|
|
|
|
`${base}/api/settings/nanobot-features/disable?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-13 13:11:46 +08:00
|
|
|
export async function fetchPairingRequests(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<PairingPayload> {
|
|
|
|
|
return request<PairingPayload>(
|
|
|
|
|
`${base}/api/settings/pairing`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function runPairingAction(
|
|
|
|
|
token: string,
|
|
|
|
|
action: "approve" | "deny",
|
|
|
|
|
code: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<PairingPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("code", code);
|
|
|
|
|
return request<PairingPayload>(
|
|
|
|
|
`${base}/api/settings/pairing/${action}?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function startChannelConnect(
|
|
|
|
|
token: string,
|
2026-07-19 23:30:49 +08:00
|
|
|
channel: string,
|
2026-07-13 13:11:46 +08:00
|
|
|
options: {
|
2026-07-19 23:30:49 +08:00
|
|
|
domain?: string;
|
2026-07-13 13:11:46 +08:00
|
|
|
instanceId?: string;
|
|
|
|
|
mode?: "replace" | "create";
|
|
|
|
|
force?: boolean;
|
|
|
|
|
} = {},
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<ChannelConnectPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
if (options.domain) query.set("domain", options.domain);
|
|
|
|
|
if (options.instanceId) query.set("instance_id", options.instanceId);
|
|
|
|
|
if (options.mode) query.set("mode", options.mode);
|
|
|
|
|
if (options.force) query.set("force", "true");
|
|
|
|
|
const suffix = query.toString();
|
|
|
|
|
return request<ChannelConnectPayload>(
|
|
|
|
|
`${base}/api/settings/channels/${channel}/connect/start${suffix ? `?${suffix}` : ""}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function pollChannelConnect(
|
|
|
|
|
token: string,
|
2026-07-19 23:30:49 +08:00
|
|
|
channel: string,
|
2026-07-13 13:11:46 +08:00
|
|
|
sessionId: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<ChannelConnectPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("session_id", sessionId);
|
|
|
|
|
return request<ChannelConnectPayload>(
|
|
|
|
|
`${base}/api/settings/channels/${channel}/connect/poll?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function cancelChannelConnect(
|
|
|
|
|
token: string,
|
2026-07-19 23:30:49 +08:00
|
|
|
channel: string,
|
2026-07-13 13:11:46 +08:00
|
|
|
sessionId: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<ChannelConnectPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("session_id", sessionId);
|
|
|
|
|
return request<ChannelConnectPayload>(
|
|
|
|
|
`${base}/api/settings/channels/${channel}/connect/cancel?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function configureChannel(
|
|
|
|
|
token: string,
|
|
|
|
|
name: string,
|
|
|
|
|
values: Record<string, string>,
|
|
|
|
|
options: { enable?: boolean; instanceId?: string } = {},
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<ChannelConfigurePayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("name", name);
|
|
|
|
|
if (options.enable !== undefined) query.set("enable", String(options.enable));
|
|
|
|
|
if (options.instanceId) query.set("instance_id", options.instanceId);
|
|
|
|
|
return request<ChannelConfigurePayload>(
|
|
|
|
|
`${base}/api/settings/channels/configure?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
{
|
|
|
|
|
headers: {
|
|
|
|
|
[CHANNEL_VALUES_HEADER]: JSON.stringify(values),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function validateChannel(
|
|
|
|
|
token: string,
|
|
|
|
|
name: string,
|
|
|
|
|
values: Record<string, string> = {},
|
|
|
|
|
options: { instanceId?: string } = {},
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<ChannelValidationPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("name", name);
|
|
|
|
|
if (options.instanceId) query.set("instance_id", options.instanceId);
|
|
|
|
|
return request<ChannelValidationPayload>(
|
|
|
|
|
`${base}/api/settings/channels/validate?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
{
|
|
|
|
|
headers: {
|
|
|
|
|
[CHANNEL_VALUES_HEADER]: JSON.stringify(values),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-22 22:25:12 +08:00
|
|
|
export async function runCliAppAction(
|
|
|
|
|
token: string,
|
|
|
|
|
action: "install" | "update" | "uninstall" | "test",
|
|
|
|
|
name: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<CliAppsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("name", name);
|
|
|
|
|
return request<CliAppsPayload>(`${base}/api/settings/cli-apps/${action}?${query}`, token);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-24 13:38:37 +08:00
|
|
|
export async function fetchMcpPresets(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<McpPresetsPayload> {
|
2026-06-02 15:36:52 +08:00
|
|
|
return request<McpPresetsPayload>(
|
|
|
|
|
`${base}/api/settings/mcp-presets`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
2026-05-24 13:38:37 +08:00
|
|
|
}
|
|
|
|
|
|
2026-05-30 23:45:26 +08:00
|
|
|
export async function fetchProviderModels(
|
|
|
|
|
token: string,
|
|
|
|
|
provider: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<ProviderModelsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("provider", provider);
|
|
|
|
|
return request<ProviderModelsPayload>(
|
|
|
|
|
`${base}/api/settings/provider-models?${query}`,
|
|
|
|
|
token,
|
2026-06-02 15:36:52 +08:00
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
2026-05-30 23:45:26 +08:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-24 13:38:37 +08:00
|
|
|
export async function runMcpPresetAction(
|
|
|
|
|
token: string,
|
|
|
|
|
action: "enable" | "remove" | "test",
|
|
|
|
|
name: string,
|
|
|
|
|
values: Record<string, string> = {},
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<McpPresetsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("name", name);
|
|
|
|
|
return request<McpPresetsPayload>(
|
|
|
|
|
`${base}/api/settings/mcp-presets/${action}?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
{ headers: mcpValuesHeader(values) },
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function saveCustomMcpServer(
|
|
|
|
|
token: string,
|
|
|
|
|
values: Record<string, string>,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<McpPresetsPayload> {
|
|
|
|
|
return request<McpPresetsPayload>(
|
|
|
|
|
`${base}/api/settings/mcp-presets/custom`,
|
|
|
|
|
token,
|
|
|
|
|
{ headers: mcpValuesHeader(values) },
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function importMcpConfig(
|
|
|
|
|
token: string,
|
|
|
|
|
config: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<McpPresetsPayload> {
|
|
|
|
|
return request<McpPresetsPayload>(
|
|
|
|
|
`${base}/api/settings/mcp-presets/import`,
|
|
|
|
|
token,
|
|
|
|
|
{ headers: mcpValuesHeader({ config }) },
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function updateMcpServerTools(
|
|
|
|
|
token: string,
|
|
|
|
|
name: string,
|
|
|
|
|
enabledTools: string[],
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<McpPresetsPayload> {
|
|
|
|
|
return request<McpPresetsPayload>(
|
|
|
|
|
`${base}/api/settings/mcp-presets/tools`,
|
|
|
|
|
token,
|
|
|
|
|
{ headers: mcpValuesHeader({ name, enabled_tools: enabledTools }) },
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-06 15:54:15 +00:00
|
|
|
export async function listSlashCommands(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SlashCommand[]> {
|
|
|
|
|
type Row = {
|
|
|
|
|
command: string;
|
|
|
|
|
title: string;
|
|
|
|
|
description: string;
|
|
|
|
|
icon: string;
|
|
|
|
|
arg_hint?: string;
|
2026-07-07 14:01:07 +08:00
|
|
|
lifecycle?: unknown;
|
|
|
|
|
accepts_args?: unknown;
|
2026-05-06 15:54:15 +00:00
|
|
|
};
|
2026-06-02 15:36:52 +08:00
|
|
|
const body = await request<{ commands: Row[] }>(
|
|
|
|
|
`${base}/api/commands`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
2026-05-08 09:40:15 +00:00
|
|
|
return body.commands
|
2026-07-07 14:01:07 +08:00
|
|
|
.flatMap((command) => {
|
|
|
|
|
if (!isSlashCommandLifecycle(command.lifecycle)) return [];
|
|
|
|
|
return [{
|
|
|
|
|
command: command.command,
|
|
|
|
|
title: command.title,
|
|
|
|
|
description: command.description,
|
|
|
|
|
icon: command.icon,
|
|
|
|
|
argHint: command.arg_hint ?? "",
|
|
|
|
|
lifecycle: command.lifecycle,
|
|
|
|
|
acceptsArgs: command.accepts_args === true,
|
|
|
|
|
}];
|
|
|
|
|
});
|
2026-05-06 15:54:15 +00:00
|
|
|
}
|
|
|
|
|
|
2026-05-19 22:42:38 +08:00
|
|
|
export async function fetchSidebarState(
|
|
|
|
|
token: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SidebarStatePayload> {
|
2026-06-02 15:36:52 +08:00
|
|
|
return request<SidebarStatePayload>(
|
|
|
|
|
`${base}/api/webui/sidebar-state`,
|
|
|
|
|
token,
|
|
|
|
|
undefined,
|
|
|
|
|
API_READ_TIMEOUT_MS,
|
|
|
|
|
);
|
2026-05-19 22:42:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function updateSidebarState(
|
|
|
|
|
token: string,
|
|
|
|
|
state: SidebarStatePayload,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SidebarStatePayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("state", JSON.stringify(state));
|
|
|
|
|
return request<SidebarStatePayload>(
|
|
|
|
|
`${base}/api/webui/sidebar-state/update?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-25 18:05:06 +00:00
|
|
|
export async function updateSettings(
|
|
|
|
|
token: string,
|
|
|
|
|
update: SettingsUpdate,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SettingsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
2026-05-19 22:42:38 +08:00
|
|
|
if (update.modelPreset !== undefined) {
|
|
|
|
|
query.set("model_preset", update.modelPreset ?? "default");
|
|
|
|
|
}
|
2026-04-25 18:05:06 +00:00
|
|
|
if (update.model !== undefined) query.set("model", update.model);
|
|
|
|
|
if (update.provider !== undefined) query.set("provider", update.provider);
|
2026-05-29 04:23:30 +08:00
|
|
|
if (update.contextWindowTokens !== undefined) {
|
|
|
|
|
query.set("context_window_tokens", String(update.contextWindowTokens));
|
|
|
|
|
}
|
2026-05-19 22:42:38 +08:00
|
|
|
if (update.timezone !== undefined) query.set("timezone", update.timezone);
|
|
|
|
|
if (update.botName !== undefined) query.set("bot_name", update.botName);
|
|
|
|
|
if (update.botIcon !== undefined) query.set("bot_icon", update.botIcon);
|
|
|
|
|
if (update.toolHintMaxLength !== undefined) {
|
|
|
|
|
query.set("tool_hint_max_length", String(update.toolHintMaxLength));
|
|
|
|
|
}
|
2026-04-25 18:05:06 +00:00
|
|
|
return request<SettingsPayload>(`${base}/api/settings/update?${query}`, token);
|
|
|
|
|
}
|
2026-05-08 15:31:52 +00:00
|
|
|
|
2026-05-24 13:38:37 +08:00
|
|
|
export async function createModelConfiguration(
|
|
|
|
|
token: string,
|
|
|
|
|
configuration: ModelConfigurationCreate,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SettingsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
if (configuration.name !== undefined) query.set("name", configuration.name);
|
|
|
|
|
query.set("label", configuration.label);
|
|
|
|
|
query.set("provider", configuration.provider);
|
|
|
|
|
query.set("model", configuration.model);
|
|
|
|
|
return request<SettingsPayload>(
|
|
|
|
|
`${base}/api/settings/model-configurations/create?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-29 03:42:53 +08:00
|
|
|
export async function updateModelConfiguration(
|
|
|
|
|
token: string,
|
|
|
|
|
configuration: ModelConfigurationUpdate,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SettingsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("name", configuration.name);
|
|
|
|
|
if (configuration.label !== undefined) query.set("label", configuration.label);
|
|
|
|
|
if (configuration.provider !== undefined) query.set("provider", configuration.provider);
|
|
|
|
|
if (configuration.model !== undefined) query.set("model", configuration.model);
|
2026-05-29 04:23:30 +08:00
|
|
|
if (configuration.contextWindowTokens !== undefined) {
|
|
|
|
|
query.set("context_window_tokens", String(configuration.contextWindowTokens));
|
|
|
|
|
}
|
2026-05-29 03:42:53 +08:00
|
|
|
return request<SettingsPayload>(
|
|
|
|
|
`${base}/api/settings/model-configurations/update?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-08 15:31:52 +00:00
|
|
|
export async function updateProviderSettings(
|
|
|
|
|
token: string,
|
|
|
|
|
update: ProviderSettingsUpdate,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SettingsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("provider", update.provider);
|
|
|
|
|
if (update.apiKey !== undefined) query.set("api_key", update.apiKey);
|
|
|
|
|
if (update.apiBase !== undefined) query.set("api_base", update.apiBase);
|
2026-05-23 18:04:40 +08:00
|
|
|
if (update.apiType !== undefined) query.set("api_type", update.apiType);
|
2026-05-08 15:31:52 +00:00
|
|
|
return request<SettingsPayload>(
|
|
|
|
|
`${base}/api/settings/provider/update?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-05-09 06:48:26 +00:00
|
|
|
|
2026-05-29 03:42:53 +08:00
|
|
|
export async function loginProviderOAuth(
|
|
|
|
|
token: string,
|
|
|
|
|
provider: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SettingsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("provider", provider);
|
|
|
|
|
return request<SettingsPayload>(
|
|
|
|
|
`${base}/api/settings/provider/oauth-login?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function logoutProviderOAuth(
|
|
|
|
|
token: string,
|
|
|
|
|
provider: string,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SettingsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("provider", provider);
|
|
|
|
|
return request<SettingsPayload>(
|
|
|
|
|
`${base}/api/settings/provider/oauth-logout?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-09 06:48:26 +00:00
|
|
|
export async function updateWebSearchSettings(
|
|
|
|
|
token: string,
|
|
|
|
|
update: WebSearchSettingsUpdate,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SettingsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("provider", update.provider);
|
|
|
|
|
if (update.apiKey !== undefined) query.set("api_key", update.apiKey);
|
|
|
|
|
if (update.baseUrl !== undefined) query.set("base_url", update.baseUrl);
|
2026-05-19 22:42:38 +08:00
|
|
|
if (update.maxResults !== undefined) query.set("max_results", String(update.maxResults));
|
|
|
|
|
if (update.timeout !== undefined) query.set("timeout", String(update.timeout));
|
|
|
|
|
if (update.useJinaReader !== undefined) {
|
|
|
|
|
query.set("use_jina_reader", String(update.useJinaReader));
|
|
|
|
|
}
|
2026-05-09 06:48:26 +00:00
|
|
|
return request<SettingsPayload>(
|
|
|
|
|
`${base}/api/settings/web-search/update?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-05-19 22:42:38 +08:00
|
|
|
|
2026-05-29 03:42:53 +08:00
|
|
|
export async function updateNetworkSafetySettings(
|
|
|
|
|
token: string,
|
|
|
|
|
update: NetworkSafetySettingsUpdate,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SettingsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("webui_allow_local_service_access", String(update.webuiAllowLocalServiceAccess));
|
|
|
|
|
query.set("webui_default_access_mode", update.webuiDefaultAccessMode);
|
|
|
|
|
return request<SettingsPayload>(
|
|
|
|
|
`${base}/api/settings/network-safety/update?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-19 22:42:38 +08:00
|
|
|
export async function updateImageGenerationSettings(
|
|
|
|
|
token: string,
|
|
|
|
|
update: ImageGenerationSettingsUpdate,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SettingsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("enabled", String(update.enabled));
|
|
|
|
|
query.set("provider", update.provider);
|
|
|
|
|
query.set("model", update.model);
|
|
|
|
|
query.set("default_aspect_ratio", update.defaultAspectRatio);
|
|
|
|
|
query.set("default_image_size", update.defaultImageSize);
|
|
|
|
|
query.set("max_images_per_turn", String(update.maxImagesPerTurn));
|
|
|
|
|
return request<SettingsPayload>(
|
|
|
|
|
`${base}/api/settings/image-generation/update?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-06-09 01:08:49 +08:00
|
|
|
|
|
|
|
|
export async function updateTranscriptionSettings(
|
|
|
|
|
token: string,
|
|
|
|
|
update: TranscriptionSettingsUpdate,
|
|
|
|
|
base: string = "",
|
|
|
|
|
): Promise<SettingsPayload> {
|
|
|
|
|
const query = new URLSearchParams();
|
|
|
|
|
query.set("enabled", String(update.enabled));
|
|
|
|
|
query.set("provider", update.provider);
|
|
|
|
|
query.set("model", update.model);
|
|
|
|
|
query.set("language", update.language);
|
|
|
|
|
query.set("max_duration_sec", String(update.maxDurationSec));
|
|
|
|
|
query.set("max_upload_mb", String(update.maxUploadMb));
|
|
|
|
|
return request<SettingsPayload>(
|
|
|
|
|
`${base}/api/settings/transcription/update?${query}`,
|
|
|
|
|
token,
|
|
|
|
|
);
|
|
|
|
|
}
|