mioku-service-webui 4.9.0 → 4.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.ts +2 -0
- package/package.json +1 -1
- package/routes/agent.ts +132 -0
- package/routes/ai.ts +1 -0
- package/routes/index.ts +1 -0
- package/system.ts +12 -0
- package/utils.ts +1 -0
package/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
createConfigRoutes,
|
|
27
27
|
createWebUISettingsRoutes,
|
|
28
28
|
createAIRoutes,
|
|
29
|
+
createAgentRoutes,
|
|
29
30
|
createDBRoutes,
|
|
30
31
|
createPluginConfigRoutes,
|
|
31
32
|
createServiceConfigRoutes,
|
|
@@ -120,6 +121,7 @@ class WebUIRuntime {
|
|
|
120
121
|
this.app.route("/api/config", createConfigRoutes());
|
|
121
122
|
this.app.route("/api/settings", createWebUISettingsRoutes());
|
|
122
123
|
this.app.route("/api/ai", createAIRoutes());
|
|
124
|
+
this.app.route("/api/agent", createAgentRoutes());
|
|
123
125
|
this.app.route("/api/manage", createManageRoutes());
|
|
124
126
|
this.app.route("/api/store", createStoreRoutes());
|
|
125
127
|
this.app.route("/api/db", createDBRoutes());
|
package/package.json
CHANGED
package/routes/agent.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { logger } from "mioku";
|
|
3
|
+
import { getAgentConfig, updateAgentConfig } from "../system";
|
|
4
|
+
import aiService from "mioku-service-ai";
|
|
5
|
+
|
|
6
|
+
const PERMISSION_LEVELS = new Set([
|
|
7
|
+
"read-only",
|
|
8
|
+
"workspace-write",
|
|
9
|
+
"auto",
|
|
10
|
+
"full",
|
|
11
|
+
"yolo",
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
function normalizeIdList(input: unknown): number[] {
|
|
15
|
+
if (!Array.isArray(input)) return [];
|
|
16
|
+
return Array.from(
|
|
17
|
+
new Set(
|
|
18
|
+
input
|
|
19
|
+
.map((item) => Math.floor(Number(item)))
|
|
20
|
+
.filter((id: number) => Number.isFinite(id) && id > 0),
|
|
21
|
+
),
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function sanitizeAccess(input: any): any {
|
|
26
|
+
const access = input && typeof input === "object" ? input : {};
|
|
27
|
+
return {
|
|
28
|
+
allowAdmins: Boolean(access.allowAdmins),
|
|
29
|
+
users: normalizeIdList(access.users),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function sanitizeBaseForSave(body: any): any {
|
|
34
|
+
if (!body || typeof body !== "object") return body;
|
|
35
|
+
const next = { ...body };
|
|
36
|
+
delete next.persona;
|
|
37
|
+
delete next.roleBindings;
|
|
38
|
+
next.access = sanitizeAccess(next.access);
|
|
39
|
+
next.workspaceDir = String(next.workspaceDir ?? "").trim();
|
|
40
|
+
next.permissionLevel = PERMISSION_LEVELS.has(next.permissionLevel)
|
|
41
|
+
? next.permissionLevel
|
|
42
|
+
: "workspace-write";
|
|
43
|
+
next.model = String(next.model ?? "").trim();
|
|
44
|
+
return next;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function sanitizeSettingsForSave(body: any): any {
|
|
48
|
+
if (!body || typeof body !== "object") return body;
|
|
49
|
+
const next = { ...body };
|
|
50
|
+
const positive = (value: unknown, fallback: number) => {
|
|
51
|
+
const num = Math.floor(Number(value));
|
|
52
|
+
return Number.isFinite(num) && num > 0 ? num : fallback;
|
|
53
|
+
};
|
|
54
|
+
delete next.temperature;
|
|
55
|
+
delete next.enableMediaRecognition;
|
|
56
|
+
next.maxIterations = positive(next.maxIterations, 500);
|
|
57
|
+
next.maxContextTokens = positive(next.maxContextTokens, 524288);
|
|
58
|
+
next.stream = next.stream !== false;
|
|
59
|
+
next.enableMarkdownScreenshot = next.enableMarkdownScreenshot !== false;
|
|
60
|
+
next.compaction = {
|
|
61
|
+
enabled: next.compaction?.enabled !== false,
|
|
62
|
+
keepRecentMessages: positive(next.compaction?.keepRecentMessages, 20),
|
|
63
|
+
};
|
|
64
|
+
next.webSearch = {
|
|
65
|
+
enabled: next.webSearch?.enabled !== false,
|
|
66
|
+
baseUrl: String(next.webSearch?.baseUrl ?? "").trim(),
|
|
67
|
+
timeoutMs: positive(next.webSearch?.timeoutMs, 8000),
|
|
68
|
+
defaultLimit: positive(next.webSearch?.defaultLimit, 5),
|
|
69
|
+
maxLimit: positive(next.webSearch?.maxLimit, 8),
|
|
70
|
+
maxSearchCount: positive(next.webSearch?.maxSearchCount, 50),
|
|
71
|
+
};
|
|
72
|
+
next.webFetch = {
|
|
73
|
+
enabled: next.webFetch?.enabled !== false,
|
|
74
|
+
timeoutMs: positive(next.webFetch?.timeoutMs, 15000),
|
|
75
|
+
maxChars: positive(next.webFetch?.maxChars, 12000),
|
|
76
|
+
};
|
|
77
|
+
next.bash = {
|
|
78
|
+
enabled: next.bash?.enabled !== false,
|
|
79
|
+
timeoutMs: positive(next.bash?.timeoutMs, 120000),
|
|
80
|
+
approvalTimeoutMs: positive(next.bash?.approvalTimeoutMs, 300000),
|
|
81
|
+
};
|
|
82
|
+
next.dataCollection = { enabled: next.dataCollection?.enabled !== false };
|
|
83
|
+
next.debug = Boolean(next.debug);
|
|
84
|
+
return next;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function getAIApi() {
|
|
88
|
+
return aiService?.api as any;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function createAgentRoutes() {
|
|
92
|
+
const app = new Hono();
|
|
93
|
+
|
|
94
|
+
app.get("/base", (c) =>
|
|
95
|
+
c.json({ ok: true, data: getAgentConfig("base.json") }),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
app.put("/base", async (c) => {
|
|
99
|
+
const body = sanitizeBaseForSave(await c.req.json());
|
|
100
|
+
logger.info(`[webui-action] agent.base.update`, {
|
|
101
|
+
permissionLevel: body?.permissionLevel,
|
|
102
|
+
});
|
|
103
|
+
return c.json({ ok: true, data: updateAgentConfig("base.json", body) });
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
app.get("/settings", (c) =>
|
|
107
|
+
c.json({ ok: true, data: getAgentConfig("settings.json") }),
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
app.put("/settings", async (c) => {
|
|
111
|
+
const body = sanitizeSettingsForSave(await c.req.json());
|
|
112
|
+
logger.info(`[webui-action] agent.settings.update`);
|
|
113
|
+
return c.json({ ok: true, data: updateAgentConfig("settings.json", body) });
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
app.get("/status", (c) => {
|
|
117
|
+
const api = getAIApi();
|
|
118
|
+
const bindings = api?.getRoleBindings?.() ?? {};
|
|
119
|
+
const base = getAgentConfig("base.json");
|
|
120
|
+
return c.json({
|
|
121
|
+
ok: true,
|
|
122
|
+
data: {
|
|
123
|
+
aiConfigured: Boolean(bindings.main),
|
|
124
|
+
mainModel: bindings.main ?? "",
|
|
125
|
+
permissionLevel: base?.permissionLevel ?? "workspace-write",
|
|
126
|
+
workspaceDir: base?.workspaceDir ?? "",
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return app;
|
|
132
|
+
}
|
package/routes/ai.ts
CHANGED
package/routes/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { createConfigRoutes } from "./config";
|
|
2
2
|
export { createWebUISettingsRoutes } from "./webui";
|
|
3
3
|
export { createAIRoutes } from "./ai";
|
|
4
|
+
export { createAgentRoutes } from "./agent";
|
|
4
5
|
export { createDBRoutes, createPluginConfigRoutes, createMemeRoutes, createServiceConfigRoutes } from "./db";
|
|
5
6
|
export { createAdapterConfigRoutes } from "./adapter-config";
|
|
6
7
|
export { createManageRoutes } from "./manage";
|
package/system.ts
CHANGED
|
@@ -16,6 +16,7 @@ import type {
|
|
|
16
16
|
} from "./types";
|
|
17
17
|
import {
|
|
18
18
|
AUTH_PATH,
|
|
19
|
+
AGENT_CONFIG_DIR,
|
|
19
20
|
CHAT_CONFIG_DIR,
|
|
20
21
|
CONFIG_DIR,
|
|
21
22
|
defaultWebUISettings,
|
|
@@ -2419,6 +2420,17 @@ export function updateChatConfig(fileName: string, data: any): any {
|
|
|
2419
2420
|
return data;
|
|
2420
2421
|
}
|
|
2421
2422
|
|
|
2423
|
+
export function getAgentConfig(fileName: string): any {
|
|
2424
|
+
const filePath = path.join(AGENT_CONFIG_DIR, fileName);
|
|
2425
|
+
return readJsonFile(filePath, {});
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2428
|
+
export function updateAgentConfig(fileName: string, data: any): any {
|
|
2429
|
+
const filePath = path.join(AGENT_CONFIG_DIR, fileName);
|
|
2430
|
+
writeJsonFile(filePath, data);
|
|
2431
|
+
return data;
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2422
2434
|
export function getAdapterConfigs(adapterName: string): any {
|
|
2423
2435
|
const rootPkg = readRootPackageJson();
|
|
2424
2436
|
const adapters = rootPkg?.mioku?.adapters ?? {};
|
package/utils.ts
CHANGED
|
@@ -28,6 +28,7 @@ export const DATA_DIR = getDataDir();
|
|
|
28
28
|
export const PLUGINS_DIR = path.join(process.cwd(), "plugins");
|
|
29
29
|
export const SERVICES_DIR = path.join(process.cwd(), "node_modules");
|
|
30
30
|
export const CHAT_CONFIG_DIR = path.join(getConfigDir(), "chat");
|
|
31
|
+
export const AGENT_CONFIG_DIR = path.join(getConfigDir(), "agent");
|
|
31
32
|
export const CHAT_DATA_DIR = path.join(getDataDir(), "chat");
|
|
32
33
|
export const LOGS_DIR = path.join(process.cwd(), "logs");
|
|
33
34
|
export const NODE_MODULES_DIR = path.join(process.cwd(), "node_modules");
|