feat(automation): add daily briefing preset and cron backup scheduling
This commit is contained in:
@@ -205,7 +205,9 @@ describe('configSchema — backup', () => {
|
||||
it('defaults backup settings', () => {
|
||||
const result = configSchema.parse(minimalConfig);
|
||||
expect(result.backup.enabled).toBe(false);
|
||||
expect(result.backup.schedule).toBeUndefined();
|
||||
expect(result.backup.interval).toBe('24h');
|
||||
expect(result.backup.run_on_start).toBe(false);
|
||||
expect(result.backup.include_vectors).toBe(true);
|
||||
expect(result.backup.minio.enabled).toBe(false);
|
||||
expect(result.backup.minio.prefix).toBe('flynn');
|
||||
@@ -217,7 +219,9 @@ describe('configSchema — backup', () => {
|
||||
...minimalConfig,
|
||||
backup: {
|
||||
enabled: true,
|
||||
schedule: '0 2 * * *',
|
||||
interval: '12h',
|
||||
run_on_start: true,
|
||||
local_dir: '/tmp/flynn-backups',
|
||||
include_vectors: false,
|
||||
minio: {
|
||||
@@ -233,7 +237,9 @@ describe('configSchema — backup', () => {
|
||||
});
|
||||
|
||||
expect(result.backup.enabled).toBe(true);
|
||||
expect(result.backup.schedule).toBe('0 2 * * *');
|
||||
expect(result.backup.interval).toBe('12h');
|
||||
expect(result.backup.run_on_start).toBe(true);
|
||||
expect(result.backup.local_dir).toBe('/tmp/flynn-backups');
|
||||
expect(result.backup.include_vectors).toBe(false);
|
||||
expect(result.backup.minio.enabled).toBe(true);
|
||||
@@ -845,6 +851,9 @@ describe('configSchema automation', () => {
|
||||
expect(result.automation).toBeDefined();
|
||||
expect(result.automation.delivery_mode).toBe('shared_session');
|
||||
expect(result.automation.cron).toEqual([]);
|
||||
expect(result.automation.daily_briefing.enabled).toBe(false);
|
||||
expect(result.automation.daily_briefing.schedule).toBe('0 8 * * *');
|
||||
expect(result.automation.daily_briefing.name).toBe('daily-briefing');
|
||||
});
|
||||
|
||||
it('accepts isolated automation delivery mode', () => {
|
||||
@@ -919,6 +928,31 @@ describe('configSchema automation', () => {
|
||||
expect(result.automation.cron[0].enabled).toBe(false);
|
||||
expect(result.automation.cron[0].timezone).toBe('America/New_York');
|
||||
});
|
||||
|
||||
it('accepts daily briefing automation config', () => {
|
||||
const result = configSchema.parse({
|
||||
...baseConfig,
|
||||
automation: {
|
||||
daily_briefing: {
|
||||
enabled: true,
|
||||
name: 'weekday-briefing',
|
||||
schedule: '0 7 * * 1-5',
|
||||
timezone: 'America/New_York',
|
||||
output: { channel: 'telegram', peer: '123' },
|
||||
prompt: 'Custom briefing prompt',
|
||||
model_tier: 'fast',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.automation.daily_briefing.enabled).toBe(true);
|
||||
expect(result.automation.daily_briefing.name).toBe('weekday-briefing');
|
||||
expect(result.automation.daily_briefing.schedule).toBe('0 7 * * 1-5');
|
||||
expect(result.automation.daily_briefing.timezone).toBe('America/New_York');
|
||||
expect(result.automation.daily_briefing.output).toEqual({ channel: 'telegram', peer: '123' });
|
||||
expect(result.automation.daily_briefing.prompt).toBe('Custom briefing prompt');
|
||||
expect(result.automation.daily_briefing.model_tier).toBe('fast');
|
||||
});
|
||||
});
|
||||
|
||||
describe('configSchema — intents', () => {
|
||||
|
||||
@@ -341,6 +341,36 @@ const gtasksSchema = z.object({
|
||||
token_file: z.string().default('~/.config/flynn/gtasks-token.json'),
|
||||
}).optional();
|
||||
|
||||
const dailyBriefingSchema = z.object({
|
||||
enabled: z.boolean().default(false),
|
||||
name: z.string().min(1).default('daily-briefing'),
|
||||
schedule: z.string().min(1).default('0 8 * * *'),
|
||||
timezone: z.string().optional(),
|
||||
output: z.object({
|
||||
channel: z.string().min(1),
|
||||
peer: z.string().min(1),
|
||||
}).optional(),
|
||||
prompt: z.string().min(1).default(
|
||||
[
|
||||
'Create my daily briefing.',
|
||||
'',
|
||||
'Use available tools to gather:',
|
||||
'- Today\'s calendar events (calendar.today or calendar.list)',
|
||||
'- Unread or recent important email (gmail.search/gmail.list)',
|
||||
'- Top pending tasks (tasks.list/tasks.lists)',
|
||||
'',
|
||||
'Output format:',
|
||||
'1) Schedule',
|
||||
'2) Priorities',
|
||||
'3) Risks/Follow-ups',
|
||||
'4) Suggested first actions',
|
||||
'',
|
||||
'Keep it concise and actionable.',
|
||||
].join('\n'),
|
||||
),
|
||||
model_tier: modelTierEnum.optional(),
|
||||
}).default({});
|
||||
|
||||
const automationDeliveryModeSchema = z.enum(['shared_session', 'isolated_job']);
|
||||
|
||||
const automationSchema = z.object({
|
||||
@@ -353,6 +383,7 @@ const automationSchema = z.object({
|
||||
gdocs: gdocsSchema,
|
||||
gdrive: gdriveSchema,
|
||||
gtasks: gtasksSchema,
|
||||
daily_briefing: dailyBriefingSchema,
|
||||
heartbeat: heartbeatSchema,
|
||||
}).default({});
|
||||
|
||||
@@ -683,7 +714,9 @@ const sessionsSchema = z.object({
|
||||
|
||||
const backupSchema = z.object({
|
||||
enabled: z.boolean().default(false),
|
||||
schedule: z.string().optional(),
|
||||
interval: z.string().default('24h'),
|
||||
run_on_start: z.boolean().default(false),
|
||||
local_dir: z.string().default('~/.local/share/flynn/backups'),
|
||||
include_vectors: z.boolean().default(true),
|
||||
minio: z.object({
|
||||
@@ -814,6 +847,7 @@ export type GcalConfig = z.infer<typeof gcalSchema>;
|
||||
export type GdocsConfig = z.infer<typeof gdocsSchema>;
|
||||
export type GdriveConfig = z.infer<typeof gdriveSchema>;
|
||||
export type GtasksConfig = z.infer<typeof gtasksSchema>;
|
||||
export type DailyBriefingConfig = z.infer<typeof dailyBriefingSchema>;
|
||||
export type AutomationDeliveryMode = z.infer<typeof automationDeliveryModeSchema>;
|
||||
export type PairingCodeConfig = z.infer<typeof pairingSchema>;
|
||||
export type LogLevel = z.infer<typeof logLevelSchema>;
|
||||
|
||||
Reference in New Issue
Block a user