feat: add node browser proxy routing

This commit is contained in:
Peter Steinberger
2026-01-24 04:19:43 +00:00
parent dd06028827
commit c3cb26f7ca
14 changed files with 834 additions and 39 deletions

View File

@@ -50,6 +50,7 @@ const GROUP_LABELS: Record<string, string> = {
diagnostics: "Diagnostics",
logging: "Logging",
gateway: "Gateway",
nodeHost: "Node Host",
agents: "Agents",
tools: "Tools",
bindings: "Bindings",
@@ -76,6 +77,7 @@ const GROUP_ORDER: Record<string, number> = {
update: 25,
diagnostics: 27,
gateway: 30,
nodeHost: 35,
agents: 40,
tools: 50,
bindings: 55,
@@ -193,8 +195,12 @@ const FIELD_LABELS: Record<string, string> = {
"gateway.http.endpoints.chatCompletions.enabled": "OpenAI Chat Completions Endpoint",
"gateway.reload.mode": "Config Reload Mode",
"gateway.reload.debounceMs": "Config Reload Debounce (ms)",
"gateway.nodes.browser.mode": "Gateway Node Browser Mode",
"gateway.nodes.browser.node": "Gateway Node Browser Pin",
"gateway.nodes.allowCommands": "Gateway Node Allowlist (Extra Commands)",
"gateway.nodes.denyCommands": "Gateway Node Denylist",
"nodeHost.browserProxy.enabled": "Node Browser Proxy Enabled",
"nodeHost.browserProxy.allowProfiles": "Node Browser Proxy Allowed Profiles",
"skills.load.watch": "Watch Skills",
"skills.load.watchDebounceMs": "Skills Watch Debounce (ms)",
"agents.defaults.workspace": "Workspace",
@@ -366,10 +372,16 @@ const FIELD_HELP: Record<string, string> = {
"Enable the OpenAI-compatible `POST /v1/chat/completions` endpoint (default: false).",
"gateway.reload.mode": 'Hot reload strategy for config changes ("hybrid" recommended).',
"gateway.reload.debounceMs": "Debounce window (ms) before applying config changes.",
"gateway.nodes.browser.mode":
'Node browser routing ("auto" = pick single connected browser node, "manual" = require node param, "off" = disable).',
"gateway.nodes.browser.node": "Pin browser routing to a specific node id or name (optional).",
"gateway.nodes.allowCommands":
"Extra node.invoke commands to allow beyond the gateway defaults (array of command strings).",
"gateway.nodes.denyCommands":
"Commands to block even if present in node claims or default allowlist.",
"nodeHost.browserProxy.enabled": "Expose the local browser control server via node proxy.",
"nodeHost.browserProxy.allowProfiles":
"Optional allowlist of browser profile names exposed via the node proxy.",
"diagnostics.cacheTrace.enabled":
"Log cache trace snapshots for embedded agent runs (default: false).",
"diagnostics.cacheTrace.filePath":

View File

@@ -18,6 +18,7 @@ import type {
MessagesConfig,
} from "./types.messages.js";
import type { ModelsConfig } from "./types.models.js";
import type { NodeHostConfig } from "./types.node-host.js";
import type { PluginsConfig } from "./types.plugins.js";
import type { SkillsConfig } from "./types.skills.js";
import type { ToolsConfig } from "./types.tools.js";
@@ -75,6 +76,7 @@ export type ClawdbotConfig = {
skills?: SkillsConfig;
plugins?: PluginsConfig;
models?: ModelsConfig;
nodeHost?: NodeHostConfig;
agents?: AgentsConfig;
tools?: ToolsConfig;
bindings?: AgentBinding[];

View File

@@ -175,6 +175,13 @@ export type GatewayHttpConfig = {
};
export type GatewayNodesConfig = {
/** Browser routing policy for node-hosted browser proxies. */
browser?: {
/** Routing mode (default: auto). */
mode?: "auto" | "manual" | "off";
/** Pin to a specific node id/name (optional). */
node?: string;
};
/** Additional node.invoke commands to allow on the gateway. */
allowCommands?: string[];
/** Commands to deny even if they appear in the defaults or node claims. */

View File

@@ -0,0 +1,11 @@
export type NodeHostBrowserProxyConfig = {
/** Enable the browser proxy on the node host (default: true). */
enabled?: boolean;
/** Optional allowlist of profile names exposed via the proxy. */
allowProfiles?: string[];
};
export type NodeHostConfig = {
/** Browser proxy settings for node hosts. */
browserProxy?: NodeHostBrowserProxyConfig;
};

View File

@@ -14,6 +14,7 @@ export * from "./types.hooks.js";
export * from "./types.imessage.js";
export * from "./types.messages.js";
export * from "./types.models.js";
export * from "./types.node-host.js";
export * from "./types.msteams.js";
export * from "./types.plugins.js";
export * from "./types.queue.js";

View File

@@ -13,6 +13,19 @@ const BrowserSnapshotDefaultsSchema = z
.strict()
.optional();
const NodeHostSchema = z
.object({
browserProxy: z
.object({
enabled: z.boolean().optional(),
allowProfiles: z.array(z.string()).optional(),
})
.strict()
.optional(),
})
.strict()
.optional();
export const ClawdbotSchema = z
.object({
meta: z
@@ -193,6 +206,7 @@ export const ClawdbotSchema = z
.strict()
.optional(),
models: ModelsConfigSchema,
nodeHost: NodeHostSchema,
agents: AgentsSchema,
tools: ToolsSchema,
bindings: BindingsSchema,
@@ -403,6 +417,15 @@ export const ClawdbotSchema = z
.optional(),
nodes: z
.object({
browser: z
.object({
mode: z
.union([z.literal("auto"), z.literal("manual"), z.literal("off")])
.optional(),
node: z.string().optional(),
})
.strict()
.optional(),
allowCommands: z.array(z.string()).optional(),
denyCommands: z.array(z.string()).optional(),
})