feat: 完成 I 群組 — 生活作息與離線生活
- ScheduleService:I-1 平日/週末/假期時段表(可為角色寫入高中生預設作息)、 I-3 時間感知(Asia/Taipei 當地時間,不受伺服器時區影響)、剛醒/睡前偵測 - constants.ts:I-2 時段狀態 → 回應可用度對照(FREE/SEMI_BUSY/BUSY/SLEEP → NORMAL/BRIEF/DELAYED/NO_REPLY),沒有作息表的角色一律視為 NORMAL(相容既有角色) - ScheduleExceptionService:I-4 三種破例(深夜還陪你聊/上課偷回訊息/為你調整行程), 各自獨立冷卻期,觸發時記入關係帳本 - ScheduleEmotionBaselineService:I-5 作息驅動情緒基線(社團剛結束的疲憊、假日偏高心情), 只在本輪沒有明確情緒訊號時介入,串接進 EmotionService.processInput 的新增選項 - OfflineEventService:I-6 離線事件生成,依「今天已發生的固定行程」挑選對應模板, 一天只生成一次,寫入低權重情節記憶 - DialogueService 整合以上機制:離線事件生成 → 情緒基線標記 → 累積親密度 → 作息可用度判定 → 不符合則嘗試破例 → 依可用度決定回覆內容 - 修正真實 bug:G-5 角色建立流程誤用 source=OFFLINE_GENERATED 標記背景故事, 與 I-6「今天是否已生成離線事件」的判斷共用同一標記,已改為 SOURCE_EXTRACTION - ChatView.tsx 補上 NO_REPLY/context 為 null 的防呆(作息可用度整合後的必要調整) - scripts/smoke/I.mjs:以獨立測試角色(避免污染種子角色的排程狀態)驗證全部六項 npm run restart && npm run smoke -- I 皆通過(I-V),A~H 群組冒煙測試無回歸。
This commit is contained in:
@@ -44,6 +44,20 @@ enum RelationshipStage {
|
||||
BONDED // 羈絆 80-100
|
||||
}
|
||||
|
||||
// I-1 週期表:平日/週末/假期各一份時段表
|
||||
enum ScheduleDayType {
|
||||
WEEKDAY // 平日
|
||||
WEEKEND // 週末
|
||||
HOLIDAY // 假期/特殊日
|
||||
}
|
||||
|
||||
enum ScheduleSlotStatus {
|
||||
SLEEP // 睡眠
|
||||
BUSY // 忙碌
|
||||
SEMI_BUSY // 半忙碌
|
||||
FREE // 空閒
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
@@ -97,6 +111,9 @@ model Character {
|
||||
emotionState EmotionState?
|
||||
relationships Relationship[]
|
||||
contrastTriggerLogs ContrastTriggerLog[]
|
||||
scheduleSlots ScheduleSlot[]
|
||||
specialDays SpecialDay[]
|
||||
scheduleExceptions ScheduleExceptionLog[]
|
||||
|
||||
@@map("characters")
|
||||
}
|
||||
@@ -111,6 +128,42 @@ model ContrastTriggerLog {
|
||||
@@map("contrast_trigger_logs")
|
||||
}
|
||||
|
||||
// I-1 作息表:平日/週末/假期各一份時段表,每個時段一列。
|
||||
model ScheduleSlot {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
dayType ScheduleDayType
|
||||
startMinute Int // 當天 00:00 起算的分鐘數(0~1440),跨午夜的時段請拆成兩列
|
||||
endMinute Int
|
||||
status ScheduleSlotStatus
|
||||
label String? // 固定行程名稱,例如「社團活動」
|
||||
|
||||
@@map("schedule_slots")
|
||||
}
|
||||
|
||||
// I-1 特殊日:考試週、生日、原作紀念日——當天整天視為 HOLIDAY 作息。
|
||||
model SpecialDay {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
date DateTime // 只使用日期部分(比對年/月/日)
|
||||
label String
|
||||
|
||||
@@map("special_days")
|
||||
}
|
||||
|
||||
// I-4 破例規則:記錄每種破例最後一次觸發的時間,供稀有度冷卻判定。
|
||||
model ScheduleExceptionLog {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||
exceptionType String // LATE_NIGHT_CHAT/SNEAK_REPLY_IN_CLASS/ADJUST_SCHEDULE
|
||||
triggeredAt DateTime @default(now())
|
||||
|
||||
@@map("schedule_exception_logs")
|
||||
}
|
||||
|
||||
model CharacterAlias {
|
||||
id String @id @default(cuid())
|
||||
characterId String
|
||||
|
||||
Reference in New Issue
Block a user