@sharpee/character 0.9.106 → 0.9.107
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apply.d.ts +29 -7
- package/apply.d.ts.map +1 -1
- package/apply.js +15 -7
- package/apply.js.map +1 -1
- package/character-builder.d.ts +67 -4
- package/character-builder.d.ts.map +1 -1
- package/character-builder.js +116 -7
- package/character-builder.js.map +1 -1
- package/conversation/acl.d.ts +62 -0
- package/conversation/acl.d.ts.map +1 -0
- package/conversation/acl.js +117 -0
- package/conversation/acl.js.map +1 -0
- package/conversation/builder.d.ts +247 -0
- package/conversation/builder.d.ts.map +1 -0
- package/conversation/builder.js +324 -0
- package/conversation/builder.js.map +1 -0
- package/conversation/constraint-evaluator.d.ts +147 -0
- package/conversation/constraint-evaluator.d.ts.map +1 -0
- package/conversation/constraint-evaluator.js +247 -0
- package/conversation/constraint-evaluator.js.map +1 -0
- package/conversation/conversation-messages.d.ts +56 -0
- package/conversation/conversation-messages.d.ts.map +1 -0
- package/conversation/conversation-messages.js +69 -0
- package/conversation/conversation-messages.js.map +1 -0
- package/conversation/dialogue-extension.d.ts +87 -0
- package/conversation/dialogue-extension.d.ts.map +1 -0
- package/conversation/dialogue-extension.js +302 -0
- package/conversation/dialogue-extension.js.map +1 -0
- package/conversation/dialogue-types.d.ts +71 -0
- package/conversation/dialogue-types.d.ts.map +1 -0
- package/conversation/dialogue-types.js +13 -0
- package/conversation/dialogue-types.js.map +1 -0
- package/conversation/index.d.ts +19 -0
- package/conversation/index.d.ts.map +1 -0
- package/conversation/index.js +37 -0
- package/conversation/index.js.map +1 -0
- package/conversation/lifecycle.d.ts +212 -0
- package/conversation/lifecycle.d.ts.map +1 -0
- package/conversation/lifecycle.js +348 -0
- package/conversation/lifecycle.js.map +1 -0
- package/conversation/response-types.d.ts +98 -0
- package/conversation/response-types.d.ts.map +1 -0
- package/conversation/response-types.js +30 -0
- package/conversation/response-types.js.map +1 -0
- package/conversation/topic-registry.d.ts +130 -0
- package/conversation/topic-registry.d.ts.map +1 -0
- package/conversation/topic-registry.js +187 -0
- package/conversation/topic-registry.js.map +1 -0
- package/goals/builder.d.ts +135 -0
- package/goals/builder.d.ts.map +1 -0
- package/goals/builder.js +193 -0
- package/goals/builder.js.map +1 -0
- package/goals/goal-activation.d.ts +99 -0
- package/goals/goal-activation.d.ts.map +1 -0
- package/goals/goal-activation.js +212 -0
- package/goals/goal-activation.js.map +1 -0
- package/goals/goal-types.d.ts +138 -0
- package/goals/goal-types.d.ts.map +1 -0
- package/goals/goal-types.js +20 -0
- package/goals/goal-types.js.map +1 -0
- package/goals/index.d.ts +15 -0
- package/goals/index.d.ts.map +1 -0
- package/goals/index.js +24 -0
- package/goals/index.js.map +1 -0
- package/goals/pathfinding.d.ts +67 -0
- package/goals/pathfinding.d.ts.map +1 -0
- package/goals/pathfinding.js +134 -0
- package/goals/pathfinding.js.map +1 -0
- package/goals/step-evaluator.d.ts +52 -0
- package/goals/step-evaluator.d.ts.map +1 -0
- package/goals/step-evaluator.js +153 -0
- package/goals/step-evaluator.js.map +1 -0
- package/index.d.ts +6 -1
- package/index.d.ts.map +1 -1
- package/index.js +60 -1
- package/index.js.map +1 -1
- package/influence/builder.d.ts +136 -0
- package/influence/builder.d.ts.map +1 -0
- package/influence/builder.js +198 -0
- package/influence/builder.js.map +1 -0
- package/influence/index.d.ts +16 -0
- package/influence/index.d.ts.map +1 -0
- package/influence/index.js +25 -0
- package/influence/index.js.map +1 -0
- package/influence/influence-duration.d.ts +82 -0
- package/influence/influence-duration.d.ts.map +1 -0
- package/influence/influence-duration.js +148 -0
- package/influence/influence-duration.js.map +1 -0
- package/influence/influence-evaluator.d.ts +55 -0
- package/influence/influence-evaluator.d.ts.map +1 -0
- package/influence/influence-evaluator.js +183 -0
- package/influence/influence-evaluator.js.map +1 -0
- package/influence/influence-messages.d.ts +30 -0
- package/influence/influence-messages.d.ts.map +1 -0
- package/influence/influence-messages.js +40 -0
- package/influence/influence-messages.js.map +1 -0
- package/influence/influence-types.d.ts +123 -0
- package/influence/influence-types.d.ts.map +1 -0
- package/influence/influence-types.js +12 -0
- package/influence/influence-types.js.map +1 -0
- package/influence/pc-influence.d.ts +38 -0
- package/influence/pc-influence.d.ts.map +1 -0
- package/influence/pc-influence.js +56 -0
- package/influence/pc-influence.js.map +1 -0
- package/package.json +4 -3
- package/propagation/builder.d.ts +47 -0
- package/propagation/builder.d.ts.map +1 -0
- package/propagation/builder.js +46 -0
- package/propagation/builder.js.map +1 -0
- package/propagation/fact-transfer.d.ts +47 -0
- package/propagation/fact-transfer.d.ts.map +1 -0
- package/propagation/fact-transfer.js +76 -0
- package/propagation/fact-transfer.js.map +1 -0
- package/propagation/index.d.ts +16 -0
- package/propagation/index.d.ts.map +1 -0
- package/propagation/index.js +28 -0
- package/propagation/index.js.map +1 -0
- package/propagation/propagation-evaluator.d.ts +53 -0
- package/propagation/propagation-evaluator.d.ts.map +1 -0
- package/propagation/propagation-evaluator.js +231 -0
- package/propagation/propagation-evaluator.js.map +1 -0
- package/propagation/propagation-messages.d.ts +30 -0
- package/propagation/propagation-messages.d.ts.map +1 -0
- package/propagation/propagation-messages.js +37 -0
- package/propagation/propagation-messages.js.map +1 -0
- package/propagation/propagation-types.d.ts +100 -0
- package/propagation/propagation-types.d.ts.map +1 -0
- package/propagation/propagation-types.js +68 -0
- package/propagation/propagation-types.js.map +1 -0
- package/propagation/visibility.d.ts +46 -0
- package/propagation/visibility.d.ts.map +1 -0
- package/propagation/visibility.js +79 -0
- package/propagation/visibility.js.map +1 -0
- package/tick-phases.d.ts +93 -0
- package/tick-phases.d.ts.map +1 -0
- package/tick-phases.js +433 -0
- package/tick-phases.js.map +1 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constraint evaluator (ADR-142)
|
|
3
|
+
*
|
|
4
|
+
* Evaluates authored response constraints against NPC character state
|
|
5
|
+
* to select the appropriate response. Uses first-match-wins ordering
|
|
6
|
+
* with .otherwise() fallback.
|
|
7
|
+
*
|
|
8
|
+
* Also handles response recording, contradiction detection, and
|
|
9
|
+
* evidence tracking.
|
|
10
|
+
*
|
|
11
|
+
* Public interface: evaluateConstraints, ConstraintEvaluator.
|
|
12
|
+
* Owner context: @sharpee/character / conversation
|
|
13
|
+
*/
|
|
14
|
+
import { CharacterModelTrait } from "../../world-model/index";
|
|
15
|
+
import { ResponseCandidate, ResponseAction, ConversationRecord, ConversationEntry, EvidenceEntry } from './response-types';
|
|
16
|
+
/** A detected contradiction in conversation history. */
|
|
17
|
+
export interface Contradiction {
|
|
18
|
+
/** The topic where the contradiction was detected. */
|
|
19
|
+
topic: string;
|
|
20
|
+
/** The previous response action for this topic. */
|
|
21
|
+
previousAction: ResponseAction;
|
|
22
|
+
/** The new response action that contradicts the previous one. */
|
|
23
|
+
currentAction: ResponseAction;
|
|
24
|
+
/** Turn of the previous response. */
|
|
25
|
+
previousTurn: number;
|
|
26
|
+
/** Turn of the current response. */
|
|
27
|
+
currentTurn: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Evaluate a list of response candidates against NPC character state.
|
|
31
|
+
* Uses first-match-wins: the first candidate whose constraints are all
|
|
32
|
+
* satisfied is selected. Empty constraints means "always matches"
|
|
33
|
+
* (the .otherwise() fallback).
|
|
34
|
+
*
|
|
35
|
+
* @param candidates - Ordered list of response candidates for this topic
|
|
36
|
+
* @param npcTrait - The NPC's CharacterModelTrait for predicate evaluation
|
|
37
|
+
* @returns The selected candidate, or undefined if no candidate matches
|
|
38
|
+
*/
|
|
39
|
+
export declare function evaluateConstraints(candidates: ResponseCandidate[], npcTrait: CharacterModelTrait): ResponseCandidate | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Stateful constraint evaluator that tracks conversation history,
|
|
42
|
+
* detects contradictions, and records evidence presentations.
|
|
43
|
+
*
|
|
44
|
+
* One instance per NPC. State survives save/restore.
|
|
45
|
+
*/
|
|
46
|
+
export declare class ConstraintEvaluator {
|
|
47
|
+
/** Per-NPC conversation records. Keyed by NPC entity ID. */
|
|
48
|
+
private readonly records;
|
|
49
|
+
/** Evidence the player has presented. Keyed by NPC entity ID. */
|
|
50
|
+
private readonly evidence;
|
|
51
|
+
/**
|
|
52
|
+
* Evaluate constraints and select the best response for a topic.
|
|
53
|
+
*
|
|
54
|
+
* @param candidates - Ordered response candidates
|
|
55
|
+
* @param npcTrait - NPC's character model trait
|
|
56
|
+
* @returns The selected candidate, or undefined
|
|
57
|
+
*/
|
|
58
|
+
evaluate(candidates: ResponseCandidate[], npcTrait: CharacterModelTrait): ResponseCandidate | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Record that an NPC gave a specific response to a topic.
|
|
61
|
+
* Updates both the current response and the history.
|
|
62
|
+
*
|
|
63
|
+
* @param npcId - The NPC entity ID
|
|
64
|
+
* @param topic - The topic name
|
|
65
|
+
* @param action - The response action taken
|
|
66
|
+
* @param turn - The current turn number
|
|
67
|
+
* @returns A Contradiction if this response contradicts a previous one, or undefined
|
|
68
|
+
*/
|
|
69
|
+
recordResponse(npcId: string, topic: string, action: ResponseAction, turn: number): Contradiction | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Get the conversation record for an NPC.
|
|
72
|
+
*
|
|
73
|
+
* @param npcId - The NPC entity ID
|
|
74
|
+
* @returns The conversation record, or undefined if no conversation has occurred
|
|
75
|
+
*/
|
|
76
|
+
getRecord(npcId: string): ConversationRecord | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* Check whether a topic has been discussed with an NPC.
|
|
79
|
+
*
|
|
80
|
+
* @param npcId - The NPC entity ID
|
|
81
|
+
* @param topic - The topic name
|
|
82
|
+
* @returns True if the topic has been discussed
|
|
83
|
+
*/
|
|
84
|
+
hasDiscussed(npcId: string, topic: string): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Get the most recent response action for a topic.
|
|
87
|
+
*
|
|
88
|
+
* @param npcId - The NPC entity ID
|
|
89
|
+
* @param topic - The topic name
|
|
90
|
+
* @returns The most recent conversation entry, or undefined
|
|
91
|
+
*/
|
|
92
|
+
getLastResponse(npcId: string, topic: string): ConversationEntry | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Record that the player presented evidence/information to an NPC.
|
|
95
|
+
*
|
|
96
|
+
* @param npcId - The NPC entity ID
|
|
97
|
+
* @param topic - The evidence topic
|
|
98
|
+
* @param turn - The current turn number
|
|
99
|
+
*/
|
|
100
|
+
recordEvidence(npcId: string, topic: string, turn: number): void;
|
|
101
|
+
/**
|
|
102
|
+
* Check whether the player has presented specific evidence to an NPC.
|
|
103
|
+
*
|
|
104
|
+
* @param npcId - The NPC entity ID
|
|
105
|
+
* @param topic - The evidence topic
|
|
106
|
+
* @returns True if this evidence has been presented
|
|
107
|
+
*/
|
|
108
|
+
hasPresented(npcId: string, topic: string): boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Get all evidence presented to an NPC.
|
|
111
|
+
*
|
|
112
|
+
* @param npcId - The NPC entity ID
|
|
113
|
+
* @returns Array of evidence entries, or empty array
|
|
114
|
+
*/
|
|
115
|
+
getEvidence(npcId: string): EvidenceEntry[];
|
|
116
|
+
/**
|
|
117
|
+
* Export state for save/restore.
|
|
118
|
+
* Converts Maps to plain objects for JSON serialization.
|
|
119
|
+
*/
|
|
120
|
+
toJSON(): ConstraintEvaluatorState;
|
|
121
|
+
/**
|
|
122
|
+
* Restore state from serialized data.
|
|
123
|
+
*
|
|
124
|
+
* @param state - Previously serialized state
|
|
125
|
+
*/
|
|
126
|
+
static fromJSON(state: ConstraintEvaluatorState): ConstraintEvaluator;
|
|
127
|
+
/** Get or create a conversation record for an NPC. */
|
|
128
|
+
private getOrCreateRecord;
|
|
129
|
+
/**
|
|
130
|
+
* Determine if two response actions constitute a contradiction.
|
|
131
|
+
* A contradiction occurs when the NPC's story changes — telling the truth
|
|
132
|
+
* after lying, confessing after deflecting, etc.
|
|
133
|
+
*/
|
|
134
|
+
private isContradiction;
|
|
135
|
+
}
|
|
136
|
+
/** Serialized conversation record (Maps converted to plain objects). */
|
|
137
|
+
interface SerializedConversationRecord {
|
|
138
|
+
responses: Record<string, ConversationEntry>;
|
|
139
|
+
history: Record<string, ConversationEntry[]>;
|
|
140
|
+
}
|
|
141
|
+
/** Full serialized state of a ConstraintEvaluator. */
|
|
142
|
+
export interface ConstraintEvaluatorState {
|
|
143
|
+
records: Record<string, SerializedConversationRecord>;
|
|
144
|
+
evidence: Record<string, EvidenceEntry[]>;
|
|
145
|
+
}
|
|
146
|
+
export {};
|
|
147
|
+
//# sourceMappingURL=constraint-evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constraint-evaluator.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/character/src/conversation/constraint-evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EAEjB,aAAa,EAGd,MAAM,kBAAkB,CAAC;AAM1B,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IAEd,mDAAmD;IACnD,cAAc,EAAE,cAAc,CAAC;IAE/B,iEAAiE;IACjE,aAAa,EAAE,cAAc,CAAC;IAE9B,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;IAErB,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,QAAQ,EAAE,mBAAmB,GAC5B,iBAAiB,GAAG,SAAS,CAiB/B;AAMD;;;;;GAKG;AACH,qBAAa,mBAAmB;IAC9B,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8C;IAEtE,iEAAiE;IACjE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;IAMnE;;;;;;OAMG;IACH,QAAQ,CACN,UAAU,EAAE,iBAAiB,EAAE,EAC/B,QAAQ,EAAE,mBAAmB,GAC5B,iBAAiB,GAAG,SAAS;IAIhC;;;;;;;;;OASG;IACH,cAAc,CACZ,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,MAAM,GACX,aAAa,GAAG,SAAS;IA6B5B;;;;;OAKG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAIxD;;;;;;OAMG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAKnD;;;;;;OAMG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAQ5E;;;;;;OAMG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAMhE;;;;;;OAMG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAKnD;;;;;OAKG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE;IAQ3C;;;OAGG;IACH,MAAM,IAAI,wBAAwB;IAmBlC;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,wBAAwB,GAAG,mBAAmB;IAsBrE,sDAAsD;IACtD,OAAO,CAAC,iBAAiB;IASzB;;;;OAIG;IACH,OAAO,CAAC,eAAe;CAqBxB;AAMD,wEAAwE;AACxE,UAAU,4BAA4B;IACpC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;CAC9C;AAED,sDAAsD;AACtD,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC;IACtD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;CAC3C"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Constraint evaluator (ADR-142)
|
|
4
|
+
*
|
|
5
|
+
* Evaluates authored response constraints against NPC character state
|
|
6
|
+
* to select the appropriate response. Uses first-match-wins ordering
|
|
7
|
+
* with .otherwise() fallback.
|
|
8
|
+
*
|
|
9
|
+
* Also handles response recording, contradiction detection, and
|
|
10
|
+
* evidence tracking.
|
|
11
|
+
*
|
|
12
|
+
* Public interface: evaluateConstraints, ConstraintEvaluator.
|
|
13
|
+
* Owner context: @sharpee/character / conversation
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.ConstraintEvaluator = void 0;
|
|
17
|
+
exports.evaluateConstraints = evaluateConstraints;
|
|
18
|
+
const response_types_1 = require("./response-types");
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Pure evaluation function
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
/**
|
|
23
|
+
* Evaluate a list of response candidates against NPC character state.
|
|
24
|
+
* Uses first-match-wins: the first candidate whose constraints are all
|
|
25
|
+
* satisfied is selected. Empty constraints means "always matches"
|
|
26
|
+
* (the .otherwise() fallback).
|
|
27
|
+
*
|
|
28
|
+
* @param candidates - Ordered list of response candidates for this topic
|
|
29
|
+
* @param npcTrait - The NPC's CharacterModelTrait for predicate evaluation
|
|
30
|
+
* @returns The selected candidate, or undefined if no candidate matches
|
|
31
|
+
*/
|
|
32
|
+
function evaluateConstraints(candidates, npcTrait) {
|
|
33
|
+
for (const candidate of candidates) {
|
|
34
|
+
if (candidate.constraints.length === 0) {
|
|
35
|
+
// .otherwise() — always matches
|
|
36
|
+
return candidate;
|
|
37
|
+
}
|
|
38
|
+
const allSatisfied = candidate.constraints.every(pred => npcTrait.evaluate(pred));
|
|
39
|
+
if (allSatisfied) {
|
|
40
|
+
return candidate;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Stateful evaluator (owns conversation records and evidence)
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
/**
|
|
49
|
+
* Stateful constraint evaluator that tracks conversation history,
|
|
50
|
+
* detects contradictions, and records evidence presentations.
|
|
51
|
+
*
|
|
52
|
+
* One instance per NPC. State survives save/restore.
|
|
53
|
+
*/
|
|
54
|
+
class ConstraintEvaluator {
|
|
55
|
+
/** Per-NPC conversation records. Keyed by NPC entity ID. */
|
|
56
|
+
records = new Map();
|
|
57
|
+
/** Evidence the player has presented. Keyed by NPC entity ID. */
|
|
58
|
+
evidence = (0, response_types_1.createEvidenceRecord)();
|
|
59
|
+
// =========================================================================
|
|
60
|
+
// Response evaluation and recording
|
|
61
|
+
// =========================================================================
|
|
62
|
+
/**
|
|
63
|
+
* Evaluate constraints and select the best response for a topic.
|
|
64
|
+
*
|
|
65
|
+
* @param candidates - Ordered response candidates
|
|
66
|
+
* @param npcTrait - NPC's character model trait
|
|
67
|
+
* @returns The selected candidate, or undefined
|
|
68
|
+
*/
|
|
69
|
+
evaluate(candidates, npcTrait) {
|
|
70
|
+
return evaluateConstraints(candidates, npcTrait);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Record that an NPC gave a specific response to a topic.
|
|
74
|
+
* Updates both the current response and the history.
|
|
75
|
+
*
|
|
76
|
+
* @param npcId - The NPC entity ID
|
|
77
|
+
* @param topic - The topic name
|
|
78
|
+
* @param action - The response action taken
|
|
79
|
+
* @param turn - The current turn number
|
|
80
|
+
* @returns A Contradiction if this response contradicts a previous one, or undefined
|
|
81
|
+
*/
|
|
82
|
+
recordResponse(npcId, topic, action, turn) {
|
|
83
|
+
const record = this.getOrCreateRecord(npcId);
|
|
84
|
+
const entry = { action, turn };
|
|
85
|
+
// Check for contradiction before updating
|
|
86
|
+
const previous = record.responses.get(topic);
|
|
87
|
+
let contradiction;
|
|
88
|
+
if (previous && this.isContradiction(previous.action, action)) {
|
|
89
|
+
contradiction = {
|
|
90
|
+
topic,
|
|
91
|
+
previousAction: previous.action,
|
|
92
|
+
currentAction: action,
|
|
93
|
+
previousTurn: previous.turn,
|
|
94
|
+
currentTurn: turn,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// Update current response
|
|
98
|
+
record.responses.set(topic, entry);
|
|
99
|
+
// Append to history
|
|
100
|
+
const history = record.history.get(topic) ?? [];
|
|
101
|
+
history.push(entry);
|
|
102
|
+
record.history.set(topic, history);
|
|
103
|
+
return contradiction;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get the conversation record for an NPC.
|
|
107
|
+
*
|
|
108
|
+
* @param npcId - The NPC entity ID
|
|
109
|
+
* @returns The conversation record, or undefined if no conversation has occurred
|
|
110
|
+
*/
|
|
111
|
+
getRecord(npcId) {
|
|
112
|
+
return this.records.get(npcId);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Check whether a topic has been discussed with an NPC.
|
|
116
|
+
*
|
|
117
|
+
* @param npcId - The NPC entity ID
|
|
118
|
+
* @param topic - The topic name
|
|
119
|
+
* @returns True if the topic has been discussed
|
|
120
|
+
*/
|
|
121
|
+
hasDiscussed(npcId, topic) {
|
|
122
|
+
const record = this.records.get(npcId);
|
|
123
|
+
return record?.responses.has(topic) ?? false;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get the most recent response action for a topic.
|
|
127
|
+
*
|
|
128
|
+
* @param npcId - The NPC entity ID
|
|
129
|
+
* @param topic - The topic name
|
|
130
|
+
* @returns The most recent conversation entry, or undefined
|
|
131
|
+
*/
|
|
132
|
+
getLastResponse(npcId, topic) {
|
|
133
|
+
return this.records.get(npcId)?.responses.get(topic);
|
|
134
|
+
}
|
|
135
|
+
// =========================================================================
|
|
136
|
+
// Evidence tracking
|
|
137
|
+
// =========================================================================
|
|
138
|
+
/**
|
|
139
|
+
* Record that the player presented evidence/information to an NPC.
|
|
140
|
+
*
|
|
141
|
+
* @param npcId - The NPC entity ID
|
|
142
|
+
* @param topic - The evidence topic
|
|
143
|
+
* @param turn - The current turn number
|
|
144
|
+
*/
|
|
145
|
+
recordEvidence(npcId, topic, turn) {
|
|
146
|
+
const entries = this.evidence.get(npcId) ?? [];
|
|
147
|
+
entries.push({ topic, turn });
|
|
148
|
+
this.evidence.set(npcId, entries);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Check whether the player has presented specific evidence to an NPC.
|
|
152
|
+
*
|
|
153
|
+
* @param npcId - The NPC entity ID
|
|
154
|
+
* @param topic - The evidence topic
|
|
155
|
+
* @returns True if this evidence has been presented
|
|
156
|
+
*/
|
|
157
|
+
hasPresented(npcId, topic) {
|
|
158
|
+
const entries = this.evidence.get(npcId);
|
|
159
|
+
return entries?.some(e => e.topic === topic) ?? false;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get all evidence presented to an NPC.
|
|
163
|
+
*
|
|
164
|
+
* @param npcId - The NPC entity ID
|
|
165
|
+
* @returns Array of evidence entries, or empty array
|
|
166
|
+
*/
|
|
167
|
+
getEvidence(npcId) {
|
|
168
|
+
return this.evidence.get(npcId) ?? [];
|
|
169
|
+
}
|
|
170
|
+
// =========================================================================
|
|
171
|
+
// Serialization support
|
|
172
|
+
// =========================================================================
|
|
173
|
+
/**
|
|
174
|
+
* Export state for save/restore.
|
|
175
|
+
* Converts Maps to plain objects for JSON serialization.
|
|
176
|
+
*/
|
|
177
|
+
toJSON() {
|
|
178
|
+
const records = {};
|
|
179
|
+
for (const [npcId, record] of this.records) {
|
|
180
|
+
records[npcId] = {
|
|
181
|
+
responses: Object.fromEntries(record.responses),
|
|
182
|
+
history: Object.fromEntries(Array.from(record.history.entries()).map(([topic, entries]) => [topic, entries])),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
const evidence = {};
|
|
186
|
+
for (const [npcId, entries] of this.evidence) {
|
|
187
|
+
evidence[npcId] = entries;
|
|
188
|
+
}
|
|
189
|
+
return { records, evidence };
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Restore state from serialized data.
|
|
193
|
+
*
|
|
194
|
+
* @param state - Previously serialized state
|
|
195
|
+
*/
|
|
196
|
+
static fromJSON(state) {
|
|
197
|
+
const evaluator = new ConstraintEvaluator();
|
|
198
|
+
for (const [npcId, serialized] of Object.entries(state.records)) {
|
|
199
|
+
const record = {
|
|
200
|
+
responses: new Map(Object.entries(serialized.responses)),
|
|
201
|
+
history: new Map(Object.entries(serialized.history)),
|
|
202
|
+
};
|
|
203
|
+
evaluator.records.set(npcId, record);
|
|
204
|
+
}
|
|
205
|
+
for (const [npcId, entries] of Object.entries(state.evidence)) {
|
|
206
|
+
evaluator.evidence.set(npcId, entries);
|
|
207
|
+
}
|
|
208
|
+
return evaluator;
|
|
209
|
+
}
|
|
210
|
+
// =========================================================================
|
|
211
|
+
// Private helpers
|
|
212
|
+
// =========================================================================
|
|
213
|
+
/** Get or create a conversation record for an NPC. */
|
|
214
|
+
getOrCreateRecord(npcId) {
|
|
215
|
+
let record = this.records.get(npcId);
|
|
216
|
+
if (!record) {
|
|
217
|
+
record = (0, response_types_1.createConversationRecord)();
|
|
218
|
+
this.records.set(npcId, record);
|
|
219
|
+
}
|
|
220
|
+
return record;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Determine if two response actions constitute a contradiction.
|
|
224
|
+
* A contradiction occurs when the NPC's story changes — telling the truth
|
|
225
|
+
* after lying, confessing after deflecting, etc.
|
|
226
|
+
*/
|
|
227
|
+
isContradiction(previous, current) {
|
|
228
|
+
// Same action is never a contradiction
|
|
229
|
+
if (previous === current)
|
|
230
|
+
return false;
|
|
231
|
+
// These pairs are contradictory — the NPC's story changed
|
|
232
|
+
const contradictoryPairs = [
|
|
233
|
+
['tell', 'lie'],
|
|
234
|
+
['lie', 'tell'],
|
|
235
|
+
['lie', 'confess'],
|
|
236
|
+
['deflect', 'confess'],
|
|
237
|
+
['refuse', 'confess'],
|
|
238
|
+
['omit', 'tell'],
|
|
239
|
+
['omit', 'confess'],
|
|
240
|
+
['confabulate', 'tell'],
|
|
241
|
+
['confabulate', 'confess'],
|
|
242
|
+
];
|
|
243
|
+
return contradictoryPairs.some(([a, b]) => previous === a && current === b);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
exports.ConstraintEvaluator = ConstraintEvaluator;
|
|
247
|
+
//# sourceMappingURL=constraint-evaluator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constraint-evaluator.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/character/src/conversation/constraint-evaluator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation message IDs (ADR-142)
|
|
3
|
+
*
|
|
4
|
+
* Semantic message IDs for conversation system events.
|
|
5
|
+
* Actual text is provided by the language layer (lang-en-us).
|
|
6
|
+
*
|
|
7
|
+
* Public interface: ConversationMessages.
|
|
8
|
+
* Owner context: @sharpee/character / conversation
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Platform default message IDs for the conversation system.
|
|
12
|
+
* Authors override these per-NPC; these serve as fallbacks.
|
|
13
|
+
*/
|
|
14
|
+
export declare const ConversationMessages: {
|
|
15
|
+
/** Framing for deflect responses. */
|
|
16
|
+
readonly RESPONSE_DEFLECT: "character.conversation.response.deflect";
|
|
17
|
+
/** Framing for refuse responses. */
|
|
18
|
+
readonly RESPONSE_REFUSE: "character.conversation.response.refuse";
|
|
19
|
+
/** Framing for confabulate responses (NPC fills in gaps). */
|
|
20
|
+
readonly RESPONSE_CONFABULATE: "character.conversation.response.confabulate";
|
|
21
|
+
/** Framing for omit responses (NPC knows but stays silent). */
|
|
22
|
+
readonly RESPONSE_OMIT: "character.conversation.response.omit";
|
|
23
|
+
/** Fragmented speech (low coherence). */
|
|
24
|
+
readonly COGNITIVE_FRAGMENTED: "character.conversation.cognitive.fragmented";
|
|
25
|
+
/** Drifting speech (mid coherence, tangential). */
|
|
26
|
+
readonly COGNITIVE_DRIFTING: "character.conversation.cognitive.drifting";
|
|
27
|
+
/** Detached speech (low selfModel, flat affect). */
|
|
28
|
+
readonly COGNITIVE_DETACHED: "character.conversation.cognitive.detached";
|
|
29
|
+
/** Eager NPC, first non-conversation turn. */
|
|
30
|
+
readonly BETWEEN_TURN_EAGER_1: "character.conversation.between.eager.1";
|
|
31
|
+
/** Eager NPC, third+ non-conversation turn. */
|
|
32
|
+
readonly BETWEEN_TURN_EAGER_3: "character.conversation.between.eager.3";
|
|
33
|
+
/** Reluctant NPC, first non-conversation turn. */
|
|
34
|
+
readonly BETWEEN_TURN_RELUCTANT_1: "character.conversation.between.reluctant.1";
|
|
35
|
+
/** Hostile NPC, first non-conversation turn. */
|
|
36
|
+
readonly BETWEEN_TURN_HOSTILE_1: "character.conversation.between.hostile.1";
|
|
37
|
+
/** Confessing NPC, first non-conversation turn. */
|
|
38
|
+
readonly BETWEEN_TURN_CONFESSING_1: "character.conversation.between.confessing.1";
|
|
39
|
+
/** Confessing NPC, third non-conversation turn. */
|
|
40
|
+
readonly BETWEEN_TURN_CONFESSING_3: "character.conversation.between.confessing.3";
|
|
41
|
+
/** Neutral NPC, third+ non-conversation turn (default decay). */
|
|
42
|
+
readonly BETWEEN_TURN_NEUTRAL_3: "character.conversation.between.neutral.3";
|
|
43
|
+
/** NPC yields attention when player redirects to another NPC. */
|
|
44
|
+
readonly ATTENTION_YIELDS: "character.conversation.attention.yields";
|
|
45
|
+
/** NPC protests when player redirects but doesn't block. */
|
|
46
|
+
readonly ATTENTION_PROTESTS: "character.conversation.attention.protests";
|
|
47
|
+
/** NPC blocks player from redirecting (strong attention hold). */
|
|
48
|
+
readonly ATTENTION_BLOCKS: "character.conversation.attention.blocks";
|
|
49
|
+
/** Conversation ends naturally (goodbye). */
|
|
50
|
+
readonly CONVERSATION_ENDS: "character.conversation.ends";
|
|
51
|
+
/** NPC initiates conversation. */
|
|
52
|
+
readonly CONVERSATION_INITIATES: "character.conversation.initiates";
|
|
53
|
+
};
|
|
54
|
+
/** Type for conversation message IDs. */
|
|
55
|
+
export type ConversationMessageId = (typeof ConversationMessages)[keyof typeof ConversationMessages];
|
|
56
|
+
//# sourceMappingURL=conversation-messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-messages.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/character/src/conversation/conversation-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB;IAK/B,qCAAqC;;IAErC,oCAAoC;;IAEpC,6DAA6D;;IAE7D,+DAA+D;;IAO/D,yCAAyC;;IAEzC,mDAAmD;;IAEnD,oDAAoD;;IAOpD,8CAA8C;;IAE9C,+CAA+C;;IAE/C,kDAAkD;;IAElD,gDAAgD;;IAEhD,mDAAmD;;IAEnD,mDAAmD;;IAEnD,iEAAiE;;IAOjE,iEAAiE;;IAEjE,4DAA4D;;IAE5D,kEAAkE;;IAElE,6CAA6C;;IAE7C,kCAAkC;;CAE1B,CAAC;AAEX,yCAAyC;AACzC,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,OAAO,oBAAoB,CAAC,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Conversation message IDs (ADR-142)
|
|
4
|
+
*
|
|
5
|
+
* Semantic message IDs for conversation system events.
|
|
6
|
+
* Actual text is provided by the language layer (lang-en-us).
|
|
7
|
+
*
|
|
8
|
+
* Public interface: ConversationMessages.
|
|
9
|
+
* Owner context: @sharpee/character / conversation
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ConversationMessages = void 0;
|
|
13
|
+
/**
|
|
14
|
+
* Platform default message IDs for the conversation system.
|
|
15
|
+
* Authors override these per-NPC; these serve as fallbacks.
|
|
16
|
+
*/
|
|
17
|
+
exports.ConversationMessages = {
|
|
18
|
+
// -------------------------------------------------------------------------
|
|
19
|
+
// Response action framing — wraps author message with response type context
|
|
20
|
+
// -------------------------------------------------------------------------
|
|
21
|
+
/** Framing for deflect responses. */
|
|
22
|
+
RESPONSE_DEFLECT: 'character.conversation.response.deflect',
|
|
23
|
+
/** Framing for refuse responses. */
|
|
24
|
+
RESPONSE_REFUSE: 'character.conversation.response.refuse',
|
|
25
|
+
/** Framing for confabulate responses (NPC fills in gaps). */
|
|
26
|
+
RESPONSE_CONFABULATE: 'character.conversation.response.confabulate',
|
|
27
|
+
/** Framing for omit responses (NPC knows but stays silent). */
|
|
28
|
+
RESPONSE_OMIT: 'character.conversation.response.omit',
|
|
29
|
+
// -------------------------------------------------------------------------
|
|
30
|
+
// Cognitive speech patterns — applied when NPC has cognitive state
|
|
31
|
+
// -------------------------------------------------------------------------
|
|
32
|
+
/** Fragmented speech (low coherence). */
|
|
33
|
+
COGNITIVE_FRAGMENTED: 'character.conversation.cognitive.fragmented',
|
|
34
|
+
/** Drifting speech (mid coherence, tangential). */
|
|
35
|
+
COGNITIVE_DRIFTING: 'character.conversation.cognitive.drifting',
|
|
36
|
+
/** Detached speech (low selfModel, flat affect). */
|
|
37
|
+
COGNITIVE_DETACHED: 'character.conversation.cognitive.detached',
|
|
38
|
+
// -------------------------------------------------------------------------
|
|
39
|
+
// Between-turn defaults — NPC commentary when player does other things
|
|
40
|
+
// -------------------------------------------------------------------------
|
|
41
|
+
/** Eager NPC, first non-conversation turn. */
|
|
42
|
+
BETWEEN_TURN_EAGER_1: 'character.conversation.between.eager.1',
|
|
43
|
+
/** Eager NPC, third+ non-conversation turn. */
|
|
44
|
+
BETWEEN_TURN_EAGER_3: 'character.conversation.between.eager.3',
|
|
45
|
+
/** Reluctant NPC, first non-conversation turn. */
|
|
46
|
+
BETWEEN_TURN_RELUCTANT_1: 'character.conversation.between.reluctant.1',
|
|
47
|
+
/** Hostile NPC, first non-conversation turn. */
|
|
48
|
+
BETWEEN_TURN_HOSTILE_1: 'character.conversation.between.hostile.1',
|
|
49
|
+
/** Confessing NPC, first non-conversation turn. */
|
|
50
|
+
BETWEEN_TURN_CONFESSING_1: 'character.conversation.between.confessing.1',
|
|
51
|
+
/** Confessing NPC, third non-conversation turn. */
|
|
52
|
+
BETWEEN_TURN_CONFESSING_3: 'character.conversation.between.confessing.3',
|
|
53
|
+
/** Neutral NPC, third+ non-conversation turn (default decay). */
|
|
54
|
+
BETWEEN_TURN_NEUTRAL_3: 'character.conversation.between.neutral.3',
|
|
55
|
+
// -------------------------------------------------------------------------
|
|
56
|
+
// Attention / lifecycle
|
|
57
|
+
// -------------------------------------------------------------------------
|
|
58
|
+
/** NPC yields attention when player redirects to another NPC. */
|
|
59
|
+
ATTENTION_YIELDS: 'character.conversation.attention.yields',
|
|
60
|
+
/** NPC protests when player redirects but doesn't block. */
|
|
61
|
+
ATTENTION_PROTESTS: 'character.conversation.attention.protests',
|
|
62
|
+
/** NPC blocks player from redirecting (strong attention hold). */
|
|
63
|
+
ATTENTION_BLOCKS: 'character.conversation.attention.blocks',
|
|
64
|
+
/** Conversation ends naturally (goodbye). */
|
|
65
|
+
CONVERSATION_ENDS: 'character.conversation.ends',
|
|
66
|
+
/** NPC initiates conversation. */
|
|
67
|
+
CONVERSATION_INITIATES: 'character.conversation.initiates',
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=conversation-messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-messages.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/character/src/conversation/conversation-messages.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH;;;GAGG;AACU,QAAA,oBAAoB,GAAG;IAClC,4EAA4E;IAC5E,4EAA4E;IAC5E,4EAA4E;IAE5E,qCAAqC;IACrC,gBAAgB,EAAE,yCAAyC;IAC3D,oCAAoC;IACpC,eAAe,EAAE,wCAAwC;IACzD,6DAA6D;IAC7D,oBAAoB,EAAE,6CAA6C;IACnE,+DAA+D;IAC/D,aAAa,EAAE,sCAAsC;IAErD,4EAA4E;IAC5E,mEAAmE;IACnE,4EAA4E;IAE5E,yCAAyC;IACzC,oBAAoB,EAAE,6CAA6C;IACnE,mDAAmD;IACnD,kBAAkB,EAAE,2CAA2C;IAC/D,oDAAoD;IACpD,kBAAkB,EAAE,2CAA2C;IAE/D,4EAA4E;IAC5E,uEAAuE;IACvE,4EAA4E;IAE5E,8CAA8C;IAC9C,oBAAoB,EAAE,wCAAwC;IAC9D,+CAA+C;IAC/C,oBAAoB,EAAE,wCAAwC;IAC9D,kDAAkD;IAClD,wBAAwB,EAAE,4CAA4C;IACtE,gDAAgD;IAChD,sBAAsB,EAAE,0CAA0C;IAClE,mDAAmD;IACnD,yBAAyB,EAAE,6CAA6C;IACxE,mDAAmD;IACnD,yBAAyB,EAAE,6CAA6C;IACxE,iEAAiE;IACjE,sBAAsB,EAAE,0CAA0C;IAElE,4EAA4E;IAC5E,wBAAwB;IACxB,4EAA4E;IAE5E,iEAAiE;IACjE,gBAAgB,EAAE,yCAAyC;IAC3D,4DAA4D;IAC5D,kBAAkB,EAAE,2CAA2C;IAC/D,kEAAkE;IAClE,gBAAgB,EAAE,yCAAyC;IAC3D,6CAA6C;IAC7C,iBAAiB,EAAE,6BAA6B;IAChD,kCAAkC;IAClC,sBAAsB,EAAE,kCAAkC;CAClD,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CharacterModelDialogue — DialogueExtension implementation (ADR-142)
|
|
3
|
+
*
|
|
4
|
+
* Implements the DialogueExtension interface (ADR-102) using the
|
|
5
|
+
* character model conversation system. Wires topic resolution,
|
|
6
|
+
* constraint evaluation, conversation lifecycle, and the ACL
|
|
7
|
+
* into a single handler for stdlib's ASK/TELL/SAY/TALK TO actions.
|
|
8
|
+
*
|
|
9
|
+
* Public interface: CharacterModelDialogue.
|
|
10
|
+
* Owner context: @sharpee/character / conversation
|
|
11
|
+
*/
|
|
12
|
+
import { CharacterModelTrait } from "../../world-model/index";
|
|
13
|
+
import { DialogueExtension, DialogueResult } from './dialogue-types';
|
|
14
|
+
import { ConstraintEvaluator } from './constraint-evaluator';
|
|
15
|
+
import { ConversationLifecycle } from './lifecycle';
|
|
16
|
+
import { ConversationData } from './builder';
|
|
17
|
+
/**
|
|
18
|
+
* DialogueExtension implementation backed by the character model.
|
|
19
|
+
*
|
|
20
|
+
* Manages per-NPC topic registries, constraint evaluation, conversation
|
|
21
|
+
* lifecycle, and evidence tracking. One instance per game session.
|
|
22
|
+
*/
|
|
23
|
+
export declare class CharacterModelDialogue implements DialogueExtension {
|
|
24
|
+
/** Per-NPC conversation state. */
|
|
25
|
+
private readonly npcs;
|
|
26
|
+
/** Shared constraint evaluator (owns conversation records and evidence). */
|
|
27
|
+
private readonly evaluator;
|
|
28
|
+
/** Shared conversation lifecycle (owns active conversation state). */
|
|
29
|
+
private readonly lifecycle;
|
|
30
|
+
/** Get the conversation lifecycle for external access. */
|
|
31
|
+
getLifecycle(): ConversationLifecycle;
|
|
32
|
+
/** Get the constraint evaluator for external access. */
|
|
33
|
+
getEvaluator(): ConstraintEvaluator;
|
|
34
|
+
/**
|
|
35
|
+
* Register an NPC with its conversation data and character model trait.
|
|
36
|
+
*
|
|
37
|
+
* @param npcId - The NPC entity ID
|
|
38
|
+
* @param data - Compiled conversation data from ConversationBuilder
|
|
39
|
+
* @param trait - The NPC's CharacterModelTrait
|
|
40
|
+
* @param getTurn - Function that returns the current turn number
|
|
41
|
+
*/
|
|
42
|
+
registerNpc(npcId: string, data: ConversationData, trait: CharacterModelTrait, getTurn: () => number): void;
|
|
43
|
+
/**
|
|
44
|
+
* Handle ASK [npc] ABOUT [text].
|
|
45
|
+
* Resolves topic, evaluates constraints, records response, builds intent.
|
|
46
|
+
*/
|
|
47
|
+
handleAsk(npcId: string, aboutText: string): DialogueResult;
|
|
48
|
+
/**
|
|
49
|
+
* Handle TELL [npc] ABOUT [text].
|
|
50
|
+
* Confrontation path — the player presents information.
|
|
51
|
+
*/
|
|
52
|
+
handleTell(npcId: string, aboutText: string): DialogueResult;
|
|
53
|
+
/**
|
|
54
|
+
* Handle SAY [text] or SAY [text] TO [npc].
|
|
55
|
+
* Routes free speech through topic resolution.
|
|
56
|
+
*/
|
|
57
|
+
handleSay(npcId: string | undefined, spokenText: string): DialogueResult;
|
|
58
|
+
/**
|
|
59
|
+
* Handle TALK TO [npc].
|
|
60
|
+
* Initiates conversation lifecycle.
|
|
61
|
+
*/
|
|
62
|
+
handleTalkTo(npcId: string): DialogueResult;
|
|
63
|
+
/**
|
|
64
|
+
* Select the best response for a topic and record it in the evaluator.
|
|
65
|
+
*
|
|
66
|
+
* Evaluates constraints across all authored responses, picks the best
|
|
67
|
+
* match, and records the interaction.
|
|
68
|
+
*
|
|
69
|
+
* @param npc - NPC conversation state
|
|
70
|
+
* @param npcId - The NPC entity ID
|
|
71
|
+
* @param topicName - The resolved topic name
|
|
72
|
+
* @param authoredResponses - Authored responses for this trigger
|
|
73
|
+
* @returns The selected candidate and its authored response, or null
|
|
74
|
+
*/
|
|
75
|
+
private selectAndRecordResponse;
|
|
76
|
+
/**
|
|
77
|
+
* Apply side effects from a selected authored response: state mutations,
|
|
78
|
+
* conversation context, between-turn overrides, and leave-attempt message.
|
|
79
|
+
*
|
|
80
|
+
* @param trait - The NPC's CharacterModelTrait
|
|
81
|
+
* @param authoredResponse - The selected authored response
|
|
82
|
+
*/
|
|
83
|
+
private applyResponseSideEffects;
|
|
84
|
+
/** Apply state mutations to the NPC's character model trait. */
|
|
85
|
+
private applyStateMutations;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=dialogue-extension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialogue-extension.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/character/src/conversation/dialogue-extension.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGrE,OAAO,EAAuB,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,OAAO,EACL,gBAAgB,EAGjB,MAAM,WAAW,CAAC;AAyBnB;;;;;GAKG;AACH,qBAAa,sBAAuB,YAAW,iBAAiB;IAC9D,kCAAkC;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgD;IAErE,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkD;IAE5E,sEAAsE;IACtE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsD;IAEhF,0DAA0D;IAC1D,YAAY,IAAI,qBAAqB;IAIrC,wDAAwD;IACxD,YAAY,IAAI,mBAAmB;IAQnC;;;;;;;OAOG;IACH,WAAW,CACT,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,gBAAgB,EACtB,KAAK,EAAE,mBAAmB,EAC1B,OAAO,EAAE,MAAM,MAAM,GACpB,IAAI;IAwBP;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,cAAc;IA8E3D;;;OAGG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,cAAc;IA4D5D;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc;IAOxE;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc;IA8B3C;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,uBAAuB;IAmB/B;;;;;;OAMG;IACH,OAAO,CAAC,wBAAwB;IAwBhC,gEAAgE;IAChE,OAAO,CAAC,mBAAmB;CAgB5B"}
|