mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-07 22:44:16 +00:00
fix(ui): unblock docker onboarding build
This commit is contained in:
121
src/agents/tool-policy-shared.ts
Normal file
121
src/agents/tool-policy-shared.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
export type ToolProfileId = "minimal" | "coding" | "messaging" | "full";
|
||||
|
||||
type ToolProfilePolicy = {
|
||||
allow?: string[];
|
||||
deny?: string[];
|
||||
};
|
||||
|
||||
const TOOL_NAME_ALIASES: Record<string, string> = {
|
||||
bash: "exec",
|
||||
"apply-patch": "apply_patch",
|
||||
};
|
||||
|
||||
export const TOOL_GROUPS: Record<string, string[]> = {
|
||||
// NOTE: Keep canonical (lowercase) tool names here.
|
||||
"group:memory": ["memory_search", "memory_get"],
|
||||
"group:web": ["web_search", "web_fetch"],
|
||||
// Basic workspace/file tools
|
||||
"group:fs": ["read", "write", "edit", "apply_patch"],
|
||||
// Host/runtime execution tools
|
||||
"group:runtime": ["exec", "process"],
|
||||
// Session management tools
|
||||
"group:sessions": [
|
||||
"sessions_list",
|
||||
"sessions_history",
|
||||
"sessions_send",
|
||||
"sessions_spawn",
|
||||
"subagents",
|
||||
"session_status",
|
||||
],
|
||||
// UI helpers
|
||||
"group:ui": ["browser", "canvas"],
|
||||
// Automation + infra
|
||||
"group:automation": ["cron", "gateway"],
|
||||
// Messaging surface
|
||||
"group:messaging": ["message"],
|
||||
// Nodes + device tools
|
||||
"group:nodes": ["nodes"],
|
||||
// All OpenClaw native tools (excludes provider plugins).
|
||||
"group:openclaw": [
|
||||
"browser",
|
||||
"canvas",
|
||||
"nodes",
|
||||
"cron",
|
||||
"message",
|
||||
"gateway",
|
||||
"agents_list",
|
||||
"sessions_list",
|
||||
"sessions_history",
|
||||
"sessions_send",
|
||||
"sessions_spawn",
|
||||
"subagents",
|
||||
"session_status",
|
||||
"memory_search",
|
||||
"memory_get",
|
||||
"web_search",
|
||||
"web_fetch",
|
||||
"image",
|
||||
],
|
||||
};
|
||||
|
||||
const TOOL_PROFILES: Record<ToolProfileId, ToolProfilePolicy> = {
|
||||
minimal: {
|
||||
allow: ["session_status"],
|
||||
},
|
||||
coding: {
|
||||
allow: ["group:fs", "group:runtime", "group:sessions", "group:memory", "image"],
|
||||
},
|
||||
messaging: {
|
||||
allow: [
|
||||
"group:messaging",
|
||||
"sessions_list",
|
||||
"sessions_history",
|
||||
"sessions_send",
|
||||
"session_status",
|
||||
],
|
||||
},
|
||||
full: {},
|
||||
};
|
||||
|
||||
export function normalizeToolName(name: string) {
|
||||
const normalized = name.trim().toLowerCase();
|
||||
return TOOL_NAME_ALIASES[normalized] ?? normalized;
|
||||
}
|
||||
|
||||
export function normalizeToolList(list?: string[]) {
|
||||
if (!list) {
|
||||
return [];
|
||||
}
|
||||
return list.map(normalizeToolName).filter(Boolean);
|
||||
}
|
||||
|
||||
export function expandToolGroups(list?: string[]) {
|
||||
const normalized = normalizeToolList(list);
|
||||
const expanded: string[] = [];
|
||||
for (const value of normalized) {
|
||||
const group = TOOL_GROUPS[value];
|
||||
if (group) {
|
||||
expanded.push(...group);
|
||||
continue;
|
||||
}
|
||||
expanded.push(value);
|
||||
}
|
||||
return Array.from(new Set(expanded));
|
||||
}
|
||||
|
||||
export function resolveToolProfilePolicy(profile?: string): ToolProfilePolicy | undefined {
|
||||
if (!profile) {
|
||||
return undefined;
|
||||
}
|
||||
const resolved = TOOL_PROFILES[profile as ToolProfileId];
|
||||
if (!resolved) {
|
||||
return undefined;
|
||||
}
|
||||
if (!resolved.allow && !resolved.deny) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
allow: resolved.allow ? [...resolved.allow] : undefined,
|
||||
deny: resolved.deny ? [...resolved.deny] : undefined,
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import { createRequire } from "node:module";
|
||||
import util from "node:util";
|
||||
import type { OpenClawConfig } from "../config/types.js";
|
||||
import { isVerbose } from "../globals.js";
|
||||
@@ -16,14 +15,37 @@ type ConsoleSettings = {
|
||||
};
|
||||
export type ConsoleLoggerSettings = ConsoleSettings;
|
||||
|
||||
const requireConfig = createRequire(import.meta.url);
|
||||
function resolveNodeRequire(): ((id: string) => NodeJS.Require) | null {
|
||||
const getBuiltinModule = (
|
||||
process as NodeJS.Process & {
|
||||
getBuiltinModule?: (id: string) => unknown;
|
||||
}
|
||||
).getBuiltinModule;
|
||||
if (typeof getBuiltinModule !== "function") {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
const moduleNamespace = getBuiltinModule("module") as {
|
||||
createRequire?: (id: string) => NodeJS.Require;
|
||||
};
|
||||
return typeof moduleNamespace.createRequire === "function"
|
||||
? moduleNamespace.createRequire
|
||||
: null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const requireConfig = resolveNodeRequire()?.(import.meta.url) ?? null;
|
||||
type ConsoleConfigLoader = () => OpenClawConfig["logging"] | undefined;
|
||||
const loadConfigFallbackDefault: ConsoleConfigLoader = () => {
|
||||
try {
|
||||
const loaded = requireConfig("../config/config.js") as {
|
||||
loadConfig?: () => OpenClawConfig;
|
||||
};
|
||||
return loaded.loadConfig?.().logging;
|
||||
const loaded = requireConfig?.("../config/config.js") as
|
||||
| {
|
||||
loadConfig?: () => OpenClawConfig;
|
||||
}
|
||||
| undefined;
|
||||
return loaded?.loadConfig?.().logging;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import fs from "node:fs";
|
||||
import { createRequire } from "node:module";
|
||||
import path from "node:path";
|
||||
import { Logger as TsLogger } from "tslog";
|
||||
import type { OpenClawConfig } from "../config/types.js";
|
||||
@@ -16,7 +15,28 @@ const LOG_PREFIX = "openclaw";
|
||||
const LOG_SUFFIX = ".log";
|
||||
const MAX_LOG_AGE_MS = 24 * 60 * 60 * 1000; // 24h
|
||||
|
||||
const requireConfig = createRequire(import.meta.url);
|
||||
function resolveNodeRequire(): ((id: string) => NodeJS.Require) | null {
|
||||
const getBuiltinModule = (
|
||||
process as NodeJS.Process & {
|
||||
getBuiltinModule?: (id: string) => unknown;
|
||||
}
|
||||
).getBuiltinModule;
|
||||
if (typeof getBuiltinModule !== "function") {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
const moduleNamespace = getBuiltinModule("module") as {
|
||||
createRequire?: (id: string) => NodeJS.Require;
|
||||
};
|
||||
return typeof moduleNamespace.createRequire === "function"
|
||||
? moduleNamespace.createRequire
|
||||
: null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const requireConfig = resolveNodeRequire()?.(import.meta.url) ?? null;
|
||||
|
||||
export type LoggerSettings = {
|
||||
level?: LogLevel;
|
||||
@@ -55,10 +75,12 @@ function resolveSettings(): ResolvedSettings {
|
||||
(loggingState.overrideSettings as LoggerSettings | null) ?? readLoggingConfig();
|
||||
if (!cfg) {
|
||||
try {
|
||||
const loaded = requireConfig("../config/config.js") as {
|
||||
loadConfig?: () => OpenClawConfig;
|
||||
};
|
||||
cfg = loaded.loadConfig?.().logging;
|
||||
const loaded = requireConfig?.("../config/config.js") as
|
||||
| {
|
||||
loadConfig?: () => OpenClawConfig;
|
||||
}
|
||||
| undefined;
|
||||
cfg = loaded?.loadConfig?.().logging;
|
||||
} catch {
|
||||
cfg = undefined;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,27 @@
|
||||
import { createRequire } from "node:module";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
|
||||
const requireConfig = createRequire(import.meta.url);
|
||||
function resolveNodeRequire(): ((id: string) => NodeJS.Require) | null {
|
||||
const getBuiltinModule = (
|
||||
process as NodeJS.Process & {
|
||||
getBuiltinModule?: (id: string) => unknown;
|
||||
}
|
||||
).getBuiltinModule;
|
||||
if (typeof getBuiltinModule !== "function") {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
const moduleNamespace = getBuiltinModule("module") as {
|
||||
createRequire?: (id: string) => NodeJS.Require;
|
||||
};
|
||||
return typeof moduleNamespace.createRequire === "function"
|
||||
? moduleNamespace.createRequire
|
||||
: null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const requireConfig = resolveNodeRequire()?.(import.meta.url) ?? null;
|
||||
|
||||
export type RedactSensitiveMode = "off" | "tools";
|
||||
|
||||
@@ -110,10 +130,12 @@ function redactText(text: string, patterns: RegExp[]): string {
|
||||
function resolveConfigRedaction(): RedactOptions {
|
||||
let cfg: OpenClawConfig["logging"] | undefined;
|
||||
try {
|
||||
const loaded = requireConfig("../config/config.js") as {
|
||||
loadConfig?: () => OpenClawConfig;
|
||||
};
|
||||
cfg = loaded.loadConfig?.().logging;
|
||||
const loaded = requireConfig?.("../config/config.js") as
|
||||
| {
|
||||
loadConfig?: () => OpenClawConfig;
|
||||
}
|
||||
| undefined;
|
||||
cfg = loaded?.loadConfig?.().logging;
|
||||
} catch {
|
||||
cfg = undefined;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { inspect } from "node:util";
|
||||
import { Chalk } from "chalk";
|
||||
import type { Logger as TsLogger } from "tslog";
|
||||
import { CHAT_CHANNEL_ORDER } from "../channels/registry.js";
|
||||
@@ -36,6 +35,39 @@ function shouldLogToConsole(level: LogLevel, settings: { level: LogLevel }): boo
|
||||
|
||||
type ChalkInstance = InstanceType<typeof Chalk>;
|
||||
|
||||
const inspectValue: ((value: unknown) => string) | null = (() => {
|
||||
const getBuiltinModule = (
|
||||
process as NodeJS.Process & {
|
||||
getBuiltinModule?: (id: string) => unknown;
|
||||
}
|
||||
).getBuiltinModule;
|
||||
if (typeof getBuiltinModule !== "function") {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
const utilNamespace = getBuiltinModule("util") as {
|
||||
inspect?: (value: unknown) => string;
|
||||
};
|
||||
return typeof utilNamespace.inspect === "function" ? utilNamespace.inspect : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
|
||||
function formatRuntimeArg(arg: unknown): string {
|
||||
if (typeof arg === "string") {
|
||||
return arg;
|
||||
}
|
||||
if (inspectValue) {
|
||||
return inspectValue(arg);
|
||||
}
|
||||
try {
|
||||
return JSON.stringify(arg);
|
||||
} catch {
|
||||
return String(arg);
|
||||
}
|
||||
}
|
||||
|
||||
function isRichConsoleEnv(): boolean {
|
||||
const term = (process.env.TERM ?? "").toLowerCase();
|
||||
if (process.env.COLORTERM || process.env.TERM_PROGRAM) {
|
||||
@@ -323,7 +355,7 @@ export function runtimeForLogger(
|
||||
): RuntimeEnv {
|
||||
const formatArgs = (...args: unknown[]) =>
|
||||
args
|
||||
.map((arg) => (typeof arg === "string" ? arg : inspect(arg)))
|
||||
.map((arg) => formatRuntimeArg(arg))
|
||||
.join(" ")
|
||||
.trim();
|
||||
return {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { html, nothing } from "lit";
|
||||
import { normalizeToolName } from "../../../../src/agents/tool-policy.js";
|
||||
import { normalizeToolName } from "../../../../src/agents/tool-policy-shared.js";
|
||||
import type { SkillStatusEntry, SkillStatusReport } from "../types.ts";
|
||||
import {
|
||||
isAllowedByPolicy,
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
expandToolGroups,
|
||||
normalizeToolName,
|
||||
resolveToolProfilePolicy,
|
||||
} from "../../../../src/agents/tool-policy.js";
|
||||
} from "../../../../src/agents/tool-policy-shared.js";
|
||||
import type { AgentIdentityResult, AgentsFilesListResult, AgentsListResult } from "../types.ts";
|
||||
|
||||
export const TOOL_SECTIONS = [
|
||||
|
||||
Reference in New Issue
Block a user