93 lines
3.8 KiB
TypeScript
93 lines
3.8 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
export const MAX_CONFIGURED_AUTOMATED_CONVERSATION_TURNS = 20;
|
|
|
|
export const ToneKeySchema = z.union([
|
|
z.literal('default'),
|
|
z.literal('dominant'),
|
|
z.literal('submissive'),
|
|
z.literal('playful'),
|
|
z.literal('direct'),
|
|
z.literal('gentle'),
|
|
z.literal('kink-friendly'),
|
|
z.literal('teasing'),
|
|
]);
|
|
|
|
export const RateLimitConfigSchema = z.strictObject({
|
|
minDelayBetweenMessagesMs: z.number(),
|
|
maxMessagesPerHour: z.number(),
|
|
jitterMs: z.number(),
|
|
});
|
|
export const RuntimeRedditConfigSchema = z.strictObject({
|
|
prioritizeRecentPosts: z.boolean(),
|
|
recentWindowMinutes: z.number(),
|
|
maxReadyCandidates: z.number().int().min(1).max(500),
|
|
physiqueTargeting: z.strictObject({
|
|
enabled: z.boolean(),
|
|
minScore: z.number().int().min(1).max(10),
|
|
maxScore: z.number().int().min(1).max(10),
|
|
}).refine((targeting) => targeting.minScore <= targeting.maxScore, {
|
|
message: 'Minimum physique score cannot exceed maximum physique score.',
|
|
path: ['minScore'],
|
|
}).default({ enabled: false, minScore: 1, maxScore: 10 }),
|
|
});
|
|
export const RuntimeConfigSchema = z.strictObject({
|
|
rateLimit: RateLimitConfigSchema,
|
|
browser: z.strictObject({ dryRun: z.boolean() }),
|
|
reddit: RuntimeRedditConfigSchema,
|
|
});
|
|
export const ConversationBehaviourSchema = z.strictObject({
|
|
mode: z.union([z.literal('legacy'), z.literal('r4r'), z.literal('r4r-media'), z.literal('manual')]).default('legacy'),
|
|
maxAutomatedTurns: z.number().int().min(1).max(MAX_CONFIGURED_AUTOMATED_CONVERSATION_TURNS).default(3),
|
|
rapportTurnsBeforeMediaAsk: z.number().int().min(1).max(MAX_CONFIGURED_AUTOMATED_CONVERSATION_TURNS - 1).default(3),
|
|
}).superRefine((behaviour, context) => {
|
|
if (behaviour.mode === 'r4r-media' && behaviour.rapportTurnsBeforeMediaAsk >= behaviour.maxAutomatedTurns) {
|
|
context.addIssue({
|
|
code: 'custom',
|
|
path: ['rapportTurnsBeforeMediaAsk'],
|
|
message: 'Rapport turns must be lower than the maximum automated turns.',
|
|
});
|
|
}
|
|
}).default({ mode: 'legacy', maxAutomatedTurns: 3, rapportTurnsBeforeMediaAsk: 3 });
|
|
export const SubredditConfigSchema = z.strictObject({
|
|
name: z.string(),
|
|
enabled: z.boolean().default(true),
|
|
type: z.union([z.literal('image'), z.literal('chat')]),
|
|
targetingMode: z.union([z.literal('post-author'), z.literal('comment-author')]).default('post-author'),
|
|
weight: z.number().optional(),
|
|
tone: ToneKeySchema,
|
|
scripted: z.string().optional(),
|
|
conversation: ConversationBehaviourSchema,
|
|
}).superRefine((subreddit, context) => {
|
|
if (subreddit.type === 'chat' && subreddit.targetingMode === 'comment-author') {
|
|
context.addIssue({
|
|
code: 'custom',
|
|
path: ['targetingMode'],
|
|
message: 'Comment-author targeting is available only for image posts.',
|
|
});
|
|
}
|
|
});
|
|
export const ConfigResponseSchema = RuntimeConfigSchema.extend({
|
|
subreddits: z.array(SubredditConfigSchema),
|
|
tones: z.array(ToneKeySchema),
|
|
advanced: z.record(z.string(), z.unknown()).optional(),
|
|
});
|
|
export const ConfigUpdateRequestSchema = z.strictObject({
|
|
rateLimit: RateLimitConfigSchema.partial().optional(),
|
|
browser: z.strictObject({ dryRun: z.boolean().optional() }).optional(),
|
|
reddit: RuntimeRedditConfigSchema.partial().optional(),
|
|
subreddits: z.array(SubredditConfigSchema).min(1).optional(),
|
|
advanced: z.record(z.string(), z.unknown()).optional(),
|
|
});
|
|
export const ConfigUpdateResponseSchema = z.strictObject({
|
|
success: z.literal(true),
|
|
config: RuntimeConfigSchema,
|
|
subreddits: z.array(SubredditConfigSchema),
|
|
advanced: z.record(z.string(), z.unknown()).optional(),
|
|
});
|
|
|
|
export type ToneKey = z.infer<typeof ToneKeySchema>;
|
|
export type RuntimeConfig = z.infer<typeof RuntimeConfigSchema>;
|
|
export type ConfigResponse = z.infer<typeof ConfigResponseSchema>;
|
|
export type ConfigUpdateRequest = z.infer<typeof ConfigUpdateRequestSchema>;
|