@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 @@
|
|
|
1
|
+
{"version":3,"file":"response-types.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/character/src/conversation/response-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAMvD;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,MAAM,GACN,KAAK,GACL,SAAS,GACT,QAAQ,GACR,UAAU,GACV,SAAS,GACT,aAAa,CAAC;AAMlB;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,gCAAgC;IAChC,MAAM,EAAE,cAAc,CAAC;IAEvB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,WAAW,EAAE,MAAM,EAAE,CAAC;IAEtB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC;IAEvC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAMD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,uCAAuC;IACvC,MAAM,EAAE,cAAc,CAAC;IAEvB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IAEd,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAElB,+DAA+D;IAC/D,IAAI,EAAE,IAAI,CAAC;IAEX,wEAAwE;IACxE,SAAS,EAAE,SAAS,CAAC;IAErB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAMD,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,MAAM,EAAE,cAAc,CAAC;IAEvB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,sCAAsC;IACtC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAE1C,4DAA4D;IAC5D,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;CAC3C;AAMD,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IAEd,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;AAM1D,0CAA0C;AAC1C,wBAAgB,wBAAwB,IAAI,kBAAkB,CAK7D;AAED,sCAAsC;AACtC,wBAAgB,oBAAoB,IAAI,cAAc,CAErD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Conversation response types (ADR-142)
|
|
4
|
+
*
|
|
5
|
+
* Type definitions for constraint-based response selection:
|
|
6
|
+
* ResponseAction, ResponseCandidate, ResponseIntent, and
|
|
7
|
+
* conversation/evidence tracking records.
|
|
8
|
+
*
|
|
9
|
+
* Public interface: ResponseAction, ResponseCandidate, ResponseIntent,
|
|
10
|
+
* ConversationRecord, ConversationEntry, EvidenceRecord, EvidenceEntry.
|
|
11
|
+
* Owner context: @sharpee/character / conversation
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.createConversationRecord = createConversationRecord;
|
|
15
|
+
exports.createEvidenceRecord = createEvidenceRecord;
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Factory helpers
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
/** Create an empty ConversationRecord. */
|
|
20
|
+
function createConversationRecord() {
|
|
21
|
+
return {
|
|
22
|
+
responses: new Map(),
|
|
23
|
+
history: new Map(),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** Create an empty EvidenceRecord. */
|
|
27
|
+
function createEvidenceRecord() {
|
|
28
|
+
return new Map();
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=response-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-types.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/character/src/conversation/response-types.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AA0IH,4DAKC;AAGD,oDAEC;AAfD,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,0CAA0C;AAC1C,SAAgB,wBAAwB;IACtC,OAAO;QACL,SAAS,EAAE,IAAI,GAAG,EAAE;QACpB,OAAO,EAAE,IAAI,GAAG,EAAE;KACnB,CAAC;AACJ,CAAC;AAED,sCAAsC;AACtC,SAAgB,oBAAoB;IAClC,OAAO,IAAI,GAAG,EAAE,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Topic registry and resolution (ADR-142)
|
|
3
|
+
*
|
|
4
|
+
* Authors define topics with keyword sets and optional relationships.
|
|
5
|
+
* The registry resolves free-text player input to authored topics
|
|
6
|
+
* using exact normalized word matching with neighborhood fallback.
|
|
7
|
+
*
|
|
8
|
+
* Public interface: TopicDef, TopicRegistry.
|
|
9
|
+
* Owner context: @sharpee/character / conversation
|
|
10
|
+
*/
|
|
11
|
+
import { CharacterModelTrait } from "../../world-model/index";
|
|
12
|
+
/** An authored topic definition with keywords, relationships, and availability. */
|
|
13
|
+
export interface TopicDef {
|
|
14
|
+
/** The canonical topic name (used as key). */
|
|
15
|
+
name: string;
|
|
16
|
+
/**
|
|
17
|
+
* Exact keyword set for matching player input.
|
|
18
|
+
* Stored normalized (lowercase, trimmed). Each entry can be
|
|
19
|
+
* a single word or a multi-word phrase.
|
|
20
|
+
*/
|
|
21
|
+
keywords: string[];
|
|
22
|
+
/**
|
|
23
|
+
* Related topic names — the neighborhood for fallback matching.
|
|
24
|
+
* When the player's input doesn't match any topic exactly but
|
|
25
|
+
* matches a related topic, the NPC can redirect.
|
|
26
|
+
*/
|
|
27
|
+
related?: string[];
|
|
28
|
+
/**
|
|
29
|
+
* Predicate names that must all be satisfied for this topic to be
|
|
30
|
+
* available to the player. Evaluated against the NPC's character state.
|
|
31
|
+
* If empty or undefined, the topic is always available.
|
|
32
|
+
*/
|
|
33
|
+
availableWhen?: string[];
|
|
34
|
+
}
|
|
35
|
+
/** The result of resolving player text to a topic. */
|
|
36
|
+
export type TopicResolution = {
|
|
37
|
+
type: 'exact';
|
|
38
|
+
topic: TopicDef;
|
|
39
|
+
} | {
|
|
40
|
+
type: 'related';
|
|
41
|
+
topic: TopicDef;
|
|
42
|
+
via: TopicDef;
|
|
43
|
+
} | {
|
|
44
|
+
type: 'none';
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Registry of authored topics for a single NPC.
|
|
48
|
+
*
|
|
49
|
+
* Topics are defined once during character building. At runtime,
|
|
50
|
+
* the registry resolves player free-text input to the best matching
|
|
51
|
+
* topic, considering keyword matches and topic neighborhoods.
|
|
52
|
+
*/
|
|
53
|
+
export declare class TopicRegistry {
|
|
54
|
+
private readonly topics;
|
|
55
|
+
/**
|
|
56
|
+
* Register a topic definition.
|
|
57
|
+
*
|
|
58
|
+
* @param def - The topic definition to register
|
|
59
|
+
* @throws Error if a topic with the same name is already registered
|
|
60
|
+
*/
|
|
61
|
+
define(def: TopicDef): void;
|
|
62
|
+
/**
|
|
63
|
+
* Get a topic by its canonical name.
|
|
64
|
+
*
|
|
65
|
+
* @param name - The topic name
|
|
66
|
+
* @returns The topic definition, or undefined
|
|
67
|
+
*/
|
|
68
|
+
get(name: string): TopicDef | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Check whether a topic is available given the NPC's current state.
|
|
71
|
+
*
|
|
72
|
+
* @param name - The topic name
|
|
73
|
+
* @param npcTrait - The NPC's CharacterModelTrait for predicate evaluation
|
|
74
|
+
* @returns True if the topic exists and its availability predicates are satisfied
|
|
75
|
+
*/
|
|
76
|
+
isAvailable(name: string, npcTrait: CharacterModelTrait): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Resolve player free-text input to a topic.
|
|
79
|
+
*
|
|
80
|
+
* Resolution algorithm:
|
|
81
|
+
* 1. Normalize input to lowercase words
|
|
82
|
+
* 2. Score each available topic by keyword hits (exact word match)
|
|
83
|
+
* 3. If any topic has hits, select the one with the most hits (exact match)
|
|
84
|
+
* 4. If no exact match, check if input matches keywords of any related topic
|
|
85
|
+
* and redirect through the neighborhood
|
|
86
|
+
* 5. If no match at all, return { type: 'none' }
|
|
87
|
+
*
|
|
88
|
+
* @param text - Raw text from the player (e.g., "the murder weapon")
|
|
89
|
+
* @param npcTrait - The NPC's CharacterModelTrait for availability checks
|
|
90
|
+
* @returns Resolution result: exact match, related redirect, or no match
|
|
91
|
+
*/
|
|
92
|
+
resolve(text: string, npcTrait: CharacterModelTrait): TopicResolution;
|
|
93
|
+
/**
|
|
94
|
+
* Search for a related-topic redirect when no exact match was found.
|
|
95
|
+
*
|
|
96
|
+
* For each available topic with related topics, checks if the input
|
|
97
|
+
* matches any related topic's keywords. Returns the first match as
|
|
98
|
+
* a redirect resolution.
|
|
99
|
+
*
|
|
100
|
+
* @param inputWords - Input split into normalized words
|
|
101
|
+
* @param inputNormalized - Full normalized input string
|
|
102
|
+
* @param npcTrait - The NPC's CharacterModelTrait for availability checks
|
|
103
|
+
* @returns Related redirect resolution, or { type: 'none' }
|
|
104
|
+
*/
|
|
105
|
+
private findRelatedRedirect;
|
|
106
|
+
/**
|
|
107
|
+
* Get all registered topic names.
|
|
108
|
+
*
|
|
109
|
+
* @returns Array of topic names
|
|
110
|
+
*/
|
|
111
|
+
getTopicNames(): string[];
|
|
112
|
+
/**
|
|
113
|
+
* Get all topics that are currently available to the player.
|
|
114
|
+
*
|
|
115
|
+
* @param npcTrait - The NPC's CharacterModelTrait for predicate evaluation
|
|
116
|
+
* @returns Array of available topic definitions
|
|
117
|
+
*/
|
|
118
|
+
getAvailableTopics(npcTrait: CharacterModelTrait): TopicDef[];
|
|
119
|
+
/**
|
|
120
|
+
* Score how well the input matches a keyword set.
|
|
121
|
+
* Each keyword that appears as a word or phrase in the input scores 1.
|
|
122
|
+
*
|
|
123
|
+
* @param inputWords - Input split into normalized words
|
|
124
|
+
* @param inputNormalized - Full normalized input string
|
|
125
|
+
* @param keywords - The topic's keyword set (already normalized)
|
|
126
|
+
* @returns Number of keyword hits
|
|
127
|
+
*/
|
|
128
|
+
private scoreKeywordMatch;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=topic-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topic-registry.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/character/src/conversation/topic-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAM3D,mFAAmF;AACnF,MAAM,WAAW,QAAQ;IACvB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAMD,sDAAsD;AACtD,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAMrB;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAE3D;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI;IAY3B;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAIvC;;;;;;OAMG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,OAAO;IAWjE;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,eAAe;IA0BrE;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,mBAAmB;IAwB3B;;;;OAIG;IACH,aAAa,IAAI,MAAM,EAAE;IAIzB;;;;;OAKG;IACH,kBAAkB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,QAAQ,EAAE;IAc7D;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB;CAmB1B"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Topic registry and resolution (ADR-142)
|
|
4
|
+
*
|
|
5
|
+
* Authors define topics with keyword sets and optional relationships.
|
|
6
|
+
* The registry resolves free-text player input to authored topics
|
|
7
|
+
* using exact normalized word matching with neighborhood fallback.
|
|
8
|
+
*
|
|
9
|
+
* Public interface: TopicDef, TopicRegistry.
|
|
10
|
+
* Owner context: @sharpee/character / conversation
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.TopicRegistry = void 0;
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Topic registry
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
/**
|
|
18
|
+
* Registry of authored topics for a single NPC.
|
|
19
|
+
*
|
|
20
|
+
* Topics are defined once during character building. At runtime,
|
|
21
|
+
* the registry resolves player free-text input to the best matching
|
|
22
|
+
* topic, considering keyword matches and topic neighborhoods.
|
|
23
|
+
*/
|
|
24
|
+
class TopicRegistry {
|
|
25
|
+
topics = new Map();
|
|
26
|
+
/**
|
|
27
|
+
* Register a topic definition.
|
|
28
|
+
*
|
|
29
|
+
* @param def - The topic definition to register
|
|
30
|
+
* @throws Error if a topic with the same name is already registered
|
|
31
|
+
*/
|
|
32
|
+
define(def) {
|
|
33
|
+
if (this.topics.has(def.name)) {
|
|
34
|
+
throw new Error(`Topic '${def.name}' is already defined`);
|
|
35
|
+
}
|
|
36
|
+
// Normalize keywords at registration time
|
|
37
|
+
const normalized = {
|
|
38
|
+
...def,
|
|
39
|
+
keywords: def.keywords.map(k => k.toLowerCase().trim()),
|
|
40
|
+
};
|
|
41
|
+
this.topics.set(def.name, normalized);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get a topic by its canonical name.
|
|
45
|
+
*
|
|
46
|
+
* @param name - The topic name
|
|
47
|
+
* @returns The topic definition, or undefined
|
|
48
|
+
*/
|
|
49
|
+
get(name) {
|
|
50
|
+
return this.topics.get(name);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check whether a topic is available given the NPC's current state.
|
|
54
|
+
*
|
|
55
|
+
* @param name - The topic name
|
|
56
|
+
* @param npcTrait - The NPC's CharacterModelTrait for predicate evaluation
|
|
57
|
+
* @returns True if the topic exists and its availability predicates are satisfied
|
|
58
|
+
*/
|
|
59
|
+
isAvailable(name, npcTrait) {
|
|
60
|
+
const topic = this.topics.get(name);
|
|
61
|
+
if (!topic)
|
|
62
|
+
return false;
|
|
63
|
+
if (!topic.availableWhen || topic.availableWhen.length === 0) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
return topic.availableWhen.every(pred => npcTrait.evaluate(pred));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Resolve player free-text input to a topic.
|
|
70
|
+
*
|
|
71
|
+
* Resolution algorithm:
|
|
72
|
+
* 1. Normalize input to lowercase words
|
|
73
|
+
* 2. Score each available topic by keyword hits (exact word match)
|
|
74
|
+
* 3. If any topic has hits, select the one with the most hits (exact match)
|
|
75
|
+
* 4. If no exact match, check if input matches keywords of any related topic
|
|
76
|
+
* and redirect through the neighborhood
|
|
77
|
+
* 5. If no match at all, return { type: 'none' }
|
|
78
|
+
*
|
|
79
|
+
* @param text - Raw text from the player (e.g., "the murder weapon")
|
|
80
|
+
* @param npcTrait - The NPC's CharacterModelTrait for availability checks
|
|
81
|
+
* @returns Resolution result: exact match, related redirect, or no match
|
|
82
|
+
*/
|
|
83
|
+
resolve(text, npcTrait) {
|
|
84
|
+
const inputWords = text.toLowerCase().trim().split(/\s+/);
|
|
85
|
+
const inputNormalized = text.toLowerCase().trim();
|
|
86
|
+
// Phase 1: Score each available topic by keyword hits
|
|
87
|
+
let bestTopic;
|
|
88
|
+
let bestScore = 0;
|
|
89
|
+
for (const topic of this.topics.values()) {
|
|
90
|
+
if (!this.isAvailable(topic.name, npcTrait))
|
|
91
|
+
continue;
|
|
92
|
+
const score = this.scoreKeywordMatch(inputWords, inputNormalized, topic.keywords);
|
|
93
|
+
if (score > bestScore) {
|
|
94
|
+
bestScore = score;
|
|
95
|
+
bestTopic = topic;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (bestTopic) {
|
|
99
|
+
return { type: 'exact', topic: bestTopic };
|
|
100
|
+
}
|
|
101
|
+
// Phase 2: Check related topic neighborhoods
|
|
102
|
+
return this.findRelatedRedirect(inputWords, inputNormalized, npcTrait);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Search for a related-topic redirect when no exact match was found.
|
|
106
|
+
*
|
|
107
|
+
* For each available topic with related topics, checks if the input
|
|
108
|
+
* matches any related topic's keywords. Returns the first match as
|
|
109
|
+
* a redirect resolution.
|
|
110
|
+
*
|
|
111
|
+
* @param inputWords - Input split into normalized words
|
|
112
|
+
* @param inputNormalized - Full normalized input string
|
|
113
|
+
* @param npcTrait - The NPC's CharacterModelTrait for availability checks
|
|
114
|
+
* @returns Related redirect resolution, or { type: 'none' }
|
|
115
|
+
*/
|
|
116
|
+
findRelatedRedirect(inputWords, inputNormalized, npcTrait) {
|
|
117
|
+
for (const topic of this.topics.values()) {
|
|
118
|
+
if (!this.isAvailable(topic.name, npcTrait))
|
|
119
|
+
continue;
|
|
120
|
+
if (topic.related) {
|
|
121
|
+
for (const relatedName of topic.related) {
|
|
122
|
+
const relatedTopic = this.topics.get(relatedName);
|
|
123
|
+
if (!relatedTopic)
|
|
124
|
+
continue;
|
|
125
|
+
const score = this.scoreKeywordMatch(inputWords, inputNormalized, relatedTopic.keywords);
|
|
126
|
+
if (score > 0) {
|
|
127
|
+
return { type: 'related', topic, via: relatedTopic };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return { type: 'none' };
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get all registered topic names.
|
|
136
|
+
*
|
|
137
|
+
* @returns Array of topic names
|
|
138
|
+
*/
|
|
139
|
+
getTopicNames() {
|
|
140
|
+
return Array.from(this.topics.keys());
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get all topics that are currently available to the player.
|
|
144
|
+
*
|
|
145
|
+
* @param npcTrait - The NPC's CharacterModelTrait for predicate evaluation
|
|
146
|
+
* @returns Array of available topic definitions
|
|
147
|
+
*/
|
|
148
|
+
getAvailableTopics(npcTrait) {
|
|
149
|
+
const result = [];
|
|
150
|
+
for (const topic of this.topics.values()) {
|
|
151
|
+
if (this.isAvailable(topic.name, npcTrait)) {
|
|
152
|
+
result.push(topic);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
// -------------------------------------------------------------------------
|
|
158
|
+
// Private helpers
|
|
159
|
+
// -------------------------------------------------------------------------
|
|
160
|
+
/**
|
|
161
|
+
* Score how well the input matches a keyword set.
|
|
162
|
+
* Each keyword that appears as a word or phrase in the input scores 1.
|
|
163
|
+
*
|
|
164
|
+
* @param inputWords - Input split into normalized words
|
|
165
|
+
* @param inputNormalized - Full normalized input string
|
|
166
|
+
* @param keywords - The topic's keyword set (already normalized)
|
|
167
|
+
* @returns Number of keyword hits
|
|
168
|
+
*/
|
|
169
|
+
scoreKeywordMatch(inputWords, inputNormalized, keywords) {
|
|
170
|
+
let score = 0;
|
|
171
|
+
for (const keyword of keywords) {
|
|
172
|
+
if (keyword.includes(' ')) {
|
|
173
|
+
// Multi-word phrase: check substring match in full input
|
|
174
|
+
if (inputNormalized.includes(keyword)) {
|
|
175
|
+
score++;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else if (inputWords.includes(keyword)) {
|
|
179
|
+
// Single word: check exact word match
|
|
180
|
+
score++;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return score;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
exports.TopicRegistry = TopicRegistry;
|
|
187
|
+
//# sourceMappingURL=topic-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topic-registry.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/character/src/conversation/topic-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Goal builder API (ADR-145 layer 5)
|
|
3
|
+
*
|
|
4
|
+
* Fluent builder for defining NPC goals with activation conditions,
|
|
5
|
+
* pursuit modes, behavior sequences, and interruption rules.
|
|
6
|
+
* Returns from CharacterBuilder.goal(id) and compiles to GoalDef
|
|
7
|
+
* stored in CompiledCharacter.goalDefs.
|
|
8
|
+
*
|
|
9
|
+
* Public interface: GoalBuilder.
|
|
10
|
+
* Owner context: @sharpee/character / goals
|
|
11
|
+
*/
|
|
12
|
+
import { GoalPriority, PursuitMode, GoalStep, GoalDef } from './goal-types';
|
|
13
|
+
/**
|
|
14
|
+
* Fluent builder for a single goal definition.
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* ```
|
|
18
|
+
* builder.goal('eliminate-player')
|
|
19
|
+
* .activatesWhen('knows murder discovered', 'has weapon')
|
|
20
|
+
* .priority('critical')
|
|
21
|
+
* .mode('prepared')
|
|
22
|
+
* .pursues([
|
|
23
|
+
* { type: 'moveTo', target: 'study' },
|
|
24
|
+
* { type: 'acquire', target: 'knife' },
|
|
25
|
+
* ])
|
|
26
|
+
* .actsWhen('alone with player')
|
|
27
|
+
* .act('colonel-attacks-player')
|
|
28
|
+
* .onInterrupt('colonel-retreats')
|
|
29
|
+
* .resumeOnClear(true)
|
|
30
|
+
* .done()
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class GoalBuilder<TParent> {
|
|
34
|
+
private readonly _id;
|
|
35
|
+
private readonly _parent;
|
|
36
|
+
private readonly _finalize;
|
|
37
|
+
private readonly _activatesWhen;
|
|
38
|
+
private readonly _interruptedBy;
|
|
39
|
+
private _priority;
|
|
40
|
+
private _mode;
|
|
41
|
+
private _steps;
|
|
42
|
+
private readonly _actsWhen;
|
|
43
|
+
private _actMessageId?;
|
|
44
|
+
private _onInterrupt?;
|
|
45
|
+
private _resumeOnClear;
|
|
46
|
+
/**
|
|
47
|
+
* Create a new goal builder.
|
|
48
|
+
*
|
|
49
|
+
* @param id - Unique goal identifier
|
|
50
|
+
* @param parent - Parent builder to return to on .done()
|
|
51
|
+
* @param finalize - Callback to register the compiled GoalDef
|
|
52
|
+
*/
|
|
53
|
+
constructor(id: string, parent: TParent, finalize: (def: GoalDef) => void);
|
|
54
|
+
/**
|
|
55
|
+
* Set predicate conditions that activate this goal.
|
|
56
|
+
*
|
|
57
|
+
* @param predicates - Predicate names (all must be true)
|
|
58
|
+
* @returns this for chaining
|
|
59
|
+
*/
|
|
60
|
+
activatesWhen(...predicates: string[]): GoalBuilder<TParent>;
|
|
61
|
+
/**
|
|
62
|
+
* Set goal priority.
|
|
63
|
+
*
|
|
64
|
+
* @param priority - Priority word
|
|
65
|
+
* @returns this for chaining
|
|
66
|
+
*/
|
|
67
|
+
priority(priority: GoalPriority): GoalBuilder<TParent>;
|
|
68
|
+
/**
|
|
69
|
+
* Set pursuit mode.
|
|
70
|
+
*
|
|
71
|
+
* @param mode - How the NPC pursues the goal
|
|
72
|
+
* @returns this for chaining
|
|
73
|
+
*/
|
|
74
|
+
mode(mode: PursuitMode): GoalBuilder<TParent>;
|
|
75
|
+
/**
|
|
76
|
+
* Set the behavior sequence (for sequential and prepared modes).
|
|
77
|
+
*
|
|
78
|
+
* @param steps - Array of goal steps
|
|
79
|
+
* @returns this for chaining
|
|
80
|
+
*/
|
|
81
|
+
pursues(steps: GoalStep[]): GoalBuilder<TParent>;
|
|
82
|
+
/**
|
|
83
|
+
* Set conditions for the final act (opportunistic/prepared modes).
|
|
84
|
+
*
|
|
85
|
+
* @param predicates - Predicate names (all must be true)
|
|
86
|
+
* @returns this for chaining
|
|
87
|
+
*/
|
|
88
|
+
actsWhen(...predicates: string[]): GoalBuilder<TParent>;
|
|
89
|
+
/**
|
|
90
|
+
* Set the message ID for the final act.
|
|
91
|
+
*
|
|
92
|
+
* @param messageId - Message ID
|
|
93
|
+
* @returns this for chaining
|
|
94
|
+
*/
|
|
95
|
+
act(messageId: string): GoalBuilder<TParent>;
|
|
96
|
+
/**
|
|
97
|
+
* Set predicate conditions that interrupt (suspend) this goal.
|
|
98
|
+
*
|
|
99
|
+
* @param predicates - Predicate names
|
|
100
|
+
* @returns this for chaining
|
|
101
|
+
*/
|
|
102
|
+
interruptedBy(...predicates: string[]): GoalBuilder<TParent>;
|
|
103
|
+
/**
|
|
104
|
+
* Set the message ID when the goal is interrupted.
|
|
105
|
+
*
|
|
106
|
+
* @param messageId - Message ID
|
|
107
|
+
* @returns this for chaining
|
|
108
|
+
*/
|
|
109
|
+
onInterrupt(messageId: string): GoalBuilder<TParent>;
|
|
110
|
+
/**
|
|
111
|
+
* Set whether the goal resumes from where it left off after interruption.
|
|
112
|
+
*
|
|
113
|
+
* @param resume - Whether to resume
|
|
114
|
+
* @returns this for chaining
|
|
115
|
+
*/
|
|
116
|
+
resumeOnClear(resume: boolean): GoalBuilder<TParent>;
|
|
117
|
+
/**
|
|
118
|
+
* Finalize this goal definition and return the parent builder.
|
|
119
|
+
*
|
|
120
|
+
* @returns The parent builder
|
|
121
|
+
*/
|
|
122
|
+
done(): TParent;
|
|
123
|
+
/**
|
|
124
|
+
* Compile the parent builder, auto-finalizing this goal.
|
|
125
|
+
* Allows calling .compile() directly from a goal chain without .done().
|
|
126
|
+
*
|
|
127
|
+
* @returns Compiled character data (delegates to parent's compile())
|
|
128
|
+
*/
|
|
129
|
+
compile(): ReturnType<TParent extends {
|
|
130
|
+
compile(): infer R;
|
|
131
|
+
} ? () => R : never>;
|
|
132
|
+
/** @internal Build the GoalDef without finalizing. */
|
|
133
|
+
_buildDef(): GoalDef;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/character/src/goals/builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,OAAO,EACR,MAAM,cAAc,CAAC;AAEtB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,WAAW,CAAC,OAAO;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAS;IAE/B;;;;;;OAMG;gBACS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI;IAMzE;;;;;OAKG;IACH,aAAa,CAAC,GAAG,UAAU,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC;IAK5D;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG,WAAW,CAAC,OAAO,CAAC;IAKtD;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC;IAK7C;;;;;OAKG;IACH,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC;IAKhD;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,UAAU,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC;IAKvD;;;;;OAKG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC;IAK5C;;;;;OAKG;IACH,aAAa,CAAC,GAAG,UAAU,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC;IAK5D;;;;;OAKG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC;IAKpD;;;;;OAKG;IACH,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;IAKpD;;;;OAIG;IACH,IAAI,IAAI,OAAO;IAKf;;;;;OAKG;IACH,OAAO,IAAI,UAAU,CAAC,OAAO,SAAS;QAAE,OAAO,IAAI,MAAM,CAAC,CAAA;KAAE,GAAG,MAAM,CAAC,GAAG,KAAK,CAAC;IAK/E,sDAAsD;IACtD,SAAS,IAAI,OAAO;CAiBrB"}
|