import { z } from 'zod'; export const activity=z.enum(['explore','quest','socialize','trade','rest']); export const decisionSchema=z.object({action:activity,reason:z.string().min(1).max(500),goal:z.string().min(1).max(200)}).strict(); export const recipeSchema=z.object({id:z.string().max(80).optional(),name:z.string().trim().min(2).max(80),description:z.string().trim().max(500),tags:z.array(z.string().trim().min(1).max(30)).max(8),sociability:z.number().int().min(0).max(100),aggression:z.number().int().min(0).max(100),curiosity:z.number().int().min(0).max(100),economy:z.number().int().min(0).max(100),activities:z.array(activity).min(1).max(5),version:z.number().int().optional()}); const populationSchema=z.object({defaultZoneTarget:z.number().int().min(0).max(100),zoneMax:z.number().int().min(1).max(200),serverMax:z.number().int().min(1).max(1000),foregroundMax:z.number().int().min(1).max(200),backgroundMax:z.number().int().min(1).max(1000)}); const brainsSchema=z.object({enabled:z.boolean(),residentModel:z.string().trim().min(1).max(100),heroModel:z.string().trim().min(1).max(100),backgroundUseLLM:z.boolean(),residentMemoryLimit:z.number().int().min(1).max(50),heroMemoryLimit:z.number().int().min(1).max(100),residentMaxTokens:z.number().int().min(64).max(2048),heroMaxTokens:z.number().int().min(64).max(4096)}); export const actionSchema=z.discriminatedUnion('type',[ z.object({type:z.literal('retentionPolicy'),days:z.number().int().min(3).max(30)}), z.object({type:z.literal('communityPolicy'),partiesEnabled:z.boolean(),guildsEnabled:z.boolean()}), z.object({type:z.literal('guildGoal'),guildId:z.number().int().positive(),goal:z.enum(['quest','support','explore'])}), z.object({type:z.literal('createBot'),name:z.string().trim().regex(/^[A-Za-z][A-Za-z '-]{1,23}$/),role:z.enum(['Warrior','Priest','Mage','Rogue','Hunter','Paladin','Warlock','Druid','Shaman']),race:z.enum(['Human','Night Elf','Dwarf','Orc','Undead','Tauren','Gnome','Troll','Blood Elf','Draenei']),recipeId:z.string(),goal:z.string().trim().min(1).max(200)}), z.object({type:z.literal('lifecycle'),botId:z.string(),action:z.enum(['spawn','pause','resume','despawn','retire'])}), z.object({type:z.literal('think'),botId:z.string()}), z.object({type:z.literal('recordDeath'),botId:z.string(),cause:z.string().trim().min(1).max(300),killer:z.string().trim().max(120).optional(),zone:z.string().trim().max(120).optional(),confirmed:z.literal(true)}), z.object({type:z.literal('worldTrigger'),kind:z.enum(['zone-change','interaction','time','manual']),zone:z.string().trim().min(1).max(120),playerName:z.string().trim().max(40).optional(),detail:z.string().trim().max(500).optional()}), z.object({type:z.literal('assignHome'),botId:z.string(),homeId:z.string()}), z.object({type:z.literal('saveRecipe'),recipe:recipeSchema}), z.object({type:z.literal('applyRecipe'),botId:z.string(),recipeId:z.string()}), z.object({type:z.literal('memory'),botId:z.string(),text:z.string().trim().min(1).max(1000),importance:z.number().int().min(1).max(10)}), z.object({type:z.literal('relationship'),botId:z.string(),targetId:z.string(),affinity:z.number().int().min(-100).max(100),note:z.string().trim().min(1).max(300)}), z.object({type:z.literal('settings'),connector:z.enum(['simulation','azerothcore']),provider:z.enum(['deterministic','ollama','openai-compatible']),model:z.string().trim().min(1).max(100),brains:brainsSchema,hardcore:z.object({enabled:z.boolean(),requireVerifiedDeath:z.boolean(),memorialize:z.boolean()}),population:populationSchema}), z.object({type:z.literal('director'),experience:z.enum(['Adventuring companions','A lively town','Exploration and discovery','Rivalries and tension']),zone:z.string().trim().min(1).max(100),playerName:z.string().trim().max(40),brief:z.string().trim().min(1).max(500)}), z.object({type:z.literal('gm'),command:z.string().min(1).max(300),live:z.boolean(),confirmed:z.boolean().default(false)}), z.object({type:z.literal('health')}) ]);