mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
feat(web): add configurable cron command execution settings (#1647)
- add tools.cron.allow_command config with a default value of true - require command_confirm only when cron command execution is disabled - expose cron command permission and timeout settings in the config UI - add backend tests and update i18n strings
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
} from "@/api/system"
|
||||
import {
|
||||
AgentDefaultsSection,
|
||||
CronSection,
|
||||
DevicesSection,
|
||||
LauncherSection,
|
||||
RuntimeSection,
|
||||
@@ -164,6 +165,11 @@ export function ConfigPage() {
|
||||
"Heartbeat interval",
|
||||
{ min: 1 },
|
||||
)
|
||||
const cronExecTimeoutMinutes = parseIntField(
|
||||
form.cronExecTimeoutMinutes,
|
||||
"Cron exec timeout",
|
||||
{ min: 0 },
|
||||
)
|
||||
|
||||
await patchAppConfig({
|
||||
agents: {
|
||||
@@ -180,6 +186,10 @@ export function ConfigPage() {
|
||||
dm_scope: dmScope,
|
||||
},
|
||||
tools: {
|
||||
cron: {
|
||||
allow_command: form.allowCommand,
|
||||
exec_timeout_minutes: cronExecTimeoutMinutes,
|
||||
},
|
||||
exec: {
|
||||
allow_remote: form.allowRemote,
|
||||
},
|
||||
@@ -279,6 +289,8 @@ export function ConfigPage() {
|
||||
|
||||
<RuntimeSection form={form} onFieldChange={updateField} />
|
||||
|
||||
<CronSection form={form} onFieldChange={updateField} />
|
||||
|
||||
<LauncherSection
|
||||
launcherForm={launcherForm}
|
||||
onFieldChange={updateLauncherField}
|
||||
|
||||
@@ -236,6 +236,42 @@ export function RuntimeSection({ form, onFieldChange }: RuntimeSectionProps) {
|
||||
)
|
||||
}
|
||||
|
||||
interface CronSectionProps {
|
||||
form: CoreConfigForm
|
||||
onFieldChange: UpdateCoreField
|
||||
}
|
||||
|
||||
export function CronSection({ form, onFieldChange }: CronSectionProps) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<ConfigSectionCard title={t("pages.config.sections.cron")}>
|
||||
<SwitchCardField
|
||||
label={t("pages.config.allow_shell_execution")}
|
||||
hint={t("pages.config.allow_shell_execution_hint")}
|
||||
layout="setting-row"
|
||||
checked={form.allowCommand}
|
||||
onCheckedChange={(checked) => onFieldChange("allowCommand", checked)}
|
||||
/>
|
||||
|
||||
<Field
|
||||
label={t("pages.config.cron_exec_timeout")}
|
||||
hint={t("pages.config.cron_exec_timeout_hint")}
|
||||
layout="setting-row"
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
min={0}
|
||||
value={form.cronExecTimeoutMinutes}
|
||||
onChange={(e) =>
|
||||
onFieldChange("cronExecTimeoutMinutes", e.target.value)
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
</ConfigSectionCard>
|
||||
)
|
||||
}
|
||||
|
||||
interface LauncherSectionProps {
|
||||
launcherForm: LauncherForm
|
||||
onFieldChange: UpdateLauncherField
|
||||
|
||||
@@ -4,6 +4,8 @@ export interface CoreConfigForm {
|
||||
workspace: string
|
||||
restrictToWorkspace: boolean
|
||||
allowRemote: boolean
|
||||
allowCommand: boolean
|
||||
cronExecTimeoutMinutes: string
|
||||
maxTokens: string
|
||||
maxToolIterations: string
|
||||
summarizeMessageThreshold: string
|
||||
@@ -56,6 +58,8 @@ export const EMPTY_FORM: CoreConfigForm = {
|
||||
workspace: "",
|
||||
restrictToWorkspace: true,
|
||||
allowRemote: true,
|
||||
allowCommand: true,
|
||||
cronExecTimeoutMinutes: "5",
|
||||
maxTokens: "32768",
|
||||
maxToolIterations: "50",
|
||||
summarizeMessageThreshold: "20",
|
||||
@@ -106,6 +110,7 @@ export function buildFormFromConfig(config: unknown): CoreConfigForm {
|
||||
const heartbeat = asRecord(root.heartbeat)
|
||||
const devices = asRecord(root.devices)
|
||||
const tools = asRecord(root.tools)
|
||||
const cron = asRecord(tools.cron)
|
||||
const exec = asRecord(tools.exec)
|
||||
|
||||
return {
|
||||
@@ -118,6 +123,14 @@ export function buildFormFromConfig(config: unknown): CoreConfigForm {
|
||||
exec.allow_remote === undefined
|
||||
? EMPTY_FORM.allowRemote
|
||||
: asBool(exec.allow_remote),
|
||||
allowCommand:
|
||||
cron.allow_command === undefined
|
||||
? EMPTY_FORM.allowCommand
|
||||
: asBool(cron.allow_command),
|
||||
cronExecTimeoutMinutes: asNumberString(
|
||||
cron.exec_timeout_minutes,
|
||||
EMPTY_FORM.cronExecTimeoutMinutes,
|
||||
),
|
||||
maxTokens: asNumberString(defaults.max_tokens, EMPTY_FORM.maxTokens),
|
||||
maxToolIterations: asNumberString(
|
||||
defaults.max_tool_iterations,
|
||||
|
||||
@@ -394,6 +394,10 @@
|
||||
"restrict_workspace_hint": "Only allow file operations inside workspace.",
|
||||
"allow_remote": "Allow Remote Shell Execution",
|
||||
"allow_remote_hint": "When enabled, shell commands can also run for remote sessions or non-local contexts. When disabled, shell execution stays limited to local safe contexts.",
|
||||
"allow_shell_execution": "Allow Shell Execution",
|
||||
"allow_shell_execution_hint": "Enable scheduled shell commands for cron jobs by default. When disabled, users must pass command_confirm=true to schedule a cron command.",
|
||||
"cron_exec_timeout": "Cron Command Timeout (minutes)",
|
||||
"cron_exec_timeout_hint": "Maximum runtime for scheduled shell commands. Set to 0 to disable the timeout.",
|
||||
"max_tokens": "Max Tokens",
|
||||
"max_tokens_hint": "Upper token limit per model response.",
|
||||
"max_tool_iterations": "Max Tool Iterations",
|
||||
@@ -434,6 +438,7 @@
|
||||
"sections": {
|
||||
"agent": "Agent",
|
||||
"runtime": "Runtime",
|
||||
"cron": "Cron Tasks",
|
||||
"launcher": "Service",
|
||||
"devices": "Devices"
|
||||
},
|
||||
|
||||
@@ -394,6 +394,10 @@
|
||||
"restrict_workspace_hint": "仅允许在工作目录内执行文件操作。",
|
||||
"allow_remote": "允许远程执行 Shell 命令",
|
||||
"allow_remote_hint": "开启后,来自远程会话或非本地上下文的请求也可以执行 shell 命令;关闭后,仅允许本地安全上下文执行。",
|
||||
"allow_shell_execution": "允许 Shell 执行",
|
||||
"allow_shell_execution_hint": "开启后,cron 定时任务默认允许执行 shell 命令。关闭后,必须显式传入 command_confirm=true 才能创建 cron 命令任务。",
|
||||
"cron_exec_timeout": "定时命令超时(分钟)",
|
||||
"cron_exec_timeout_hint": "定时 shell 命令的最长执行时间。设置为 0 表示不限制超时。",
|
||||
"max_tokens": "最大 Token 数",
|
||||
"max_tokens_hint": "单次模型响应允许的最大 Token 数。",
|
||||
"max_tool_iterations": "最大工具迭代次数",
|
||||
@@ -434,6 +438,7 @@
|
||||
"sections": {
|
||||
"agent": "智能体",
|
||||
"runtime": "运行时",
|
||||
"cron": "定时任务",
|
||||
"launcher": "服务参数",
|
||||
"devices": "设备"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user