import { Injectable } from "@nestjs/common"; import { PrismaService } from "../prisma/prisma.service.js"; const REINFORCE_INCREMENT = 1; const CORRECTION_PENALTY = 1; // F-5 行為強化迴路:稱讚加權、糾正降權並以修正版取代,重複命中自動下沉為慣例(權重最高者)。 @Injectable() export class BehaviorReinforcementService { constructor(private readonly prisma: PrismaService) {} async reinforcePraise(characterId: string, situation: string, responsePattern: string): Promise { const existing = await this.prisma.client.proceduralRule.findFirst({ where: { characterId, situation, responsePattern }, }); if (existing) { await this.prisma.client.proceduralRule.update({ where: { id: existing.id }, data: { weight: existing.weight + REINFORCE_INCREMENT }, }); return; } await this.prisma.client.proceduralRule.create({ data: { characterId, situation, responsePattern, weight: 1 }, }); } async applyCorrection( characterId: string, situation: string, oldResponsePattern: string, newResponsePattern: string, ): Promise { const old = await this.prisma.client.proceduralRule.findFirst({ where: { characterId, situation, responsePattern: oldResponsePattern }, }); const oldWeight = old?.weight ?? 1; if (old) { await this.prisma.client.proceduralRule.update({ where: { id: old.id }, data: { weight: Math.max(0, oldWeight - CORRECTION_PENALTY) }, }); } // 修正版直接繼承舊模式修正前的權重,確保取代後排序上必定領先(避免降權後打平)。 const existingNew = await this.prisma.client.proceduralRule.findFirst({ where: { characterId, situation, responsePattern: newResponsePattern }, }); const inheritedWeight = Math.max(oldWeight, 1); if (existingNew) { await this.prisma.client.proceduralRule.update({ where: { id: existingNew.id }, data: { weight: existingNew.weight + inheritedWeight }, }); } else { await this.prisma.client.proceduralRule.create({ data: { characterId, situation, responsePattern: newResponsePattern, weight: inheritedWeight }, }); } } async getTopRule(characterId: string, situation: string) { return this.prisma.client.proceduralRule.findFirst({ where: { characterId, situation }, orderBy: { weight: "desc" }, }); } }