@adam0white/human-framework 2.15.0 → 2.17.0
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/README.md +36 -0
- package/dist/agenda/agenda.d.ts +2 -0
- package/dist/agenda/agenda.js +11 -1
- package/dist/conversation/conversation.d.ts +13 -4
- package/dist/conversation/conversation.js +24 -2
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -3
- package/dist/migrate.js +5 -0
- package/dist/narrate/lexicon.js +23 -0
- package/dist/narrate/narrate.d.ts +7 -1
- package/dist/narrate/narrate.js +17 -1
- package/dist/person.d.ts +6 -1
- package/dist/person.js +13 -8
- package/dist/persona-calendar.d.ts +39 -0
- package/dist/persona-calendar.js +411 -0
- package/dist/persona.d.ts +1 -1
- package/dist/persona.js +5 -2
- package/dist/projects/projects.d.ts +8 -2
- package/dist/projects/projects.js +142 -2
- package/dist/promptings/promptings.d.ts +3 -1
- package/dist/promptings/promptings.js +13 -1
- package/dist/prospection/prospection.js +15 -2
- package/dist/review/review.d.ts +4 -1
- package/dist/review/review.js +12 -1
- package/dist/types.d.ts +35 -1
- package/dist/types.js +1 -1
- package/package.json +1 -1
|
@@ -256,7 +256,19 @@ export function notePromptings(p, seen, chosenId, now) {
|
|
|
256
256
|
return noted;
|
|
257
257
|
}
|
|
258
258
|
/** Vocabulary for one prompt under a held reading (narration only; it changes nothing). */
|
|
259
|
-
export function promptingLine(reading, outcome, kind) {
|
|
259
|
+
export function promptingLine(reading, outcome, kind, options = {}) {
|
|
260
|
+
// Plain third-person observations describe the response, without inferring the prompt's origin.
|
|
261
|
+
if (options.voice === 'third') {
|
|
262
|
+
if (outcome === 'assented')
|
|
263
|
+
return 'an urge came and was acted on';
|
|
264
|
+
if (outcome === 'turned')
|
|
265
|
+
return kind === 'refuge'
|
|
266
|
+
? 'an urge came; the person sought refuge and let it pass'
|
|
267
|
+
: kind === 'redirect'
|
|
268
|
+
? 'an urge came; the person turned to something else'
|
|
269
|
+
: 'an urge came; the person held back';
|
|
270
|
+
return 'an urge came and passed';
|
|
271
|
+
}
|
|
260
272
|
if (outcome === 'assented')
|
|
261
273
|
return reading === 'whisper'
|
|
262
274
|
? 'a whisper came and was followed'
|
|
@@ -17,6 +17,7 @@ import { temporalGoalValue } from '../agenda/agenda.js';
|
|
|
17
17
|
import { trustOf } from '../beliefs/index.js';
|
|
18
18
|
import { cmpStr, isNum, isObj, round } from '../core/index.js';
|
|
19
19
|
import { expectedEffect } from '../memory/index.js';
|
|
20
|
+
import { diminishesProject } from '../projects/index.js';
|
|
20
21
|
import { MAX_MINUTE, MINUTES_PER_DAY } from '../types.js';
|
|
21
22
|
export const PROSPECTION_DEFAULTS = {
|
|
22
23
|
maxEntries: 16,
|
|
@@ -92,6 +93,10 @@ function consequence(x, receivedAt) {
|
|
|
92
93
|
(!Array.isArray(s.advances) ||
|
|
93
94
|
s.advances.length > 8 ||
|
|
94
95
|
!s.advances.every((x) => typeof x === 'string' && x.length > 0 && x.length <= 512))) ||
|
|
96
|
+
(s.diminishes !== undefined &&
|
|
97
|
+
(!Array.isArray(s.diminishes) ||
|
|
98
|
+
s.diminishes.length > 8 ||
|
|
99
|
+
!s.diminishes.every((x) => typeof x === 'string' && x.length > 0 && x.length <= 512))) ||
|
|
95
100
|
(s.focus !== undefined && !unit(s.focus)) ||
|
|
96
101
|
(s.materialCost !== undefined &&
|
|
97
102
|
(!isNum(s.materialCost) || s.materialCost < 0 || s.materialCost > PROSPECTION_DEFAULTS.maxMaterialCost)))
|
|
@@ -115,6 +120,7 @@ function consequence(x, receivedAt) {
|
|
|
115
120
|
duration: s.duration,
|
|
116
121
|
effort: s.effort,
|
|
117
122
|
...(s.advances !== undefined ? { advances: [...s.advances] } : {}),
|
|
123
|
+
...(s.diminishes !== undefined ? { diminishes: [...s.diminishes] } : {}),
|
|
118
124
|
...(s.focus !== undefined ? { focus: s.focus } : {}),
|
|
119
125
|
...(s.materialCost !== undefined ? { materialCost: s.materialCost } : {}),
|
|
120
126
|
},
|
|
@@ -262,7 +268,9 @@ function successorOffer(e) {
|
|
|
262
268
|
}
|
|
263
269
|
/** Select a whole route in the exact rounded units cognition emits. @internal */
|
|
264
270
|
export function receivedGoalRoute(p, aff, now, maturityScale, costs) {
|
|
265
|
-
const goals = p.agenda.goals.filter((g) => g.status === 'active' &&
|
|
271
|
+
const goals = p.agenda.goals.filter((g) => g.status === 'active' &&
|
|
272
|
+
g.temporal !== undefined &&
|
|
273
|
+
!(g.project && diminishesProject(p, aff, g.project.prospectId)));
|
|
266
274
|
if (!goals.length || !p.prospection?.entries.length)
|
|
267
275
|
return undefined;
|
|
268
276
|
const direct = goals.map((g) => temporalGoalValue(p, g, aff, now, now + Math.max(0, aff.duration)));
|
|
@@ -297,7 +305,12 @@ export function receivedGoalRoute(p, aff, now, maturityScale, costs) {
|
|
|
297
305
|
entry.confidence *
|
|
298
306
|
reliability(p, entry);
|
|
299
307
|
const successor = successorOffer(entry);
|
|
300
|
-
const nextValues = goals.map((g, i) =>
|
|
308
|
+
const nextValues = goals.map((g, i) => {
|
|
309
|
+
const prospectId = g.project?.prospectId;
|
|
310
|
+
return prospectId && [...done, previous, successor].some((a) => diminishesProject(p, a, prospectId))
|
|
311
|
+
? 0
|
|
312
|
+
: Math.max(values[i] ?? 0, nextAccess * beta * temporalGoalValue(p, g, successor, now, end));
|
|
313
|
+
});
|
|
301
314
|
const nextCost = accumulatedCost + beta * nextAccess * Math.min(0, costs(successor));
|
|
302
315
|
const cost = round(nextCost);
|
|
303
316
|
const total = nextValues.reduce((sum, value) => sum + round(value * maturityScale), 0) + cost;
|
package/dist/review/review.d.ts
CHANGED
|
@@ -42,6 +42,9 @@ export declare function reviewIfDue(p: Person, now: Minute, recent: readonly Day
|
|
|
42
42
|
distress: number;
|
|
43
43
|
} | undefined;
|
|
44
44
|
/** The person's own words for their latest review, or undefined when they hold no review. */
|
|
45
|
-
export declare function reviewLine(p: Person
|
|
45
|
+
export declare function reviewLine(p: Person, options?: {
|
|
46
|
+
variety?: boolean;
|
|
47
|
+
cause?: 'ordered' | 'interrupted';
|
|
48
|
+
}): string | undefined;
|
|
46
49
|
/** Restore guard: drop malformed fields, keep valid resolves. */
|
|
47
50
|
export declare function sanitizeReview(x: unknown, now?: Minute): ReviewState | undefined;
|
package/dist/review/review.js
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
* fast-forward) should still live, or release, that day's occasions, or the review counts each one as missed.
|
|
32
32
|
*/
|
|
33
33
|
import { clamp01, dexp, isObj, minuteOfDay, round } from '../core/index.js';
|
|
34
|
+
import { pickLine } from '../narrate/lexicon.js';
|
|
34
35
|
export const REVIEW_DEFAULTS = {
|
|
35
36
|
/** Default evening review time, minute of day. */
|
|
36
37
|
at: 21 * 60,
|
|
@@ -192,7 +193,7 @@ export function reviewIfDue(p, now, recent, closed) {
|
|
|
192
193
|
return { record, distress };
|
|
193
194
|
}
|
|
194
195
|
/** The person's own words for their latest review, or undefined when they hold no review. */
|
|
195
|
-
export function reviewLine(p) {
|
|
196
|
+
export function reviewLine(p, options = {}) {
|
|
196
197
|
const st = p.review;
|
|
197
198
|
const r = st?.last;
|
|
198
199
|
if (!st || st.style === 'none' || !r)
|
|
@@ -200,6 +201,16 @@ export function reviewLine(p) {
|
|
|
200
201
|
const list = (xs) => xs.length <= 1 ? (xs[0] ?? '') : `${xs.slice(0, -1).join(', ')} and ${xs.at(-1)}`;
|
|
201
202
|
if (r.missed.length === 0)
|
|
202
203
|
return r.kept.length > 0 ? `Today I kept ${list(r.kept)}.` : undefined;
|
|
204
|
+
if (options.cause) {
|
|
205
|
+
const cause = options.cause === 'ordered' ? 'following an order' : 'being interrupted';
|
|
206
|
+
const next = options.cause === 'ordered'
|
|
207
|
+
? 'Next time I will say what the order would put aside.'
|
|
208
|
+
: 'Next time I will make room to return to it.';
|
|
209
|
+
return pickLine('review.cause', `${p.id}:${r.day}`, { cause, missed: list(r.missed), next }, p.lexicon);
|
|
210
|
+
}
|
|
211
|
+
if (options.variety ?? p.lexicon?.variety) {
|
|
212
|
+
return pickLine(`review.${st.style}`, `${p.id}:${r.day}`, { missed: list(r.missed) }, p.lexicon);
|
|
213
|
+
}
|
|
203
214
|
if (st.style === 'ruminating')
|
|
204
215
|
return `I keep going back over ${list(r.missed)}.`;
|
|
205
216
|
return `I didn't keep ${list(r.missed)}. Next time I'll be ready when it comes.`;
|
package/dist/types.d.ts
CHANGED
|
@@ -373,6 +373,8 @@ export interface Episode {
|
|
|
373
373
|
/** 0..1 how memorable; decays and is boosted by recall. */
|
|
374
374
|
salience: Unit;
|
|
375
375
|
summary: string;
|
|
376
|
+
/** Host-authored summary spoken back to actorId (second person); never inferred from free text. */
|
|
377
|
+
addressedSummary?: string;
|
|
376
378
|
tags: string[];
|
|
377
379
|
/**
|
|
378
380
|
* The outside voice whose suggestion led to this episode (set on outcomes of assented/complied activities and
|
|
@@ -896,7 +898,7 @@ export declare const PERSON_SCHEMA = "human/person@1";
|
|
|
896
898
|
* and an activity that would cover a closing stretch is reviewed when the stretch begins (`isUnderWay`,
|
|
897
899
|
* `dutyReviewAt`). Person shape unchanged.
|
|
898
900
|
*/
|
|
899
|
-
export declare const ENGINE_VERSION = "2.
|
|
901
|
+
export declare const ENGINE_VERSION = "2.17.0";
|
|
900
902
|
/** A pregnancy carried by this person (host-driven; see `family/`). */
|
|
901
903
|
export interface Pregnancy {
|
|
902
904
|
fatherId: PersonId;
|
|
@@ -1013,6 +1015,8 @@ export interface ReceivedConsequence {
|
|
|
1013
1015
|
effort: Unit;
|
|
1014
1016
|
focus?: Unit;
|
|
1015
1017
|
materialCost?: number;
|
|
1018
|
+
/** Prospect ids this successor reduces; read only with projects protectProgress. */
|
|
1019
|
+
diminishes?: string[];
|
|
1016
1020
|
/** Goal or prospect ids this successor contributes to (bounded to 8). */
|
|
1017
1021
|
advances?: string[];
|
|
1018
1022
|
};
|
|
@@ -1186,6 +1190,8 @@ export interface Affordance {
|
|
|
1186
1190
|
* earliest-ending match, explicit or by action, as before.
|
|
1187
1191
|
*/
|
|
1188
1192
|
fulfills?: string[];
|
|
1193
|
+
/** Prospect ids this offer reduces; read only with projects protectProgress. */
|
|
1194
|
+
diminishes?: string[];
|
|
1189
1195
|
/** Goal ids this advances. */
|
|
1190
1196
|
advances?: string[];
|
|
1191
1197
|
/** Probability of harm and its severity, as advertised. */
|
|
@@ -1251,6 +1257,8 @@ export interface Percept {
|
|
|
1251
1257
|
aboutId?: PersonId;
|
|
1252
1258
|
};
|
|
1253
1259
|
summary: string;
|
|
1260
|
+
/** Host-authored summary spoken back to actorId (second person); never inferred from free text. */
|
|
1261
|
+
addressedSummary?: string;
|
|
1254
1262
|
/**
|
|
1255
1263
|
* Host flag for `sim/` interrupts. true: this percept is near the person (the framework has no spatial model),
|
|
1256
1264
|
* so a salient one forces re-decision even if it does not target them. false: never interrupts.
|
|
@@ -1759,6 +1767,12 @@ export interface VoiceConflict {
|
|
|
1759
1767
|
* slots documented next to each key.
|
|
1760
1768
|
*/
|
|
1761
1769
|
export interface Lexicon {
|
|
1770
|
+
/** Include person identity and stable temperament in assent/deferral selection (no RNG draws). */
|
|
1771
|
+
variety?: boolean;
|
|
1772
|
+
/** What material gains mean here, e.g. 'food', 'household keep' or 'resources'; absent keeps legacy money lines. */
|
|
1773
|
+
materialMeaning?: string;
|
|
1774
|
+
/** Treat action labels as noun phrases unless explicit verb forms are supplied. */
|
|
1775
|
+
nounActions?: boolean;
|
|
1762
1776
|
/** Informational locale tag, e.g. 'en', 'tr'. */
|
|
1763
1777
|
locale?: string;
|
|
1764
1778
|
/** Display names by entity id: { ana: 'Ana', ben: 'Ben' }. */
|
|
@@ -1987,6 +2001,8 @@ export interface Prospect {
|
|
|
1987
2001
|
progress?: Unit;
|
|
1988
2002
|
}
|
|
1989
2003
|
export interface ProjectsSpec {
|
|
2004
|
+
/** Learn and respect declared reductions of a held project. Absent preserves existing choice. */
|
|
2005
|
+
protectProgress?: boolean;
|
|
1990
2006
|
forgetMinutes?: number;
|
|
1991
2007
|
calmUrgency?: Unit;
|
|
1992
2008
|
fearBelow?: Unit;
|
|
@@ -2008,6 +2024,24 @@ export interface ProjectsState {
|
|
|
2008
2024
|
/** Absent retains 2.14.0 credit. Re-enabling, including on every load, opts into net credit. */
|
|
2009
2025
|
behaviour?: 2;
|
|
2010
2026
|
spec?: ProjectsSpec;
|
|
2027
|
+
/** Exact contextual acts learned to reduce a prospect; oldest entries are evicted. */
|
|
2028
|
+
setbacks?: {
|
|
2029
|
+
prospectId: string;
|
|
2030
|
+
action: string;
|
|
2031
|
+
targetId?: EntityId;
|
|
2032
|
+
placeId?: EntityId;
|
|
2033
|
+
}[];
|
|
2034
|
+
/** Last completed act and attended progress before it; consumed by the next matching perception. */
|
|
2035
|
+
pendingAct?: {
|
|
2036
|
+
action: string;
|
|
2037
|
+
targetId?: EntityId;
|
|
2038
|
+
placeId?: EntityId;
|
|
2039
|
+
at: Minute;
|
|
2040
|
+
readings: {
|
|
2041
|
+
prospectId: string;
|
|
2042
|
+
progress: Unit;
|
|
2043
|
+
}[];
|
|
2044
|
+
};
|
|
2011
2045
|
prospects: (Prospect & {
|
|
2012
2046
|
lastSeenAt: Minute;
|
|
2013
2047
|
})[];
|
package/dist/types.js
CHANGED
|
@@ -120,4 +120,4 @@ export const PERSON_SCHEMA = 'human/person@1';
|
|
|
120
120
|
* and an activity that would cover a closing stretch is reviewed when the stretch begins (`isUnderWay`,
|
|
121
121
|
* `dutyReviewAt`). Person shape unchanged.
|
|
122
122
|
*/
|
|
123
|
-
export const ENGINE_VERSION = '2.
|
|
123
|
+
export const ENGINE_VERSION = '2.17.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adam0white/human-framework",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.17.0",
|
|
4
4
|
"description": "Deterministic, explainable simulated people: body, needs, affect, memory, beliefs, skills, habits, relationships, values and a will that can refuse a suggestion",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"simulation",
|