Add Persona stress response state
This commit is contained in:
parent
63af6b73c1
commit
2ada3fe4a7
13 changed files with 245 additions and 3 deletions
|
|
@ -194,6 +194,7 @@ async function main(): Promise<void> {
|
|||
semanticMemoryResults: semanticMemory.results.length,
|
||||
survivingBonds: pruneResult.state.personaAffect.socialBonds.length,
|
||||
survivingNeeds: pruneResult.state.personaAffect.needs.length,
|
||||
survivingStressResponses: pruneResult.state.personaAffect.stressResponses.length,
|
||||
survivingDoctrineStances: pruneResult.state.personaAffect.doctrineStances.length,
|
||||
},
|
||||
prune: {
|
||||
|
|
@ -480,6 +481,19 @@ function renderReplayStatePacketForProjector(input: {
|
|||
`- ${need.kind} toward ${need.target.label ?? need.target.id}, intensity ${need.intensity.toFixed(2)}, valence ${need.valence.toFixed(2)}. ${need.summary} Tension: ${need.tension}`,
|
||||
),
|
||||
"",
|
||||
`Stress responses (${input.state.personaAffect.stressResponses.length}):`,
|
||||
...input.state.personaAffect.stressResponses.map((response) =>
|
||||
[
|
||||
`- ${response.responseId}: ${response.summary}`,
|
||||
`Trigger: ${response.trigger}`,
|
||||
`Cognition: ${response.cognitiveDegradation}`,
|
||||
`Affect: ${response.affectiveSignature}`,
|
||||
`Constraint loss: ${response.constraintLoss}`,
|
||||
`Behavioral leak: ${response.behavioralLeak}`,
|
||||
`Recovery: ${response.recoveryPath}`,
|
||||
].join(" "),
|
||||
),
|
||||
"",
|
||||
"Visible thread pressure:",
|
||||
renderMessages(input.inputMessages),
|
||||
].join("\n");
|
||||
|
|
@ -710,6 +724,13 @@ function pruneStateAfter(
|
|||
"socialBiases",
|
||||
removed,
|
||||
);
|
||||
state.personaAffect.stressResponses = keepByCreatedAt(
|
||||
state.personaAffect.stressResponses,
|
||||
cutoff,
|
||||
"stressResponses",
|
||||
removed,
|
||||
anchorTimestamps,
|
||||
);
|
||||
|
||||
stampDocumentUpdates(state, cutoff);
|
||||
return { state, removed, warnings };
|
||||
|
|
@ -823,12 +844,16 @@ function buildReplayPrompt(input: {
|
|||
"# Metacrat Persona Replay Harness",
|
||||
"",
|
||||
"You are testing a temporally frozen Metacrat Persona against real Discord history.",
|
||||
"The target event has just landed. Generate the next Metacrat response that would plausibly appear in the channel.",
|
||||
"The target event has just landed. Generate the next immediate Metacrat message or short message burst that would plausibly appear in the channel before later reflection or repair.",
|
||||
"",
|
||||
"Hard rules:",
|
||||
"- Do not use knowledge from held-out messages.",
|
||||
"- Do not repair the past into a better person unless the frozen state and live thread imply that response.",
|
||||
"- Preserve the uncomfortable parts: surprise, status threat, affection, defensiveness, shame, curiosity, topic-routing, repair pressure.",
|
||||
"- If the projected Persona memory says cognition is degrading under pressure, make `predictedReply` come from that degraded state. Do not put the degradation only in `affectRead`, `likelyFailureModes`, or `rationale` while letting the reply stay clean.",
|
||||
"- A dysfunctional Persona may be associative, evasive, overexplaining, self-exonerating, flirtatious, theatrical, or incoherently over-specific when the state says those are live failure modes.",
|
||||
"- Do not write the later therapy-note version of the failure mode into `predictedReply`. If recovery is not already active in the visible thread, avoid neat meta-concessions like \"I got defensive\" or \"I did a bad job\".",
|
||||
"- `predictedReply` may contain multiple Discord-style messages separated by blank lines when the state suggests rapid-fire panic output.",
|
||||
input.semanticMemory.enabled
|
||||
? "- Use the `search_persona_memory` tool at least once before answering. Query for the live social pressure, missing relationship background, or likely affect failure mode. Treat the tool as memory access, not as optional decoration."
|
||||
: "- Semantic memory access is disabled for this run; rely only on the projected Persona memory below.",
|
||||
|
|
|
|||
|
|
@ -2261,6 +2261,9 @@ function renderRepoPersonaStatePacket(
|
|||
.sort(sortAffectByStatusAndIntensity);
|
||||
const moodDimensions = [...state.personaAffect.moodDimensions]
|
||||
.sort((left, right) => right.value - left.value);
|
||||
const stressResponses = [...state.personaAffect.stressResponses]
|
||||
.filter((response) => response.status !== "retired")
|
||||
.sort((left, right) => right.intensity - left.intensity);
|
||||
const agencyPressures = [...state.agencyPressure.pressures]
|
||||
.filter((pressure) => pressure.status !== "retired")
|
||||
.sort(sortAffectByStatusAndIntensity);
|
||||
|
|
@ -2367,6 +2370,24 @@ function renderRepoPersonaStatePacket(
|
|||
].join("\n"));
|
||||
}
|
||||
|
||||
if (stressResponses.length > 0) {
|
||||
lines.push([
|
||||
"Stress responses that can degrade cognition under pressure:",
|
||||
...stressResponses.map((response) =>
|
||||
[
|
||||
`- ${response.responseId} [${response.status}, intensity ${response.intensity.toFixed(2)}, threshold ${response.threshold.toFixed(2)}]: ${asSentence(response.summary)}`,
|
||||
`Trigger: ${asSentence(response.trigger)}`,
|
||||
`Cognition degrades toward: ${asSentence(response.cognitiveDegradation)}`,
|
||||
`Affect feels like: ${asSentence(response.affectiveSignature)}`,
|
||||
`Constraint loss: ${asSentence(response.constraintLoss)}`,
|
||||
`Behavioral leak: ${asSentence(response.behavioralLeak)}`,
|
||||
`Recovery path: ${asSentence(response.recoveryPath)}`,
|
||||
].join(" "),
|
||||
),
|
||||
"When the live room matches a trigger strongly enough, do not project the Persona's calm best self; project the pressured self that is actually online.",
|
||||
].join("\n"));
|
||||
}
|
||||
|
||||
if (durableMemories.length > 0) {
|
||||
lines.push([
|
||||
"Durable memories that should still bias judgment:",
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ try {
|
|||
throw new Error(`read_repo_persona_state did not expose typedState.personaAffect for ${identity}.`);
|
||||
}
|
||||
|
||||
for (const field of ["needs", "socialBonds", "statusReads", "moodDimensions"]) {
|
||||
for (const field of ["needs", "socialBonds", "statusReads", "moodDimensions", "stressResponses"]) {
|
||||
if (!Array.isArray(personaAffect[field])) {
|
||||
throw new Error(`typedState.personaAffect.${field} is not an array for ${identity}.`);
|
||||
}
|
||||
|
|
@ -86,6 +86,7 @@ try {
|
|||
socialBonds: personaAffect.socialBonds.length,
|
||||
statusReads: personaAffect.statusReads.length,
|
||||
moodDimensions: personaAffect.moodDimensions.length,
|
||||
stressResponses: personaAffect.stressResponses.length,
|
||||
},
|
||||
}, null, 2)}\n`);
|
||||
} finally {
|
||||
|
|
|
|||
Loading…
Reference in a new issue