Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 58 additions & 2 deletions ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ChevronLeft,
ChevronDown,
ChevronRight,
Clock,
Database,
FileCog,
FolderOpen,
Expand Down Expand Up @@ -128,6 +129,11 @@ type PilotDeckConfig = {
};
projects?: Record<string, { enabled?: boolean }>;
};
cron?: {
enabled?: boolean;
timezone?: string;
maxConcurrentRuns?: number;
};
customEnv?: Record<string, string>;
router?: {
enabled?: boolean;
Expand Down Expand Up @@ -179,13 +185,14 @@ type PilotDeckConfig = {
};
};

type SectionId = 'models' | 'agents' | 'memory' | 'tools' | 'router' | 'gateway' | 'customEnv' | 'alwaysOn' | 'advanced';
type SectionId = 'models' | 'agents' | 'memory' | 'tools' | 'router' | 'gateway' | 'customEnv' | 'alwaysOn' | 'cron' | 'advanced';

const SECTIONS: Array<{ id: SectionId; labelKey: string; descriptionKey: string }> = [
{ id: 'advanced', labelKey: 'runtime', descriptionKey: 'runtime' },
{ id: 'models', labelKey: 'models', descriptionKey: 'models' },
{ id: 'agents', labelKey: 'agents', descriptionKey: 'agents' },
{ id: 'alwaysOn', labelKey: 'alwaysOn', descriptionKey: 'alwaysOn' },
{ id: 'cron', labelKey: 'cron', descriptionKey: 'cron' },
{ id: 'memory', labelKey: 'memory', descriptionKey: 'memory' },
{ id: 'tools', labelKey: 'tools', descriptionKey: 'tools' },
{ id: 'router', labelKey: 'router', descriptionKey: 'router' },
Expand All @@ -195,7 +202,7 @@ const SECTIONS: Array<{ id: SectionId; labelKey: string; descriptionKey: string

const SECTION_GROUPS: Array<{ id: 'basic' | 'features' | 'advanced'; sections: SectionId[] }> = [
{ id: 'basic', sections: ['models', 'agents'] },
{ id: 'features', sections: ['router', 'memory', 'tools', 'alwaysOn', 'gateway'] },
{ id: 'features', sections: ['router', 'memory', 'tools', 'alwaysOn', 'cron', 'gateway'] },
{ id: 'advanced', sections: ['advanced', 'customEnv'] },
];

Expand All @@ -206,6 +213,7 @@ const SECTION_ICONS: Record<SectionId, LucideIcon> = {
memory: Brain,
tools: Search,
alwaysOn: Zap,
cron: Clock,
gateway: Wifi,
advanced: Server,
customEnv: FileCog,
Expand Down Expand Up @@ -1744,6 +1752,53 @@ function AlwaysOnSection({
);
}

function CronSection({ config, onChange }: { config: PilotDeckConfig; onChange: (next: PilotDeckConfig) => void }) {
const { t } = useTranslation('settings');
const cron = config.cron ?? {};
const enabled = cron.enabled !== false;

Comment on lines +1757 to +1759
return (
<SettingsSection
title={t('pilotDeckConfig.panels.cron.title')}
description={t('pilotDeckConfig.panels.cron.description')}
>
<SettingsCard divided>
<SettingsRow
label={t('pilotDeckConfig.panels.cron.enabled.label')}
description={t('pilotDeckConfig.panels.cron.enabled.description')}
>
<SettingsToggle
checked={enabled}
ariaLabel={t('pilotDeckConfig.panels.cron.enabled.label')}
onChange={(value) => onChange(patch(config, ['cron', 'enabled'], value))}
/>
</SettingsRow>
<FormRow
label={t('pilotDeckConfig.panels.cron.timezone.label')}
description={t('pilotDeckConfig.panels.cron.timezone.description')}
>
<TextInput
value={cron.timezone}
placeholder="Asia/Shanghai"
monospace
onChange={(value) => onChange(patch(config, ['cron', 'timezone'], value || undefined))}
/>
</FormRow>
<FormRow
label={t('pilotDeckConfig.panels.cron.maxConcurrentRuns.label')}
description={t('pilotDeckConfig.panels.cron.maxConcurrentRuns.description')}
>
<NumberInput
value={cron.maxConcurrentRuns}
placeholder="2"
onChange={(value) => onChange(patch(config, ['cron', 'maxConcurrentRuns'], value))}
/>
</FormRow>
</SettingsCard>
</SettingsSection>
);
}

function MemorySection({ config, onChange }: { config: PilotDeckConfig; onChange: (next: PilotDeckConfig) => void }) {
const { t } = useTranslation('settings');
const m = config.memory ?? {};
Expand Down Expand Up @@ -3188,6 +3243,7 @@ export default function PilotDeckConfigTab({ projects = [] }: { projects?: Setti
{activeSection === 'gateway' && <GatewaySection config={parsedConfig} onChange={onFormChange} />}
{activeSection === 'customEnv' && <CustomEnvSection config={parsedConfig} onChange={onFormChange} />}
{activeSection === 'alwaysOn' && <AlwaysOnSection config={parsedConfig} projects={projects} onChange={onFormChange} />}
{activeSection === 'cron' && <CronSection config={parsedConfig} onChange={onFormChange} />}
{activeSection === 'advanced' && <ServiceSection config={parsedConfig} onChange={onFormChange} />}
</div>
</div>
Expand Down
20 changes: 20 additions & 0 deletions ui/src/i18n/locales/en/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,10 @@
"label": "Always-On",
"description": "Automatic discovery and workspace opt-in"
},
"cron": {
"label": "Cron",
"description": "Scheduled background task runtime"
},
"memory": {
"label": "Memory",
"description": "PilotDeck memory service"
Expand Down Expand Up @@ -779,6 +783,22 @@
"empty": "No recognized projects yet. Add or open a workspace first."
}
},
"cron": {
"title": "Cron",
"description": "Configure the background scheduler used by Cron jobs. Create and manage jobs from Always-On > Plans & Cron Jobs.",
"enabled": {
"label": "Enabled",
"description": "Master switch for scheduled Cron background tasks."
},
"timezone": {
"label": "Timezone",
"description": "IANA timezone used as the scheduler default."
},
"maxConcurrentRuns": {
"label": "Max concurrent runs",
"description": "Maximum number of Cron runs that may execute at the same time."
}
},
"memory": {
"title": "Memory",
"description": "Configure the model used for memory indexing and Dream.",
Expand Down
20 changes: 20 additions & 0 deletions ui/src/i18n/locales/zh-CN/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,10 @@
"label": "常驻",
"description": "自动发现和工作区启用设置"
},
"cron": {
"label": "Cron",
"description": "定时后台任务运行时"
},
"memory": {
"label": "记忆",
"description": "PilotDeck 记忆服务"
Expand Down Expand Up @@ -779,6 +783,22 @@
"empty": "尚未识别到项目。请先添加或打开一个工作区。"
}
},
"cron": {
"title": "Cron",
"description": "配置 Cron 任务使用的后台调度器。任务创建和管理仍在 Always-On > Plans & Cron Jobs 中完成。",
"enabled": {
"label": "启用",
"description": "定时 Cron 后台任务的总开关。"
},
"timezone": {
"label": "时区",
"description": "调度器默认使用的 IANA 时区。"
},
"maxConcurrentRuns": {
"label": "最大并发运行数",
"description": "同一时间允许执行的 Cron 运行数量上限。"
}
},
"memory": {
"title": "记忆",
"description": "配置记忆索引与 Dream 使用的模型。",
Expand Down