import * as Schema from "effect/Schema"; import { CommandId, IsoDateTime, ProjectId, ScheduledTaskId, ThreadId, TrimmedNonEmptyString,} from "./baseSchemas.ts";import { ModelSelection } from "./modelSelection.ts";import { OrchestrationV2Actor, OrchestrationV2CreationSource, OrchestrationV2ThreadLaunchWorkspaceStrategy,} from "./orchestrationV2.ts";import { ProviderInteractionMode, RuntimeMode } from "./providerPolicy.ts"; /** 24-hour "HH:MM" wall-clock time. Mirrors `parseTimeOfDay` on the server. */const TimeOfDay = TrimmedNonEmptyString.check( Schema.isPattern(/^([01]?\d|2[0-3]):([0-5]\d)$/),).annotate({ description: "Local wall-clock time in 24-hour HH:MM form, such as 09:30." }); export const MIN_SCHEDULED_TASK_INTERVAL_MS = 60_000; const ScheduledTaskIntervalMs = Schema.Int.check(Schema.isGreaterThan(0)).annotate({ description: "Positive interval in milliseconds.",}); const ScheduledTaskIntervalSchedule = Schema.Struct({ type: Schema.Literal("interval").annotate({ description: "Select interval scheduling.", }), everyMs: ScheduledTaskIntervalMs,}).annotate({ description: "Run repeatedly after a fixed number of milliseconds.",}); const ScheduledTaskFixedTimeSchedule = Schema.Struct({ type: Schema.Literal("fixed_time").annotate({ description: "Select a fixed local wall-clock time.", }), timeOfDay: TimeOfDay, weekdays: Schema.optional( Schema.Array( Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 6 })).annotate({ description: "Weekday number where 0 is Sunday and 6 is Saturday.", }), ).annotate({ description: "Optional weekdays; omit to run every day.", }), ),}).annotate({ description: "Run at a fixed local wall-clock time on selected weekdays.",}); /** * Read model for persisted schedules. Keep accepting legacy sub-minute rows so * users can list, disable, edit, or delete them after the write minimum changes. */export const ScheduledTaskSchedule = Schema.Union([ ScheduledTaskIntervalSchedule, ScheduledTaskFixedTimeSchedule,]).annotate({ description: "Structured recurring schedule. Pass an object with type 'interval' or 'fixed_time'.",});export type ScheduledTaskSchedule = typeof ScheduledTaskSchedule.Type; /** Mutation model: newly created or updated interval schedules run at most once per minute. */export const ScheduledTaskUpsertSchedule = Schema.Union([ Schema.Struct({ type: Schema.Literal("interval").annotate({ description: "Select interval scheduling.", }), everyMs: ScheduledTaskIntervalMs.check( Schema.isGreaterThanOrEqualTo(MIN_SCHEDULED_TASK_INTERVAL_MS), ).annotate({ description: "Interval in milliseconds, with a minimum of 60000 (one minute).", }), }).annotate({ description: "Run repeatedly after a fixed number of milliseconds.", }), ScheduledTaskFixedTimeSchedule,]).annotate({ description: "Writable recurring schedule. Pass an object with type 'interval' or 'fixed_time'.",});export type ScheduledTaskUpsertSchedule = typeof ScheduledTaskUpsertSchedule.Type; export const ScheduledTaskRunStatus = Schema.Literals(["never", "running", "succeeded", "failed"]);export type ScheduledTaskRunStatus = typeof ScheduledTaskRunStatus.Type; export const ScheduledTask = Schema.Struct({ id: ScheduledTaskId, title: TrimmedNonEmptyString, prompt: TrimmedNonEmptyString, enabled: Schema.Boolean, schedule: ScheduledTaskSchedule, projectId: ProjectId, threadId: Schema.NullOr(ThreadId), workspaceStrategy: OrchestrationV2ThreadLaunchWorkspaceStrategy, modelSelection: ModelSelection, runtimeMode: RuntimeMode, interactionMode: ProviderInteractionMode, createdBy: OrchestrationV2Actor, creationSource: OrchestrationV2CreationSource, createdAt: IsoDateTime, updatedAt: IsoDateTime, nextRunAt: Schema.NullOr(IsoDateTime), lastRunAt: Schema.NullOr(IsoDateTime), lastRunStatus: ScheduledTaskRunStatus, lastRunError: Schema.NullOr(Schema.String), runCount: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),});export type ScheduledTask = typeof ScheduledTask.Type; export const ScheduledTaskListInput = Schema.Struct({});export type ScheduledTaskListInput = typeof ScheduledTaskListInput.Type; export const ScheduledTaskListResult = Schema.Struct({ tasks: Schema.Array(ScheduledTask),});export type ScheduledTaskListResult = typeof ScheduledTaskListResult.Type; export const ScheduledTaskUpsertInput = Schema.Struct({ id: Schema.optional(ScheduledTaskId), commandId: Schema.optional(CommandId), title: TrimmedNonEmptyString, prompt: TrimmedNonEmptyString, enabled: Schema.Boolean, schedule: ScheduledTaskUpsertSchedule, projectId: ProjectId, threadId: Schema.optional(Schema.NullOr(ThreadId)), workspaceStrategy: OrchestrationV2ThreadLaunchWorkspaceStrategy, modelSelection: ModelSelection, runtimeMode: RuntimeMode, interactionMode: ProviderInteractionMode, createdBy: Schema.optional(OrchestrationV2Actor), creationSource: Schema.optional(OrchestrationV2CreationSource),});export type ScheduledTaskUpsertInput = typeof ScheduledTaskUpsertInput.Type; /** Partial update that flips only the enabled flag — never overwrites other fields. */export const ScheduledTaskSetEnabledInput = Schema.Struct({ id: ScheduledTaskId, enabled: Schema.Boolean,});export type ScheduledTaskSetEnabledInput = typeof ScheduledTaskSetEnabledInput.Type; export const ScheduledTaskDeleteInput = Schema.Struct({ id: ScheduledTaskId,});export type ScheduledTaskDeleteInput = typeof ScheduledTaskDeleteInput.Type; export const ScheduledTaskRunNowInput = Schema.Struct({ id: ScheduledTaskId,});export type ScheduledTaskRunNowInput = typeof ScheduledTaskRunNowInput.Type; export const ScheduledTaskMutationResult = Schema.Struct({ task: ScheduledTask,});export type ScheduledTaskMutationResult = typeof ScheduledTaskMutationResult.Type; export const ScheduledTaskDeleteResult = Schema.Struct({ id: ScheduledTaskId,});export type ScheduledTaskDeleteResult = typeof ScheduledTaskDeleteResult.Type; export const ScheduledTaskRunNowResult = Schema.Struct({ task: ScheduledTask,});export type ScheduledTaskRunNowResult = typeof ScheduledTaskRunNowResult.Type; export class ScheduledTaskError extends Schema.TaggedErrorClass<ScheduledTaskError>()( "ScheduledTaskError", { message: Schema.String, taskId: Schema.optional(ScheduledTaskId), cause: Schema.optional(Schema.Defect()), },) {}
import * as Schema from "effect/Schema";
import {
CommandId,
IsoDateTime,
ProjectId,
ScheduledTaskId,
ThreadId,
TrimmedNonEmptyString,
} from "./baseSchemas.ts";
import { ModelSelection } from "./modelSelection.ts";
import {
OrchestrationV2Actor,
OrchestrationV2CreationSource,
OrchestrationV2ThreadLaunchWorkspaceStrategy,
} from "./orchestrationV2.ts";
import { ProviderInteractionMode, RuntimeMode } from "./providerPolicy.ts";
/** 24-hour "HH:MM" wall-clock time. Mirrors `parseTimeOfDay` on the server. */
const TimeOfDay = TrimmedNonEmptyString.check(
Schema.isPattern(/^([01]?\d|2[0-3]):([0-5]\d)$/),
).annotate({ description: "Local wall-clock time in 24-hour HH:MM form, such as 09:30." });
export const MIN_SCHEDULED_TASK_INTERVAL_MS = 60_000;
const ScheduledTaskIntervalMs = Schema.Int.check(Schema.isGreaterThan(0)).annotate({
description: "Positive interval in milliseconds.",
});
const ScheduledTaskIntervalSchedule = Schema.Struct({
type: Schema.Literal("interval").annotate({
description: "Select interval scheduling.",
}),
everyMs: ScheduledTaskIntervalMs,
}).annotate({
description: "Run repeatedly after a fixed number of milliseconds.",
});
const ScheduledTaskFixedTimeSchedule = Schema.Struct({
type: Schema.Literal("fixed_time").annotate({
description: "Select a fixed local wall-clock time.",
}),
timeOfDay: TimeOfDay,
weekdays: Schema.optional(
Schema.Array(
Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 6 })).annotate({
description: "Weekday number where 0 is Sunday and 6 is Saturday.",
}),
).annotate({
description: "Optional weekdays; omit to run every day.",
}),
),
}).annotate({
description: "Run at a fixed local wall-clock time on selected weekdays.",
});
/**
* Read model for persisted schedules. Keep accepting legacy sub-minute rows so
* users can list, disable, edit, or delete them after the write minimum changes.
*/
export const ScheduledTaskSchedule = Schema.Union([
ScheduledTaskIntervalSchedule,
ScheduledTaskFixedTimeSchedule,
]).annotate({
description:
"Structured recurring schedule. Pass an object with type 'interval' or 'fixed_time'.",
});
export type ScheduledTaskSchedule = typeof ScheduledTaskSchedule.Type;
/** Mutation model: newly created or updated interval schedules run at most once per minute. */
export const ScheduledTaskUpsertSchedule = Schema.Union([
Schema.Struct({
type: Schema.Literal("interval").annotate({
description: "Select interval scheduling.",
}),
everyMs: ScheduledTaskIntervalMs.check(
Schema.isGreaterThanOrEqualTo(MIN_SCHEDULED_TASK_INTERVAL_MS),
).annotate({
description: "Interval in milliseconds, with a minimum of 60000 (one minute).",
}),
}).annotate({
description: "Run repeatedly after a fixed number of milliseconds.",
}),
ScheduledTaskFixedTimeSchedule,
]).annotate({
description: "Writable recurring schedule. Pass an object with type 'interval' or 'fixed_time'.",
});
export type ScheduledTaskUpsertSchedule = typeof ScheduledTaskUpsertSchedule.Type;
export const ScheduledTaskRunStatus = Schema.Literals(["never", "running", "succeeded", "failed"]);
export type ScheduledTaskRunStatus = typeof ScheduledTaskRunStatus.Type;
export const ScheduledTask = Schema.Struct({
id: ScheduledTaskId,
title: TrimmedNonEmptyString,
prompt: TrimmedNonEmptyString,
enabled: Schema.Boolean,
schedule: ScheduledTaskSchedule,
projectId: ProjectId,
threadId: Schema.NullOr(ThreadId),
workspaceStrategy: OrchestrationV2ThreadLaunchWorkspaceStrategy,
modelSelection: ModelSelection,
runtimeMode: RuntimeMode,
interactionMode: ProviderInteractionMode,
createdBy: OrchestrationV2Actor,
creationSource: OrchestrationV2CreationSource,
createdAt: IsoDateTime,
updatedAt: IsoDateTime,
nextRunAt: Schema.NullOr(IsoDateTime),
lastRunAt: Schema.NullOr(IsoDateTime),
lastRunStatus: ScheduledTaskRunStatus,
lastRunError: Schema.NullOr(Schema.String),
runCount: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
});
export type ScheduledTask = typeof ScheduledTask.Type;
export const ScheduledTaskListInput = Schema.Struct({});
export type ScheduledTaskListInput = typeof ScheduledTaskListInput.Type;
export const ScheduledTaskListResult = Schema.Struct({
tasks: Schema.Array(ScheduledTask),
});
export type ScheduledTaskListResult = typeof ScheduledTaskListResult.Type;
export const ScheduledTaskUpsertInput = Schema.Struct({
id: Schema.optional(ScheduledTaskId),
commandId: Schema.optional(CommandId),
title: TrimmedNonEmptyString,
prompt: TrimmedNonEmptyString,
enabled: Schema.Boolean,
schedule: ScheduledTaskUpsertSchedule,
projectId: ProjectId,
threadId: Schema.optional(Schema.NullOr(ThreadId)),
workspaceStrategy: OrchestrationV2ThreadLaunchWorkspaceStrategy,
modelSelection: ModelSelection,
runtimeMode: RuntimeMode,
interactionMode: ProviderInteractionMode,
createdBy: Schema.optional(OrchestrationV2Actor),
creationSource: Schema.optional(OrchestrationV2CreationSource),
});
export type ScheduledTaskUpsertInput = typeof ScheduledTaskUpsertInput.Type;
/** Partial update that flips only the enabled flag — never overwrites other fields. */
export const ScheduledTaskSetEnabledInput = Schema.Struct({
id: ScheduledTaskId,
enabled: Schema.Boolean,
});
export type ScheduledTaskSetEnabledInput = typeof ScheduledTaskSetEnabledInput.Type;
export const ScheduledTaskDeleteInput = Schema.Struct({
id: ScheduledTaskId,
});
export type ScheduledTaskDeleteInput = typeof ScheduledTaskDeleteInput.Type;
export const ScheduledTaskRunNowInput = Schema.Struct({
id: ScheduledTaskId,
});
export type ScheduledTaskRunNowInput = typeof ScheduledTaskRunNowInput.Type;
export const ScheduledTaskMutationResult = Schema.Struct({
task: ScheduledTask,
});
export type ScheduledTaskMutationResult = typeof ScheduledTaskMutationResult.Type;
export const ScheduledTaskDeleteResult = Schema.Struct({
id: ScheduledTaskId,
});
export type ScheduledTaskDeleteResult = typeof ScheduledTaskDeleteResult.Type;
export const ScheduledTaskRunNowResult = Schema.Struct({
task: ScheduledTask,
});
export type ScheduledTaskRunNowResult = typeof ScheduledTaskRunNowResult.Type;
export class ScheduledTaskError extends Schema.TaggedErrorClass<ScheduledTaskError>()(
"ScheduledTaskError",
{
message: Schema.String,
taskId: Schema.optional(ScheduledTaskId),
cause: Schema.optional(Schema.Defect()),
},
) {}