@adam0white/human-framework 2.9.0 → 2.10.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/dist/agenda/agenda.js +1 -1
- package/dist/beliefs/beliefs.d.ts +45 -1
- package/dist/beliefs/beliefs.js +208 -4
- package/dist/cognition/cognition.js +2 -2
- package/dist/conscience/conscience.d.ts +7 -3
- package/dist/conscience/conscience.js +5 -1
- package/dist/conversation/conversation.d.ts +4 -0
- package/dist/conversation/conversation.js +25 -0
- package/dist/core/math.d.ts +1 -0
- package/dist/core/math.js +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/memory/memory.js +4 -1
- package/dist/migrate.js +18 -1
- package/dist/person.js +150 -100
- package/dist/prospection/prospection.js +8 -2
- package/dist/restore.d.ts +9 -0
- package/dist/restore.js +22 -0
- package/dist/sim/sim.d.ts +7 -2
- package/dist/sim/sim.js +118 -93
- package/dist/social/impressions.d.ts +31 -2
- package/dist/social/impressions.js +38 -1
- package/dist/social/social.d.ts +2 -0
- package/dist/social/social.js +18 -2
- package/dist/types.d.ts +55 -6
- package/dist/types.js +1 -1
- package/dist/will/will.js +94 -65
- package/package.json +1 -1
package/dist/will/will.js
CHANGED
|
@@ -562,10 +562,49 @@ const voiceTerm = (c, voiceId) => c?.terms.find((t) => t.source === `suggestion:
|
|
|
562
562
|
* group-advice findings only in shape (advice is weighed by trust in each adviser, not by headcount); it does not model conformity to a majority, persuasion between the voices, or the person asking for advice.
|
|
563
563
|
*/
|
|
564
564
|
function evaluate(p, input, ctx, given, draw) {
|
|
565
|
-
const W = WILL_DEFAULTS;
|
|
566
565
|
const cmd = ctx.command;
|
|
567
566
|
// A commanding voice is not also weighed as a suggestion in the same decision.
|
|
568
567
|
const suggestions = cmd ? given.filter((s) => s.voiceId !== cmd.voiceId) : given;
|
|
568
|
+
const prepared = prepareVetoes(p, input, ctx, suggestions);
|
|
569
|
+
const { considered, affById } = prepared;
|
|
570
|
+
const selection = selectOption(p, considered, ctx, draw);
|
|
571
|
+
const ev = {
|
|
572
|
+
chosenId: selection.winner?.affordanceId ?? null,
|
|
573
|
+
considered,
|
|
574
|
+
resolutions: [],
|
|
575
|
+
autonomyDelta: 0,
|
|
576
|
+
voices: [],
|
|
577
|
+
};
|
|
578
|
+
if (cmd && arbitrateCommand(p, ctx, cmd, suggestions, prepared, selection, ev))
|
|
579
|
+
return ev;
|
|
580
|
+
if (suggestions.length === 0)
|
|
581
|
+
return withCommandRefusal(ev, cmd);
|
|
582
|
+
if (inBreak(p)) {
|
|
583
|
+
// During a mental break no voice reaches them; nothing is counted for or against any of them.
|
|
584
|
+
ev.resolutions = suggestions.map((s) => ({
|
|
585
|
+
voiceId: s.voiceId,
|
|
586
|
+
verdict: 'refused',
|
|
587
|
+
kind: 'cannot',
|
|
588
|
+
reason: 'break',
|
|
589
|
+
says: '',
|
|
590
|
+
}));
|
|
591
|
+
ev.voices = suggestions.map((s) => ({ id: s.voiceId, pressure: 0, accepted: 0, refused: 0 }));
|
|
592
|
+
if (ev.resolutions.length === 1)
|
|
593
|
+
ev.suggestion = ev.resolutions[0];
|
|
594
|
+
return withCommandRefusal(ev, cmd);
|
|
595
|
+
}
|
|
596
|
+
const judged = judgeVoices(p, ctx, suggestions, prepared, selection);
|
|
597
|
+
arbitrateInsistence(p, judged, considered, affById, ev);
|
|
598
|
+
ev.resolutions = judged.map((j) => j.res);
|
|
599
|
+
ev.voices = judged.map((j) => j.side);
|
|
600
|
+
const chosen = considered.find((c) => c.affordanceId === ev.chosenId);
|
|
601
|
+
ev.suggestion =
|
|
602
|
+
creditedResolution(ev.resolutions, chosen) ??
|
|
603
|
+
(ev.resolutions.length === 1 ? ev.resolutions[0] : undefined);
|
|
604
|
+
return withCommandRefusal(ev, cmd);
|
|
605
|
+
}
|
|
606
|
+
/** Apply capacity, conscience, per-voice distrust and omission vetoes, in that order. */
|
|
607
|
+
function prepareVetoes(p, input, ctx, suggestions) {
|
|
569
608
|
const affById = new Map(ctx.affordances.map((a) => [a.id, a]));
|
|
570
609
|
const duties = closingDuties(p, ctx);
|
|
571
610
|
const servesDuty = (aff) => duties.some((c) => keepsDuty(p, c, aff, ctx.now));
|
|
@@ -609,6 +648,11 @@ function evaluate(p, input, ctx, given, draw) {
|
|
|
609
648
|
out.vetoed = veto;
|
|
610
649
|
return out;
|
|
611
650
|
});
|
|
651
|
+
return { affById, duties, baseVeto, distrustOf, considered };
|
|
652
|
+
}
|
|
653
|
+
/** Select once using the supplied draw; prediction passes no draw and stays deterministic. */
|
|
654
|
+
function selectOption(p, considered, ctx, draw) {
|
|
655
|
+
const W = WILL_DEFAULTS;
|
|
612
656
|
// Selection: inertia for the current activity, then argmax or softmax.
|
|
613
657
|
const live = considered.filter((c) => !c.vetoed);
|
|
614
658
|
const current = p.activity;
|
|
@@ -636,67 +680,55 @@ function evaluate(p, input, ctx, given, draw) {
|
|
|
636
680
|
}
|
|
637
681
|
}
|
|
638
682
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
verdict: 'commanded',
|
|
659
|
-
reason: 'command',
|
|
660
|
-
says: '',
|
|
661
|
-
margin: co.margin,
|
|
662
|
-
};
|
|
663
|
-
if (co.ownAffordanceId !== null && co.ownAffordanceId !== co.targetAffordanceId)
|
|
664
|
-
res.insteadAffordanceId = co.ownAffordanceId;
|
|
665
|
-
const all = [
|
|
666
|
-
res,
|
|
667
|
-
...suggestions.map((s) => ({
|
|
668
|
-
voiceId: s.voiceId,
|
|
669
|
-
verdict: 'refused',
|
|
670
|
-
kind: 'cannot',
|
|
671
|
-
reason: 'commanded',
|
|
672
|
-
says: '',
|
|
673
|
-
})),
|
|
674
|
-
].sort((a, b) => cmpStr(a.voiceId, b.voiceId));
|
|
675
|
-
ev.resolutions = all;
|
|
676
|
-
ev.voices = all.map((r) => ({ id: r.voiceId, pressure: 0, accepted: 0, refused: 0 }));
|
|
677
|
-
ev.suggestion = res;
|
|
678
|
-
return ev;
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
if (suggestions.length === 0)
|
|
682
|
-
return withCommandRefusal(ev, cmd);
|
|
683
|
-
if (inBreak(p)) {
|
|
684
|
-
// During a mental break no voice reaches them; nothing is counted for or against any of them.
|
|
685
|
-
ev.resolutions = suggestions.map((s) => ({
|
|
686
|
-
voiceId: s.voiceId,
|
|
687
|
-
verdict: 'refused',
|
|
688
|
-
kind: 'cannot',
|
|
689
|
-
reason: 'break',
|
|
683
|
+
return { winner, ranked, score };
|
|
684
|
+
}
|
|
685
|
+
/** Return true when a command holds and completes the evaluation ahead of all suggestions. */
|
|
686
|
+
function arbitrateCommand(p, ctx, cmd, suggestions, prepared, selection, ev) {
|
|
687
|
+
const { considered, baseVeto, duties } = prepared;
|
|
688
|
+
const { winner, score } = selection;
|
|
689
|
+
const co = commandOutcome(p, considered, ctx, cmd, winner, score, baseVeto, duties);
|
|
690
|
+
ev.command = co;
|
|
691
|
+
if (co.holds && co.targetAffordanceId !== undefined) {
|
|
692
|
+
// Direct control: the commanded option is done; every other voice is set aside (no counters) and a
|
|
693
|
+
// distrust veto another voice caused does not stand in the way.
|
|
694
|
+
ev.chosenId = co.targetAffordanceId;
|
|
695
|
+
for (const c of considered)
|
|
696
|
+
if (c.vetoed?.reason === 'distrust')
|
|
697
|
+
delete c.vetoed;
|
|
698
|
+
const res = {
|
|
699
|
+
voiceId: cmd.voiceId,
|
|
700
|
+
verdict: 'commanded',
|
|
701
|
+
reason: 'command',
|
|
690
702
|
says: '',
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
if (
|
|
694
|
-
|
|
695
|
-
|
|
703
|
+
margin: co.margin,
|
|
704
|
+
};
|
|
705
|
+
if (co.ownAffordanceId !== null && co.ownAffordanceId !== co.targetAffordanceId)
|
|
706
|
+
res.insteadAffordanceId = co.ownAffordanceId;
|
|
707
|
+
const all = [
|
|
708
|
+
res,
|
|
709
|
+
...suggestions.map((s) => ({
|
|
710
|
+
voiceId: s.voiceId,
|
|
711
|
+
verdict: 'refused',
|
|
712
|
+
kind: 'cannot',
|
|
713
|
+
reason: 'commanded',
|
|
714
|
+
says: '',
|
|
715
|
+
})),
|
|
716
|
+
].sort((a, b) => cmpStr(a.voiceId, b.voiceId));
|
|
717
|
+
ev.resolutions = all;
|
|
718
|
+
ev.voices = all.map((r) => ({ id: r.voiceId, pressure: 0, accepted: 0, refused: 0 }));
|
|
719
|
+
ev.suggestion = res;
|
|
720
|
+
return true;
|
|
696
721
|
}
|
|
722
|
+
return false;
|
|
723
|
+
}
|
|
724
|
+
/** Judge each voice against the same selected option before resolving competing insistence. */
|
|
725
|
+
function judgeVoices(p, ctx, suggestions, prepared, selection) {
|
|
726
|
+
const W = WILL_DEFAULTS;
|
|
727
|
+
const { considered, affById, distrustOf } = prepared;
|
|
728
|
+
const { winner, ranked, score } = selection;
|
|
697
729
|
const winnerAff = winner ? affById.get(winner.affordanceId) : undefined;
|
|
698
730
|
const reason = dominantTerm(winner);
|
|
699
|
-
|
|
731
|
+
return suggestions.map((s) => {
|
|
700
732
|
const suggested = considered.filter((c) => {
|
|
701
733
|
const aff = affById.get(c.affordanceId);
|
|
702
734
|
return aff !== undefined && suggestionTargets(s, aff);
|
|
@@ -815,6 +847,10 @@ function evaluate(p, input, ctx, given, draw) {
|
|
|
815
847
|
: { affordanceId: bestSuggested.affordanceId, label: 'later' },
|
|
816
848
|
}));
|
|
817
849
|
});
|
|
850
|
+
}
|
|
851
|
+
/** Settle competing insistence in the existing voice order, preserving equal-trust/strength ties. */
|
|
852
|
+
function arbitrateInsistence(p, judged, considered, affById, ev) {
|
|
853
|
+
const W = WILL_DEFAULTS;
|
|
818
854
|
// Rule (a): at most one insisted option is complied with.
|
|
819
855
|
const insisting = judged.filter((j) => j.comply !== undefined);
|
|
820
856
|
let forcer;
|
|
@@ -882,13 +918,6 @@ function evaluate(p, input, ctx, given, draw) {
|
|
|
882
918
|
}
|
|
883
919
|
}
|
|
884
920
|
}
|
|
885
|
-
ev.resolutions = judged.map((j) => j.res);
|
|
886
|
-
ev.voices = judged.map((j) => j.side);
|
|
887
|
-
const chosen = considered.find((c) => c.affordanceId === ev.chosenId);
|
|
888
|
-
ev.suggestion =
|
|
889
|
-
creditedResolution(ev.resolutions, chosen) ??
|
|
890
|
-
(ev.resolutions.length === 1 ? ev.resolutions[0] : undefined);
|
|
891
|
-
return withCommandRefusal(ev, cmd);
|
|
892
921
|
}
|
|
893
922
|
/** Add the commanding voice's refusal (a command that did not hold) to the resolutions, in voice-id order. */
|
|
894
923
|
function withCommandRefusal(ev, cmd) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adam0white/human-framework",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.10.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",
|