@mindot/will 0.8.0 → 0.9.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/channels/discord.d.ts +67 -6
- package/dist/channels/discord.js +112 -6
- package/dist/channels/discord.js.map +1 -1
- package/dist/channels/whatsapp.d.ts +1 -1
- package/dist/channels/whatsapp.js +4 -1
- package/dist/channels/whatsapp.js.map +1 -1
- package/dist/cli.js +3174 -867
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3236 -1042
- package/dist/index.js.map +1 -1
- package/dist/mcp/effectors.d.ts +1 -1
- package/dist/{will-cS6k4uiJ.d.ts → will-DbDj_TEH.d.ts} +752 -17
- package/package.json +1 -1
- package/src/channels/discord.ts +189 -11
- package/src/channels/types.ts +90 -0
- package/src/channels/whatsapp.ts +13 -4
- package/src/cli.ts +9 -4
- package/src/cognition/agency/consequence.ts +122 -1
- package/src/cognition/agency/conversation.aim.ts +260 -0
- package/src/cognition/agency/engines/action.selector.ts +83 -2
- package/src/cognition/agency/engines/affordance.synthesizer.ts +90 -1
- package/src/cognition/agency/engines/motor.schema.executor.ts +152 -10
- package/src/cognition/agency/engines/reafference.engine.ts +117 -0
- package/src/cognition/agency/proactive.communicator.ts +19 -3
- package/src/cognition/agency/restart.ts +66 -0
- package/src/cognition/agency/selection.scoring.ts +33 -0
- package/src/cognition/agency/types.ts +35 -0
- package/src/cognition/cache/composition.ts +232 -0
- package/src/cognition/cache/deliberation.cache.ts +219 -0
- package/src/cognition/cache/fingerprint.ts +120 -0
- package/src/cognition/cache/types.ts +105 -0
- package/src/cognition/config.mirror.entities.ts +108 -0
- package/src/cognition/event.schemas.ts +22 -0
- package/src/cognition/faculties/autobiographical.narrator.ts +5 -10
- package/src/cognition/faculties/episodic.consolidator.ts +59 -3
- package/src/cognition/faculties/executive.engine/commands.ts +189 -14
- package/src/cognition/faculties/executive.engine/context.ts +67 -13
- package/src/cognition/faculties/executive.engine/deliberate.reasoning.ts +1 -1
- package/src/cognition/faculties/executive.engine/engine.ts +552 -131
- package/src/cognition/faculties/executive.engine/escalation.buffer.ts +162 -44
- package/src/cognition/faculties/executive.engine/facet.supervisor.ts +310 -65
- package/src/cognition/faculties/executive.engine/facet.ts +81 -26
- package/src/cognition/faculties/executive.engine/gating.ts +14 -14
- package/src/cognition/faculties/executive.engine/parser.ts +21 -1
- package/src/cognition/faculties/executive.engine/prompt.factory.ts +167 -19
- package/src/cognition/faculties/executive.engine/types.ts +69 -0
- package/src/cognition/faculties/goal.manager.ts +94 -14
- package/src/cognition/faculties/known.entity.tracker.ts +267 -28
- package/src/cognition/faculties/moral.evaluator.ts +8 -3
- package/src/cognition/faculties/persona.consolidator.ts +141 -0
- package/src/cognition/faculties/reputation.tracker.ts +66 -2
- package/src/cognition/faculties/self.model.updater.ts +19 -12
- package/src/cognition/faculties/social.perception.ts +47 -3
- package/src/cognition/faculties/threat.evaluator.ts +7 -0
- package/src/cognition/faculties/working.memory.ts +10 -20
- package/src/cognition/identity.entity.ts +205 -0
- package/src/cognition/index.ts +7 -0
- package/src/cognition/memory/vector.adapter.ts +12 -3
- package/src/cognition/memory/vector.embedder.ts +45 -2
- package/src/cognition/persona.prior.ts +6 -0
- package/src/cognition/senses/audition.engine/engine.ts +404 -46
- package/src/cognition/senses/base.sense.engine.ts +1 -1
- package/src/cognition/senses/index.ts +12 -0
- package/src/cognition/social.identity.ts +273 -0
- package/src/cognition/utilities/token.tracker.ts +58 -5
- package/src/core/orchestrator.ts +38 -0
- package/src/llm/index.ts +25 -8
- package/src/llm/routing.ts +6 -0
- package/src/llm/summarizer.ts +1 -1
- package/src/llm/wire.contracts.ts +19 -0
- package/src/pma/index.ts +67 -53
- package/src/sdk/will.ts +39 -6
- package/src/stem/assembly.audit.ts +1 -0
- package/src/stem/guards/identity.coherence.ts +1 -1
- package/src/stem/index.ts +79 -2
- package/src/stem/mind.ts +172 -55
- package/src/stem/tracts/outbox.writer.ts +40 -2
- package/src/cognition/faculties/executive.engine/messages.ts +0 -102
|
@@ -928,6 +928,22 @@ declare class DefaultOrchestrator implements Orchestrator {
|
|
|
928
928
|
* calls _executeTick() which handles pause/stop checks internally.
|
|
929
929
|
* The orchestrator is the sole driver of ticks.
|
|
930
930
|
*/
|
|
931
|
+
/**
|
|
932
|
+
* A plain SimulationEngine's `react()` is implicitly "finish inside the tick" —
|
|
933
|
+
* only an AsyncEngine is allowed to span ticks, and it does so by LAUNCHING work
|
|
934
|
+
* and landing it later (see async.engine.ts: "react() never awaits LLM calls").
|
|
935
|
+
* Nothing enforces that on everyone else, and the failure is silent and severe:
|
|
936
|
+
* every agency deadline is denominated in TICKS, so an engine that awaits network
|
|
937
|
+
* I/O does not merely run slowly, it rescales time for the whole mind.
|
|
938
|
+
*
|
|
939
|
+
* Measured: one rate-limited embedding call awaited inside EpisodicConsolidator
|
|
940
|
+
* made two consecutive ticks take 64.9s and 63.5s. `AWAIT_TIMEOUT` — 15 ticks,
|
|
941
|
+
* normally ~15s — silently became 15 minutes, so a communicate intent sat
|
|
942
|
+
* 'awaiting' forever and the serial selector never chose anything again. 45
|
|
943
|
+
* executive decisions produced one intent and zero delivered messages, with no
|
|
944
|
+
* error anywhere. This turns that into a line in the log the first time it happens.
|
|
945
|
+
*/
|
|
946
|
+
private _warnIfSlow;
|
|
931
947
|
private _runLoop;
|
|
932
948
|
private _shutdown;
|
|
933
949
|
stop(): void;
|
|
@@ -1332,7 +1348,6 @@ declare class WorkingMemory implements SimulationEngine, CognitiveEngine {
|
|
|
1332
1348
|
private _emitEvents;
|
|
1333
1349
|
private _items;
|
|
1334
1350
|
private _modulatedCapacity;
|
|
1335
|
-
private _currentFocusId;
|
|
1336
1351
|
private _activeGoalCount;
|
|
1337
1352
|
/**
|
|
1338
1353
|
* Monotonic suffix counter for injected WM item ids. Replaces Math.random()
|
|
@@ -1373,8 +1388,10 @@ declare class WorkingMemory implements SimulationEngine, CognitiveEngine {
|
|
|
1373
1388
|
*/
|
|
1374
1389
|
private _ingestGoals;
|
|
1375
1390
|
/**
|
|
1376
|
-
* Mark the currently focused entity's WM item as attended this tick
|
|
1377
|
-
*
|
|
1391
|
+
* Mark the currently focused entity's WM item as attended this tick, from the
|
|
1392
|
+
* `attention.focus` entities AttentionAllocator writes. (A second, bus-driven
|
|
1393
|
+
* branch used to sit above this one, labelled "preferred"; the event behind it was
|
|
1394
|
+
* never published, so this loop has always been the only path — see #114.)
|
|
1378
1395
|
*/
|
|
1379
1396
|
private _applyAttention;
|
|
1380
1397
|
/**
|
|
@@ -1446,6 +1463,10 @@ interface GoalState {
|
|
|
1446
1463
|
activatedAt: Tick;
|
|
1447
1464
|
deadline?: Tick;
|
|
1448
1465
|
tags: string[];
|
|
1466
|
+
/** Why this goal was abandoned, when it was. Set only on status 'abandoned'.
|
|
1467
|
+
* The reason used to be pushed onto `tags`, which threw once the goal had
|
|
1468
|
+
* been rehydrated from a deep-frozen state entity. */
|
|
1469
|
+
abandonedReason?: string;
|
|
1449
1470
|
/** Snapshot of memory.beliefs_total when this goal was activated.
|
|
1450
1471
|
* Used to compute epistemic progress: (currentBeliefs - baseline) / threshold. */
|
|
1451
1472
|
beliefsAtActivation: number;
|
|
@@ -1573,6 +1594,19 @@ declare class GoalManager implements SimulationEngine, CognitiveEngine {
|
|
|
1573
1594
|
* "learn" ↔ "learning").
|
|
1574
1595
|
*/
|
|
1575
1596
|
private _nudgeActionGoals;
|
|
1597
|
+
/**
|
|
1598
|
+
* Somebody answered. Advance the action goals that were about reaching them.
|
|
1599
|
+
*
|
|
1600
|
+
* Linked the way every other goal→person link in the system is linked: the
|
|
1601
|
+
* `keid:<id>` tag (selection.scoring's `collectGoalTargets` reads the same one
|
|
1602
|
+
* to lift a reach-out's goal relevance) or `requestingEntityId`, set when a
|
|
1603
|
+
* conversation escalation created the goal. Nothing here guesses from wording.
|
|
1604
|
+
*
|
|
1605
|
+
* Unmatched by design: a goal with no link to this person gets nothing, even if
|
|
1606
|
+
* it is tagged 'communication'. Being answered by one person is not progress on
|
|
1607
|
+
* wanting to talk to another.
|
|
1608
|
+
*/
|
|
1609
|
+
private _nudgeAnsweredGoals;
|
|
1576
1610
|
/** True when a metric completionCondition (e.g. "emotion.boredom < 40") is already met. */
|
|
1577
1611
|
private _isConditionMet;
|
|
1578
1612
|
private _evaluateMetricProgress;
|
|
@@ -1590,8 +1624,10 @@ declare class GoalManager implements SimulationEngine, CognitiveEngine {
|
|
|
1590
1624
|
type LLMCallCategory = 'executive' | 'summarizer' | 'embedding' | 'identity-guard';
|
|
1591
1625
|
/** The actor/subsystem doing the work. */
|
|
1592
1626
|
type LLMCallAttribute = 'master' | 'facet' | 'memory' | 'guard';
|
|
1627
|
+
/** The specific cognitive process being paid for. */
|
|
1628
|
+
type LLMCallProcess = 'cog' | 'decision' | 'ideation';
|
|
1593
1629
|
/** The specific cognitive function being paid for. */
|
|
1594
|
-
type LLMCallFunction = '
|
|
1630
|
+
type LLMCallFunction = '-' | 'deliberation' | 'conversation' | 'outreach' | 'planning' | 'supervision' | 'consolidation' | 'recall' | 'index' | 'identity-coherence';
|
|
1595
1631
|
/** One attributed ledger record (5-axis attribution + tokens + cost). */
|
|
1596
1632
|
type TokenLedgerRecord = Record<string, unknown>;
|
|
1597
1633
|
type TokenRecordListener = (record: TokenLedgerRecord) => void;
|
|
@@ -1659,8 +1695,23 @@ interface TokenUsage {
|
|
|
1659
1695
|
* zero.
|
|
1660
1696
|
*/
|
|
1661
1697
|
priced: boolean;
|
|
1698
|
+
/**
|
|
1699
|
+
* How much this call demanded, 0..1 — the cognitive measure the router saw.
|
|
1700
|
+
*
|
|
1701
|
+
* Recorded so routing can be ANSWERED rather than argued. Every call computes
|
|
1702
|
+
* this, routes on it, and until now threw it away — which left questions like
|
|
1703
|
+
* "is deliberation being rated by the tick's mood rather than the stakes of
|
|
1704
|
+
* its own choice?" with no dataset at all.
|
|
1705
|
+
*
|
|
1706
|
+
* Absent means UNMEASURED, never zero. It must stay nullable all the way to
|
|
1707
|
+
* storage: a call that never reported demand and a call that reported 0.0 are
|
|
1708
|
+
* different facts, and collapsing them would put a floor of invented
|
|
1709
|
+
* confidence under exactly the analysis this exists to enable.
|
|
1710
|
+
*/
|
|
1711
|
+
demand?: number;
|
|
1662
1712
|
category: LLMCallCategory;
|
|
1663
1713
|
attribute: LLMCallAttribute;
|
|
1714
|
+
process: LLMCallProcess;
|
|
1664
1715
|
function: LLMCallFunction;
|
|
1665
1716
|
/** Optional specific id or namespace: facet id, entity id, model name. */
|
|
1666
1717
|
scope?: string;
|
|
@@ -1711,6 +1762,8 @@ declare class TokenTracker implements SimulationEngine {
|
|
|
1711
1762
|
private _categoryTokens;
|
|
1712
1763
|
private _functionCosts;
|
|
1713
1764
|
private _functionTokens;
|
|
1765
|
+
private _processCosts;
|
|
1766
|
+
private _processTokens;
|
|
1714
1767
|
private _providerCosts;
|
|
1715
1768
|
private _providerTokens;
|
|
1716
1769
|
private _tickCosts;
|
|
@@ -1757,6 +1810,13 @@ declare class TokenTracker implements SimulationEngine {
|
|
|
1757
1810
|
prompt: number;
|
|
1758
1811
|
completion: number;
|
|
1759
1812
|
}>;
|
|
1813
|
+
/** Cost broken down by process ('decision' | 'ideation' | 'cog'). */
|
|
1814
|
+
get processBreakdown(): ReadonlyMap<string, number>;
|
|
1815
|
+
/** Token counts (prompt + completion) broken down by process. */
|
|
1816
|
+
get processTokenBreakdown(): ReadonlyMap<string, {
|
|
1817
|
+
prompt: number;
|
|
1818
|
+
completion: number;
|
|
1819
|
+
}>;
|
|
1760
1820
|
/**
|
|
1761
1821
|
* Cost broken down by provider ('anthropic' | 'glm' | 'moonshot' | …), plus
|
|
1762
1822
|
* an `unattributed` bucket for usage recorded without one.
|
|
@@ -1819,12 +1879,26 @@ declare class OpenAICompatibleEmbedder implements EmbeddingProvider {
|
|
|
1819
1879
|
private _maxConcurrency;
|
|
1820
1880
|
private _timeoutMs;
|
|
1821
1881
|
private _tokenTracker;
|
|
1882
|
+
/**
|
|
1883
|
+
* Own gate — the same LLMSemaphore the LLM calls use, on a separate instance so
|
|
1884
|
+
* embeddings and reasoning do not compete for one another's slots. It bounds the
|
|
1885
|
+
* fan-out that produced the 10.7s tail, and `withGate` additionally retries a 429
|
|
1886
|
+
* with backoff, which a bare `embed()` previously surfaced as a hard failure.
|
|
1887
|
+
*/
|
|
1888
|
+
private _gate;
|
|
1822
1889
|
constructor(config: {
|
|
1823
1890
|
modelName: string;
|
|
1824
1891
|
dimensions: number;
|
|
1825
1892
|
apiUrl: string;
|
|
1826
1893
|
apiKey?: string | null;
|
|
1827
|
-
/**
|
|
1894
|
+
/**
|
|
1895
|
+
* Max embedding requests in flight at once — across ALL callers, not just one
|
|
1896
|
+
* embedBatch(). Default 4, chosen from measured provider behaviour rather than
|
|
1897
|
+
* taste: gemini-embedding-001 answers a lone request in ~1.1s, but queues hard
|
|
1898
|
+
* under fan-out — at 8 in flight the slowest three took 10.7s (all HTTP 200, no
|
|
1899
|
+
* 429, simply serialized). That tail is what made recall exceed its 5s budget
|
|
1900
|
+
* and return "no recall" while a mind with six live facets was asking.
|
|
1901
|
+
*/
|
|
1828
1902
|
maxConcurrency?: number;
|
|
1829
1903
|
/** @deprecated use maxConcurrency — kept as its fallback for back-compat. */
|
|
1830
1904
|
batchSize?: number;
|
|
@@ -1837,7 +1911,15 @@ declare class OpenAICompatibleEmbedder implements EmbeddingProvider {
|
|
|
1837
1911
|
*/
|
|
1838
1912
|
tokenTracker?: TokenTracker | null;
|
|
1839
1913
|
});
|
|
1914
|
+
/**
|
|
1915
|
+
* Embed one item, gated. Every caller funnels through here — a facet building a
|
|
1916
|
+
* prompt, the master recalling, the consolidator indexing — so the gate is the
|
|
1917
|
+
* only place total in-flight fan-out is bounded. Waiting for a slot is strictly
|
|
1918
|
+
* better than the alternative it replaces: an ungated request that returns after
|
|
1919
|
+
* the recall budget has already expired is a request whose answer is thrown away.
|
|
1920
|
+
*/
|
|
1840
1921
|
embed(content: unknown, fn?: EmbedFunction): Promise<number[]>;
|
|
1922
|
+
private _embedOnce;
|
|
1841
1923
|
embedBatch(contents: unknown[], fn?: EmbedFunction): Promise<number[][]>;
|
|
1842
1924
|
areEquivalent(embedding1: number[], embedding2: number[], tolerance?: number): boolean;
|
|
1843
1925
|
}
|
|
@@ -2003,6 +2085,16 @@ declare class DefaultVectorMemoryAdapter implements VectorMemoryAdapter {
|
|
|
2003
2085
|
persist(): Promise<void>;
|
|
2004
2086
|
load(): Promise<void>;
|
|
2005
2087
|
private _evictColdest;
|
|
2088
|
+
/**
|
|
2089
|
+
* Throttle, NOT a debounce. The previous version cleared and re-armed the timer on
|
|
2090
|
+
* every index(), so it only ever fired after 5s of complete inactivity — and a mind
|
|
2091
|
+
* consolidating steadily indexes far more often than that, so the write was pushed
|
|
2092
|
+
* back indefinitely and the index never reached disk while it was awake.
|
|
2093
|
+
*
|
|
2094
|
+
* A pending timer is now left alone: the first write after a quiet period sets the
|
|
2095
|
+
* deadline, and everything indexed within the window rides along on it. Persist is
|
|
2096
|
+
* bounded at 5s from the FIRST pending change rather than the last.
|
|
2097
|
+
*/
|
|
2006
2098
|
private _schedulePersist;
|
|
2007
2099
|
}
|
|
2008
2100
|
|
|
@@ -2065,6 +2157,13 @@ declare class EpisodicConsolidator implements SimulationEngine, CognitiveEngine
|
|
|
2065
2157
|
private _affectDominance;
|
|
2066
2158
|
private _bus;
|
|
2067
2159
|
private _vectorMemory;
|
|
2160
|
+
/**
|
|
2161
|
+
* In-flight background indexing. Indexing is deliberately not awaited inside
|
|
2162
|
+
* react() (a rate-limit retry chain would stall the whole tick loop), so this is
|
|
2163
|
+
* the handle for the two callers that genuinely must wait for it: shutdown,
|
|
2164
|
+
* before persisting the index, and tests asserting on it.
|
|
2165
|
+
*/
|
|
2166
|
+
private _indexing;
|
|
2068
2167
|
private _embedder;
|
|
2069
2168
|
private _autoIndex;
|
|
2070
2169
|
private readonly _model;
|
|
@@ -2102,6 +2201,8 @@ declare class EpisodicConsolidator implements SimulationEngine, CognitiveEngine
|
|
|
2102
2201
|
* Other metadata narrowing (sourceType / tags) remains the caller's job on the
|
|
2103
2202
|
* returned episodes (which carry all metadata).
|
|
2104
2203
|
*/
|
|
2204
|
+
/** Await any background indexing still in flight. Shutdown and tests only. */
|
|
2205
|
+
flushIndexing(): Promise<void>;
|
|
2105
2206
|
semanticQuery(query: unknown, filters?: {
|
|
2106
2207
|
minSimilarity?: number;
|
|
2107
2208
|
limit?: number;
|
|
@@ -2681,6 +2782,8 @@ interface RoutingRule {
|
|
|
2681
2782
|
category?: LLMCallMeta['category'];
|
|
2682
2783
|
/** Match `LLMCallMeta.attribute` exactly (e.g. 'master', 'facet', 'guard'). */
|
|
2683
2784
|
attribute?: LLMCallMeta['attribute'];
|
|
2785
|
+
/** Match `LLMCallMeta.process` exactly (e.g. 'decision', 'ideation'). */
|
|
2786
|
+
process?: LLMCallMeta['process'];
|
|
2684
2787
|
/** Match `LLMCallMeta.function` exactly (e.g. 'decision', 'consolidation'). */
|
|
2685
2788
|
function?: LLMCallMeta['function'];
|
|
2686
2789
|
/**
|
|
@@ -2852,6 +2955,8 @@ interface LLMCallMeta {
|
|
|
2852
2955
|
/** The actor/subsystem doing the work. */
|
|
2853
2956
|
attribute: LLMCallAttribute;
|
|
2854
2957
|
/** The specific cognitive function. */
|
|
2958
|
+
process: LLMCallProcess;
|
|
2959
|
+
/** The specific cognitive function. */
|
|
2855
2960
|
function: LLMCallFunction;
|
|
2856
2961
|
/** Optional specific id or namespace: facet id, entity id, model name. */
|
|
2857
2962
|
scope?: string;
|
|
@@ -2861,13 +2966,23 @@ interface LLMCallMeta {
|
|
|
2861
2966
|
* How much this call demands, 0..1 — MODEL_ROUTING W0.
|
|
2862
2967
|
*
|
|
2863
2968
|
* A *cognitive* measure, never a commercial one: it says how consequential or
|
|
2864
|
-
* uncertain this moment is, never who is paying for it.
|
|
2865
|
-
*
|
|
2866
|
-
*
|
|
2867
|
-
*
|
|
2868
|
-
* the
|
|
2869
|
-
*
|
|
2870
|
-
*
|
|
2969
|
+
* uncertain this moment is, never who is paying for it.
|
|
2970
|
+
*
|
|
2971
|
+
* What actually reports it today:
|
|
2972
|
+
* · the master and every facet — including the deliberation facet — forward
|
|
2973
|
+
* `effortScore`, the a-priori effort gate (uncertainty, prior confidence,
|
|
2974
|
+
* novelty, a pending reply, stress load);
|
|
2975
|
+
* · structurally background work (summarising, the identity guard) reports a
|
|
2976
|
+
* low constant, because it is background whether the mind is calm or in
|
|
2977
|
+
* crisis.
|
|
2978
|
+
*
|
|
2979
|
+
* Note what is NOT here: agency's `stakes( winner, bias )` — the consequence
|
|
2980
|
+
* of the specific choice under contest — is computed in
|
|
2981
|
+
* `agency/selection.scoring.ts` and never reaches a call. So a deliberation
|
|
2982
|
+
* facet currently reports the tick's general effort, not the stakes of the
|
|
2983
|
+
* choice it is deliberating. Carrying it is MODEL_ROUTING W1, still open.
|
|
2984
|
+
* This comment previously claimed deliberation passed those stakes; it does
|
|
2985
|
+
* not, and a doc comment that ships to npm is a bad place to be aspirational.
|
|
2871
2986
|
*
|
|
2872
2987
|
* Absent means UNKNOWN, not zero: a consumer must fall back to its default
|
|
2873
2988
|
* rather than treat a missing value as "cheapest possible".
|
|
@@ -3137,6 +3252,18 @@ interface ExecutiveOutputFull {
|
|
|
3137
3252
|
name?: string;
|
|
3138
3253
|
learned?: string[];
|
|
3139
3254
|
feeling?: number;
|
|
3255
|
+
/**
|
|
3256
|
+
* "This is the same someone as that" — another keid I now believe is this
|
|
3257
|
+
* same referent, fusing two of my records into one.
|
|
3258
|
+
*
|
|
3259
|
+
* The mind's own verdict on an identity, and it may do what the recognition
|
|
3260
|
+
* heuristic will not: absorb an ESTABLISHED relationship. The heuristic is
|
|
3261
|
+
* right to refuse — fusing two real people who share a name would take one of
|
|
3262
|
+
* them's whole history — but the mind has evidence a name-match does not,
|
|
3263
|
+
* usually because somebody just told it. Without this, the same human
|
|
3264
|
+
* well-established on two channels stayed two people permanently.
|
|
3265
|
+
*/
|
|
3266
|
+
sameAs?: string;
|
|
3140
3267
|
}>;
|
|
3141
3268
|
newGoals?: Array<{
|
|
3142
3269
|
description: string;
|
|
@@ -3155,6 +3282,8 @@ interface ExecutiveOutputFull {
|
|
|
3155
3282
|
reason: string;
|
|
3156
3283
|
}>;
|
|
3157
3284
|
selfObservations?: string[];
|
|
3285
|
+
/** Compound actions the mind is naming as single skills (see ProposedSkill). */
|
|
3286
|
+
newSkills?: ProposedSkill[];
|
|
3158
3287
|
/**
|
|
3159
3288
|
* Plain-text reply from a conversation facet — populated by parseResponse()
|
|
3160
3289
|
* from the [REPLY_TEXT]...[/REPLY_TEXT] block.
|
|
@@ -3162,6 +3291,11 @@ interface ExecutiveOutputFull {
|
|
|
3162
3291
|
* Paragraphs (double-newline separated) map to separate reply bubbles.
|
|
3163
3292
|
*/
|
|
3164
3293
|
replyText?: string;
|
|
3294
|
+
/**
|
|
3295
|
+
* Set when the facet declared it is NOT speaking this cycle, carrying why.
|
|
3296
|
+
* Present ⇒ nothing is sent, whatever else the response contains.
|
|
3297
|
+
*/
|
|
3298
|
+
noMessage?: string;
|
|
3165
3299
|
/**
|
|
3166
3300
|
* @deprecated Legacy JSON reply format — no longer emitted by conversation facets.
|
|
3167
3301
|
* Kept for backward compatibility with any tests/tooling that inspect parsed output.
|
|
@@ -3211,6 +3345,24 @@ interface ExecutiveEngineConfig$1 {
|
|
|
3211
3345
|
cooldownTicks?: number;
|
|
3212
3346
|
bus?: CognitiveBus;
|
|
3213
3347
|
}
|
|
3348
|
+
/**
|
|
3349
|
+
* A compound action the mind names as one thing it does — "when I do A then B,
|
|
3350
|
+
* that is <name>". Registered into the SchemaRepertoire as a composite, after
|
|
3351
|
+
* which it competes as a single affordance and can proceduralize into a habit.
|
|
3352
|
+
*
|
|
3353
|
+
* This is the creation seam for the instrumental→habitual gradient. Before it,
|
|
3354
|
+
* `agency.composite.proposed` was subscribed by ReafferenceEngine — whose handler
|
|
3355
|
+
* is the only caller of `registerComposite()` anywhere — and published by nothing,
|
|
3356
|
+
* so no Will could ever hold a skill beyond the innate floor (#114).
|
|
3357
|
+
*/
|
|
3358
|
+
interface ProposedSkill {
|
|
3359
|
+
/** What the mind calls it. Becomes the schema id. */
|
|
3360
|
+
id: string;
|
|
3361
|
+
/** The sub-schemas it is made of, in order. Two or more, or it is not compound. */
|
|
3362
|
+
composedOf: string[];
|
|
3363
|
+
tags?: string[];
|
|
3364
|
+
cost?: number;
|
|
3365
|
+
}
|
|
3214
3366
|
|
|
3215
3367
|
/**
|
|
3216
3368
|
* PromptFactory — single source of truth for all executive prompts
|
|
@@ -3298,6 +3450,18 @@ interface FocusSection {
|
|
|
3298
3450
|
* only sees that person's plans. When unset, those sections show all.
|
|
3299
3451
|
*/
|
|
3300
3452
|
awarenessEntityId?: string;
|
|
3453
|
+
/**
|
|
3454
|
+
* Optional: WHO this facet is engaged with — the keid and the name the mind has
|
|
3455
|
+
* learned for them. Reported back to the master on every `executive.facet.sync`.
|
|
3456
|
+
*
|
|
3457
|
+
* Without it the master was told, in its own system prompt, that "focused facets
|
|
3458
|
+
* may run simultaneously… their reasoning syncs back to me" while the sync payload
|
|
3459
|
+
* carried only a facetId and a confidence number — so a mind holding two live
|
|
3460
|
+
* conversations could not tell you whose they were. The master is the singular
|
|
3461
|
+
* seat: it has to know who is at the table to reason about them together.
|
|
3462
|
+
*/
|
|
3463
|
+
subjectEntityId?: string;
|
|
3464
|
+
subjectName?: string;
|
|
3301
3465
|
/**
|
|
3302
3466
|
* Optional: Provided by the creating engine to convert the LLM's parsed output
|
|
3303
3467
|
* into a domain-specific decision payload.
|
|
@@ -3324,6 +3488,18 @@ interface FacetReport {
|
|
|
3324
3488
|
contextId?: string;
|
|
3325
3489
|
/** Optional dynamic instructions to append to the user message */
|
|
3326
3490
|
instructions?: string;
|
|
3491
|
+
/**
|
|
3492
|
+
* Attend to something else for THIS report only, leaving the facet's standing
|
|
3493
|
+
* focus untouched.
|
|
3494
|
+
*
|
|
3495
|
+
* A facet's focus was a single mutable field, so anything that wanted a live
|
|
3496
|
+
* facet to consider one different thing had to `setFocus()` first — clobbering
|
|
3497
|
+
* whatever the facet was already set up for, and racing with any report already
|
|
3498
|
+
* queued behind it. That is why a self-initiated message to someone the mind was
|
|
3499
|
+
* ALREADY talking to had to be composed by a separate, transient facet that could
|
|
3500
|
+
* not see the live conversation at all.
|
|
3501
|
+
*/
|
|
3502
|
+
focus?: FocusSection;
|
|
3327
3503
|
}
|
|
3328
3504
|
interface FacetDecision {
|
|
3329
3505
|
facetId: string;
|
|
@@ -3333,6 +3509,16 @@ interface FacetDecision {
|
|
|
3333
3509
|
decision: unknown;
|
|
3334
3510
|
reasoning: string;
|
|
3335
3511
|
confidence: number;
|
|
3512
|
+
/**
|
|
3513
|
+
* Sim tick this decision was reasoned at.
|
|
3514
|
+
*
|
|
3515
|
+
* The facet has always known it and never passed it on, so a subscriber writing
|
|
3516
|
+
* state in response had no deterministic clock and reached for a process-local
|
|
3517
|
+
* counter instead — which resets on restart and collides. Never wall-clock: this
|
|
3518
|
+
* reaches ids that live in state, and a wall-clock id makes recorded and replayed
|
|
3519
|
+
* runs diverge (R2).
|
|
3520
|
+
*/
|
|
3521
|
+
tick: number;
|
|
3336
3522
|
}
|
|
3337
3523
|
type FacetEventListener = (decision: FacetDecision) => void;
|
|
3338
3524
|
interface ExecutiveFacetHandle {
|
|
@@ -3366,6 +3552,44 @@ interface ExecutiveFacetHandle {
|
|
|
3366
3552
|
onReaped: (handler: () => void) => void;
|
|
3367
3553
|
}
|
|
3368
3554
|
|
|
3555
|
+
/**
|
|
3556
|
+
* DeliberationCache — types and contracts.
|
|
3557
|
+
*
|
|
3558
|
+
* The cache stores past executive outputs keyed by a deterministic
|
|
3559
|
+
* cognitive fingerprint. It is pure, deterministic, and R2-safe:
|
|
3560
|
+
* the same state + same history ⇒ same retrieval + same composition.
|
|
3561
|
+
*
|
|
3562
|
+
* Scope note: Phase 1 caches the ACTIONS block only. The composed output
|
|
3563
|
+
* is a valid `ExecutiveOutputFull` carrying the three required fields
|
|
3564
|
+
* (actions, reasoning, confidence) plus whatever optional blocks the
|
|
3565
|
+
* enabled scopes cover. Everything else stays undefined and the existing
|
|
3566
|
+
* downstream (`buildStateCommands`) treats it as "nothing to do", which is
|
|
3567
|
+
* exactly the intended Phase-1 behaviour.
|
|
3568
|
+
*/
|
|
3569
|
+
|
|
3570
|
+
/** Which blocks of the executive output the cache may synthesise. */
|
|
3571
|
+
type CacheScope = 'actions' | 'goals' | 'beliefs';
|
|
3572
|
+
interface DeliberationCacheConfig {
|
|
3573
|
+
/** Maximum patterns to retain. Lowest (competence × recency) evicted when full. */
|
|
3574
|
+
maxPatterns?: number;
|
|
3575
|
+
/** Neighbors retrieved for composition. */
|
|
3576
|
+
k?: number;
|
|
3577
|
+
/** Minimum similarity for a stored pattern to count as a neighbor. */
|
|
3578
|
+
minSimilarity?: number;
|
|
3579
|
+
/** Confidence threshold θ — cache hit requires ρ ≥ θ. Start conservative. */
|
|
3580
|
+
theta?: number;
|
|
3581
|
+
/** Temperature for softmax weights over neighbors. */
|
|
3582
|
+
tau?: number;
|
|
3583
|
+
/** Learning rate (EMA) for competence updates. */
|
|
3584
|
+
eta?: number;
|
|
3585
|
+
/** Competence decay per executive cycle (applied via decay()). */
|
|
3586
|
+
decayPerCycle?: number;
|
|
3587
|
+
/** Verify 1-in-N cache hits against the LLM (0 = never). */
|
|
3588
|
+
verifyEveryNHits?: number;
|
|
3589
|
+
/** Which output blocks to synthesise. Phase 1 default: ['actions']. */
|
|
3590
|
+
scopes?: CacheScope[];
|
|
3591
|
+
}
|
|
3592
|
+
|
|
3369
3593
|
interface ExecutiveEngineConfig {
|
|
3370
3594
|
executiveInterval?: number;
|
|
3371
3595
|
cooldownTicks?: number;
|
|
@@ -3379,12 +3603,17 @@ declare class ExecutiveEngine extends AsyncEngine implements CognitiveEngine {
|
|
|
3379
3603
|
private _consumedBufferEntries;
|
|
3380
3604
|
private _llmDirector;
|
|
3381
3605
|
private _testMode;
|
|
3382
|
-
private _messageQueue;
|
|
3383
3606
|
private _recentActionTypes;
|
|
3384
3607
|
private _coherenceVersion;
|
|
3385
3608
|
private _lastEpistemicUncertainty;
|
|
3386
3609
|
private _lastExecutiveOutput;
|
|
3387
3610
|
private _lastExecutiveTick;
|
|
3611
|
+
private _cache;
|
|
3612
|
+
private _cacheRestored;
|
|
3613
|
+
private _pendingVerify;
|
|
3614
|
+
private _lastCacheHit;
|
|
3615
|
+
private _lastCacheConfidence;
|
|
3616
|
+
private _lastCacheNeighborCount;
|
|
3388
3617
|
private _willId;
|
|
3389
3618
|
/**
|
|
3390
3619
|
* The Will's default model (config.model's `executive` role, resolved in
|
|
@@ -3406,11 +3635,28 @@ declare class ExecutiveEngine extends AsyncEngine implements CognitiveEngine {
|
|
|
3406
3635
|
private _inbox;
|
|
3407
3636
|
private _tokenTracker;
|
|
3408
3637
|
private readonly _facetSupervisor;
|
|
3409
|
-
|
|
3638
|
+
/**
|
|
3639
|
+
* Who each live facet is engaged with, learned from `executive.facet.sync`.
|
|
3640
|
+
* Keyed by facetId; the last sync wins. Rendered into the master's own prompt so
|
|
3641
|
+
* the singular seat can reason across its conversations "as if they were sitting
|
|
3642
|
+
* at the same table" — which it cannot do while it only knows facet numbers.
|
|
3643
|
+
* Stale entries age out on read (see _activeConversations).
|
|
3644
|
+
*/
|
|
3645
|
+
private _facetSubjects;
|
|
3410
3646
|
private readonly _model;
|
|
3411
3647
|
private readonly _generativeModel;
|
|
3412
3648
|
private _summarizerRestored;
|
|
3413
3649
|
private _lastStateRef;
|
|
3650
|
+
/**
|
|
3651
|
+
* The tick currently being processed, refreshed every react() — distinct from
|
|
3652
|
+
* `_lastStateRef` (which tracks the REASONING tick and must not move under
|
|
3653
|
+
* onReasoningComplete) and from `_lastExecutiveTick` (the last cycle that ran).
|
|
3654
|
+
*
|
|
3655
|
+
* Off-tick arrivals — a facet handoff, in particular — need to be stamped with
|
|
3656
|
+
* when they actually happened. Using `_lastExecutiveTick` for that dated them to
|
|
3657
|
+
* the last master cycle, which can be hundreds of ticks behind.
|
|
3658
|
+
*/
|
|
3659
|
+
private _currentTick;
|
|
3414
3660
|
private readonly _deferred;
|
|
3415
3661
|
private _chunkBroadcaster;
|
|
3416
3662
|
private readonly _escalations;
|
|
@@ -3505,10 +3751,22 @@ declare class ExecutiveEngine extends AsyncEngine implements CognitiveEngine {
|
|
|
3505
3751
|
* spawn site sets a focus whose `function` matches its role — so the routed
|
|
3506
3752
|
* answer is the same one, decided later and from the work itself.
|
|
3507
3753
|
*/
|
|
3508
|
-
spawnFacet(role?: 'deliberation' | 'conversation' | 'outreach' | 'supervision'
|
|
3754
|
+
spawnFacet(role?: 'deliberation' | 'conversation' | 'outreach' | 'supervision',
|
|
3755
|
+
/**
|
|
3756
|
+
* What this facet is FOR — see `FacetSpawnDeps.key`. Two spawns with the same
|
|
3757
|
+
* key get the same facet, so callers no longer each invent their own dedup
|
|
3758
|
+
* (and `authorOutreach`, which had none, no longer opens a rival facet on a
|
|
3759
|
+
* person the mind is already talking to).
|
|
3760
|
+
*/
|
|
3761
|
+
key?: string): {
|
|
3509
3762
|
attention: 'available' | 'full';
|
|
3510
3763
|
handle?: ExecutiveFacetHandle;
|
|
3511
3764
|
};
|
|
3765
|
+
/**
|
|
3766
|
+
* The facet already attending to `key`, if one is open — without spawning.
|
|
3767
|
+
* See FacetSupervisor.handleFor.
|
|
3768
|
+
*/
|
|
3769
|
+
facetFor(key: string): ExecutiveFacetHandle | undefined;
|
|
3512
3770
|
subscribes(): string[];
|
|
3513
3771
|
publishes(): CognitiveEventSchema[];
|
|
3514
3772
|
snapshot(): Record<string, unknown>;
|
|
@@ -3520,12 +3778,119 @@ declare class ExecutiveEngine extends AsyncEngine implements CognitiveEngine {
|
|
|
3520
3778
|
* its `executive.last_tick` metric reflects whether our prior commands landed.
|
|
3521
3779
|
*/
|
|
3522
3780
|
react(delta: Duration, tick: Tick, state: ReadonlySimulationState, context: SimulationContext): Promise<EngineResult>;
|
|
3781
|
+
/**
|
|
3782
|
+
* What the mind is attending to because a facet is reasoning about it, as
|
|
3783
|
+
* `attention.demand` entities the AttentionAllocator allocates real capacity
|
|
3784
|
+
* against (`_extractSalienceSignals` reads this type; `costPerFocus` is then
|
|
3785
|
+
* charged against the same 100-unit budget as perceptual foci).
|
|
3786
|
+
*
|
|
3787
|
+
* This closes a loop that was open in one direction only: the allocator's
|
|
3788
|
+
* `freeFraction` scaled the facet budget, but facets never appeared in
|
|
3789
|
+
* `_activeFocus`, so holding three conversations reported exactly as much spare
|
|
3790
|
+
* attention as holding none. The budget was being scaled by a signal blind to the
|
|
3791
|
+
* thing it was bounding.
|
|
3792
|
+
*
|
|
3793
|
+
* `urgency` sits below 1 on purpose: a live conversation is a genuine claim on
|
|
3794
|
+
* attention but must not automatically outrank every percept — the allocator sorts
|
|
3795
|
+
* candidates by salience into `maxFoci` slots, and a facet that always won would
|
|
3796
|
+
* starve perception. Only BUSY facets are charged; an open-but-quiet thread is one
|
|
3797
|
+
* the mind is in, not one it is attending to.
|
|
3798
|
+
*/
|
|
3799
|
+
private _facetAttentionDemands;
|
|
3523
3800
|
protected shouldAct(state: ReadonlySimulationState, tick: Tick, _context: SimulationContext): boolean;
|
|
3524
3801
|
protected readState(state: ReadonlySimulationState, tick: Tick): ReasoningFootprint;
|
|
3525
3802
|
protected reasonAsync(footprint: ReasoningFootprint, state: ReadonlySimulationState, context: SimulationContext, stream: IntermediateStream): Promise<unknown>;
|
|
3526
3803
|
protected onIntermediateResult(step: string, result: unknown, _footprint: ReasoningFootprint, _context: SimulationContext): StateCommands | null;
|
|
3527
3804
|
protected onReasoningComplete(output: unknown, footprint: ReasoningFootprint, _context: SimulationContext): StateCommands;
|
|
3528
|
-
|
|
3805
|
+
/**
|
|
3806
|
+
* The people the mind is in conversation with right now, newest first.
|
|
3807
|
+
*
|
|
3808
|
+
* Pruned against the supervisor's live facets on every read: a reaped facet is a
|
|
3809
|
+
* conversation that has ended, and a master that still believes it is mid-thread
|
|
3810
|
+
* with someone reasons about a table that is no longer there.
|
|
3811
|
+
*/
|
|
3812
|
+
private _activeConversations;
|
|
3813
|
+
/**
|
|
3814
|
+
* Facet sync — remember WHO each facet is with, and wake the master.
|
|
3815
|
+
*
|
|
3816
|
+
* Reached from `onCognitiveEvent`, NOT from its own `bus.subscribe`. The bus
|
|
3817
|
+
* stores one subscription per engineId (`_subscriptions.set( engineId, … )`),
|
|
3818
|
+
* so a second `subscribe(this.name, …)` silently REPLACES the first — and the
|
|
3819
|
+
* orchestrator registers `subscribe( engine.name, engine.subscribes(), … )`
|
|
3820
|
+
* after `attachBus`, which replaced everything registered here. Two dedicated
|
|
3821
|
+
* handlers used to be installed at this point; the second overwrote the first
|
|
3822
|
+
* and the orchestrator then overwrote that, so neither ever ran. The escalation
|
|
3823
|
+
* leg had been dead in production for its whole life: a facet could escalate,
|
|
3824
|
+
* the audition engine published, and nothing was listening.
|
|
3825
|
+
*/
|
|
3826
|
+
/**
|
|
3827
|
+
* Retire undertakings the mind has already honoured, and refuse to restate one
|
|
3828
|
+
* it is already carrying.
|
|
3829
|
+
*
|
|
3830
|
+
* An undertaking percept says, in the first person, "I said I would reach X and
|
|
3831
|
+
* nothing has gone to them yet". That sentence has to stop being true at some
|
|
3832
|
+
* point, and nothing made it stop. Measured on a live Will: SEVEN of them
|
|
3833
|
+
* accumulated in state, every one still asserting nothing had been sent, while
|
|
3834
|
+
* a `conversation.sent` to that person sat right beside them. She read seven
|
|
3835
|
+
* standing unfulfilled promises every cycle and dutifully sent the same message
|
|
3836
|
+
* again, five times in five minutes and once more in the next session — the
|
|
3837
|
+
* percept meant to stop her forgetting a promise was making her unable to
|
|
3838
|
+
* believe she had kept it.
|
|
3839
|
+
*
|
|
3840
|
+
* Discharged by EVIDENCE, not by a timer: a `conversation.sent` to that target,
|
|
3841
|
+
* written no earlier than the undertaking, means the contact happened. That
|
|
3842
|
+
* record is durable and snapshots with the state, so the discharge survives a
|
|
3843
|
+
* restart exactly as the promise does — which the tick-scoped satiation in
|
|
3844
|
+
* `enactionFootprint` deliberately cannot.
|
|
3845
|
+
*
|
|
3846
|
+
* It stays a decision, not an erasure. Retiring the percept removes the standing
|
|
3847
|
+
* claim that the words are unsent; whether to say more to that person is then an
|
|
3848
|
+
* ordinary competition like any other.
|
|
3849
|
+
*/
|
|
3850
|
+
private _reconcileUndertakings;
|
|
3851
|
+
private _onFacetSync;
|
|
3852
|
+
/**
|
|
3853
|
+
* A focused part of me surfaced something the singular seat owns — work to plan
|
|
3854
|
+
* (`escalation`) or an intention toward a third party (`undertaking`).
|
|
3855
|
+
*
|
|
3856
|
+
* ONE handler for every facet type. This was `_onAuditionTaskSignal`, listening
|
|
3857
|
+
* on a topic named for one sense engine and typed with one sense engine's nouns
|
|
3858
|
+
* (`entityId`, `threadId`), which meant a planning, supervision or deliberation
|
|
3859
|
+
* facet had no way to hand anything up at all. See EscalationBuffer for the full
|
|
3860
|
+
* rationale; new kinds go in `HandoffBody`, not in a new topic and a new handler
|
|
3861
|
+
* beside this one.
|
|
3862
|
+
*
|
|
3863
|
+
* Master stays out of the reply path entirely:
|
|
3864
|
+
* • The facet has already said (or will say) whatever the person in front of
|
|
3865
|
+
* it needed to hear.
|
|
3866
|
+
* • The master's job is purely cognitive: create a [PLANS] block, update
|
|
3867
|
+
* goals, reflect, or decide whether it still means to make that contact.
|
|
3868
|
+
* Any follow-up communication flows through the agency competition —
|
|
3869
|
+
* NEVER via [REPLY].
|
|
3870
|
+
*
|
|
3871
|
+
* Buffered rather than written directly: state is read-only here, so
|
|
3872
|
+
* `EscalationBuffer.drainToPercepts()` emits it as a StateCommand on the next
|
|
3873
|
+
* master cycle, where Exteroception surfaces it under "## Percepts (What I Notice)".
|
|
3874
|
+
*/
|
|
3875
|
+
private _onFacetHandoff;
|
|
3876
|
+
/** Enable the deliberation cache (off by default). Call during mind assembly. */
|
|
3877
|
+
enableCache(config?: DeliberationCacheConfig): void;
|
|
3878
|
+
/** True when the cache is active. */
|
|
3879
|
+
get cacheEnabled(): boolean;
|
|
3880
|
+
/** Telemetry snapshot for harnesses / eval. Null when disabled. */
|
|
3881
|
+
cacheStats(): {
|
|
3882
|
+
size: number;
|
|
3883
|
+
hits: number;
|
|
3884
|
+
misses: number;
|
|
3885
|
+
} | null;
|
|
3886
|
+
/**
|
|
3887
|
+
* Reafference hook — update cache competence from a confirmed action outcome.
|
|
3888
|
+
* Optional, layered on top of the inline verify loop. Reward follows the
|
|
3889
|
+
* research sketch: mean of (action succeeded, stress relief, goal progress).
|
|
3890
|
+
*/
|
|
3891
|
+
onActionOutcome(state: ReadonlySimulationState, tick: Tick, success: boolean, stressDelta: number, goalProgressDelta: number): void;
|
|
3892
|
+
private _actionTypesMatch;
|
|
3893
|
+
private _restoreDeliberationCache;
|
|
3529
3894
|
private _restoreSummarizer;
|
|
3530
3895
|
}
|
|
3531
3896
|
|
|
@@ -4139,6 +4504,13 @@ declare class ThreatEvaluator implements SimulationEngine, CognitiveEngine {
|
|
|
4139
4504
|
* metadata.hostile === true). Updates _threatFromHostile and re-emits
|
|
4140
4505
|
* the full threat/emotion metrics so that downstream engines always see
|
|
4141
4506
|
* a current picture even when no bus event arrives.
|
|
4507
|
+
*
|
|
4508
|
+
* `threat` is a HOST SEAM, not a starved input (#114). No core engine writes
|
|
4509
|
+
* one — appraisal runs entirely off this engine's six bus inputs (energy,
|
|
4510
|
+
* sleep, stress, novelty, metacognition, prediction), all of which are live.
|
|
4511
|
+
* A host embedding a Will in a world with actual hostile agents writes `threat`
|
|
4512
|
+
* entities to make them felt. Empty here means nothing is hostile, not that
|
|
4513
|
+
* nothing is wired.
|
|
4142
4514
|
*/
|
|
4143
4515
|
react(_delta: Duration, _tick: Tick, state: ReadonlySimulationState, _context: SimulationContext): Promise<EngineResult>;
|
|
4144
4516
|
private _computeScarcityThreat;
|
|
@@ -4998,6 +5370,8 @@ declare class SelfModelUpdater extends AsyncEngine implements CognitiveEngine {
|
|
|
4998
5370
|
private _affectObservations;
|
|
4999
5371
|
private _bus;
|
|
5000
5372
|
private _semanticIntegrator;
|
|
5373
|
+
/** The reasoning tick's state — onReasoningComplete needs it to merge identity. */
|
|
5374
|
+
private _lastStateRef;
|
|
5001
5375
|
private readonly _model;
|
|
5002
5376
|
constructor(config?: SelfModelUpdaterConfig);
|
|
5003
5377
|
attachBus(bus: CognitiveBus): void;
|
|
@@ -5577,6 +5951,19 @@ interface Reputation {
|
|
|
5577
5951
|
negativeInteractions: number;
|
|
5578
5952
|
lastInteractionTick: Tick;
|
|
5579
5953
|
confidence: number;
|
|
5954
|
+
/**
|
|
5955
|
+
* Everything the mind has OBSERVED about this person, acts and silences alike.
|
|
5956
|
+
*
|
|
5957
|
+
* `interactionCount` counts acts, and only acts — a silence must never inflate
|
|
5958
|
+
* it or the mind remembers conversations that never happened. But confidence is
|
|
5959
|
+
* about how much evidence a read rests on, and a silence is evidence. Counting
|
|
5960
|
+
* only acts meant someone who never answers could never be confidently known as
|
|
5961
|
+
* someone who never answers, which is precisely the read worth holding.
|
|
5962
|
+
*
|
|
5963
|
+
* Rises in lockstep with `interactionCount` on the interaction path, so a mind
|
|
5964
|
+
* that has only ever been spoken to behaves exactly as it did before.
|
|
5965
|
+
*/
|
|
5966
|
+
observations: number;
|
|
5580
5967
|
}
|
|
5581
5968
|
declare class ReputationTracker implements SimulationEngine, CognitiveEngine {
|
|
5582
5969
|
readonly name = "reputation-tracker";
|
|
@@ -5588,6 +5975,8 @@ declare class ReputationTracker implements SimulationEngine, CognitiveEngine {
|
|
|
5588
5975
|
/** True after reputations have been rehydrated from persisted state on first tick. */
|
|
5589
5976
|
private _restored;
|
|
5590
5977
|
private _pendingInteractions;
|
|
5978
|
+
/** Whether someone answered when the mind spoke to them (ReafferenceEngine). */
|
|
5979
|
+
private _pendingResponsiveness;
|
|
5591
5980
|
private _bus;
|
|
5592
5981
|
private readonly _model;
|
|
5593
5982
|
constructor(config?: ReputationTrackerConfig);
|
|
@@ -5609,6 +5998,36 @@ declare class ReputationTracker implements SimulationEngine, CognitiveEngine {
|
|
|
5609
5998
|
private _prune;
|
|
5610
5999
|
}
|
|
5611
6000
|
|
|
6001
|
+
/**
|
|
6002
|
+
* A way this referent has been reachable, and what happened there.
|
|
6003
|
+
*
|
|
6004
|
+
* `kind` is the one fact that decides whether a room is the right place for a
|
|
6005
|
+
* given utterance, and it was being computed at the Discord edge (`isDM`) and
|
|
6006
|
+
* discarded before the mind could see it.
|
|
6007
|
+
*
|
|
6008
|
+
* `lastAnsweredTick` is evidence, not configuration — it arrives free from the
|
|
6009
|
+
* `social.responsiveness` signal. It is what lets the mind prefer the DM because
|
|
6010
|
+
* that is where this person actually answers, rather than because a constant in
|
|
6011
|
+
* the code says DMs rank higher.
|
|
6012
|
+
*/
|
|
6013
|
+
interface Handle {
|
|
6014
|
+
/** The transport address — what a channel bridge can actually deliver to. */
|
|
6015
|
+
keid: string;
|
|
6016
|
+
/**
|
|
6017
|
+
* 'dm' — a private thread. 'room' — somewhere others are listening. Left open
|
|
6018
|
+
* for a non-social referent, where the meaningful distinction is a different one.
|
|
6019
|
+
*/
|
|
6020
|
+
kind: 'dm' | 'room' | 'unknown';
|
|
6021
|
+
/** The place this handle lives in, once places are dossiers of their own. */
|
|
6022
|
+
place?: string;
|
|
6023
|
+
/** When the mind last SAID something here. */
|
|
6024
|
+
lastUsedTick?: Tick;
|
|
6025
|
+
/** When someone last answered it here — the only evidence that this route works. */
|
|
6026
|
+
lastAnsweredTick?: Tick;
|
|
6027
|
+
/** Free-form, so a host can mark what its own vocabulary cares about. */
|
|
6028
|
+
tags?: string[];
|
|
6029
|
+
}
|
|
6030
|
+
|
|
5612
6031
|
/**
|
|
5613
6032
|
* KnownEntityTracker — the cross-modal binder, and owner of the known-entity dossier.
|
|
5614
6033
|
*
|
|
@@ -5663,6 +6082,31 @@ interface KnownEntity {
|
|
|
5663
6082
|
lastSeenTick: Tick;
|
|
5664
6083
|
/** 0–1: how identified/coherent this referent is (a name + repeated encounters raise it). */
|
|
5665
6084
|
resolutionConfidence: number;
|
|
6085
|
+
/**
|
|
6086
|
+
* The ways this referent has been reachable, with the circumstances.
|
|
6087
|
+
*
|
|
6088
|
+
* Distinct from an ALIAS, and the distinction is load-bearing: an alias is
|
|
6089
|
+
* another NAME for the same referent (a transport user id), a handle is a
|
|
6090
|
+
* PLACE it can be reached (a thread, a room). One person has one identity and
|
|
6091
|
+
* several rooms, and conflating them is what made "which room should I say
|
|
6092
|
+
* this in?" unaskable.
|
|
6093
|
+
*/
|
|
6094
|
+
handles: Handle[];
|
|
6095
|
+
/**
|
|
6096
|
+
* Referents this one MIGHT be the same someone as, unresolved.
|
|
6097
|
+
*
|
|
6098
|
+
* A blocked merge used to vanish. `_recognise` will only absorb a THIN handle
|
|
6099
|
+
* into an established relationship — rightly, because fusing two real people
|
|
6100
|
+
* who share a name is the dangerous direction — so once the same human was
|
|
6101
|
+
* well-established on two channels they stayed two people permanently, and
|
|
6102
|
+
* nothing anywhere recorded the near-miss.
|
|
6103
|
+
*
|
|
6104
|
+
* A person does not silently fail here. They NOTICE — "hang on, is this the
|
|
6105
|
+
* same Mara?" — and then resolve it by asking. So the doubt is kept, shown, and
|
|
6106
|
+
* left for the mind to settle. Deliberately not a merge: this is a question,
|
|
6107
|
+
* and the answer is the mind's to give.
|
|
6108
|
+
*/
|
|
6109
|
+
suspectedSameAs?: string[];
|
|
5666
6110
|
}
|
|
5667
6111
|
declare class KnownEntityTracker implements SimulationEngine, CognitiveEngine {
|
|
5668
6112
|
readonly name = "known-entity-tracker";
|
|
@@ -5678,6 +6122,13 @@ declare class KnownEntityTracker implements SimulationEngine, CognitiveEngine {
|
|
|
5678
6122
|
private _pendingEncounters;
|
|
5679
6123
|
private _pendingConscious;
|
|
5680
6124
|
private _pendingOutcomes;
|
|
6125
|
+
/**
|
|
6126
|
+
* Aliases minted this tick, awaiting persistence. `_getOrCreate` runs deep inside
|
|
6127
|
+
* the drain loops with no access to the command list, and an alias that lives
|
|
6128
|
+
* only in memory is one the mind forgets on restart — every transport address
|
|
6129
|
+
* would mint a SECOND anchor next boot and the person would fork in two.
|
|
6130
|
+
*/
|
|
6131
|
+
private _mintedAliases;
|
|
5681
6132
|
private _bus;
|
|
5682
6133
|
private readonly _model;
|
|
5683
6134
|
constructor(config?: KnownEntityTrackerConfig);
|
|
@@ -5694,7 +6145,31 @@ declare class KnownEntityTracker implements SimulationEngine, CognitiveEngine {
|
|
|
5694
6145
|
snapshot(): Record<string, unknown>;
|
|
5695
6146
|
react(_delta: Duration, tick: Tick, state: ReadonlySimulationState, _ctx: SimulationContext): Promise<EngineResult>;
|
|
5696
6147
|
/** The dossier for a referent, if the Will has one. */
|
|
6148
|
+
/**
|
|
6149
|
+
* The dossier for anything that names this referent — its anchor, or any address
|
|
6150
|
+
* it has been met at.
|
|
6151
|
+
*
|
|
6152
|
+
* Alias-aware because a caller has no business knowing the anchor. This read
|
|
6153
|
+
* `_dossiers.get(keid)` raw, so the moment addresses became aliases of a minted
|
|
6154
|
+
* anchor, every caller holding a transport id got `undefined` — the mind would
|
|
6155
|
+
* have looked up someone it knows perfectly well and found a stranger. The
|
|
6156
|
+
* existing Phase-4 tests caught it, which is exactly what they are for.
|
|
6157
|
+
*/
|
|
5697
6158
|
getDossier(keid: string): KnownEntity | undefined;
|
|
6159
|
+
/**
|
|
6160
|
+
* Absorb `alias` into `canon` — one someone where there were two.
|
|
6161
|
+
*
|
|
6162
|
+
* Shared by the recognition heuristic and by the mind's own `sameAs` verdict,
|
|
6163
|
+
* because "these are the same person" must mean the same thing whichever
|
|
6164
|
+
* concluded it. The only difference is who is ENTITLED to conclude it: the
|
|
6165
|
+
* heuristic will not absorb an established relationship, the mind may, because
|
|
6166
|
+
* it has reasons a name-match does not — usually that somebody just told it.
|
|
6167
|
+
*
|
|
6168
|
+
* Routes MOVE. This used to delete the absorbed dossier and keep only a
|
|
6169
|
+
* redirect, so the mind concluded "same person" and in the same breath threw
|
|
6170
|
+
* away the second way to reach them.
|
|
6171
|
+
*/
|
|
6172
|
+
private _fuse;
|
|
5698
6173
|
/** Resolution confidence: a learned name plus repeated encounters identify a referent. */
|
|
5699
6174
|
private _resolution;
|
|
5700
6175
|
/**
|
|
@@ -5702,12 +6177,51 @@ declare class KnownEntityTracker implements SimulationEngine, CognitiveEngine {
|
|
|
5702
6177
|
* true if any merge happened. Pure + deterministic.
|
|
5703
6178
|
*/
|
|
5704
6179
|
private _recognise;
|
|
6180
|
+
/**
|
|
6181
|
+
* The dossier for a referent, minting its anchor the first time it is met.
|
|
6182
|
+
*
|
|
6183
|
+
* A transport address arriving here (`discord:1019…`) is not an identity, it is
|
|
6184
|
+
* a way the world happened to name someone. So it becomes an ALIAS of a fresh
|
|
6185
|
+
* `ke:` anchor, and the dossier lives under the anchor. Everything downstream —
|
|
6186
|
+
* reputation, theory-of-mind, attachment, goals, the PMA — keeps working
|
|
6187
|
+
* untouched: it still sees one opaque string per referent, which is simply no
|
|
6188
|
+
* longer a route. The same human met later on another channel resolves to this
|
|
6189
|
+
* same anchor instead of becoming a second person nobody could connect.
|
|
6190
|
+
*/
|
|
5705
6191
|
private _getOrCreate;
|
|
5706
6192
|
/** Keep the most-familiar dossiers; absence-faded acquaintances fall away (forgetting). */
|
|
6193
|
+
/**
|
|
6194
|
+
* Forget the least-held referents when over capacity.
|
|
6195
|
+
*
|
|
6196
|
+
* Ranked by more than exposure, deliberately. This sorted on `familiarity`
|
|
6197
|
+
* alone, which is MERE EXPOSURE — and now that a referent need not be a person
|
|
6198
|
+
* (a document, a repo, a room), things get far more exposure than people do. A
|
|
6199
|
+
* mind that touched sixty files would have evicted a colleague it speaks to
|
|
6200
|
+
* weekly in favour of a config file it opened a lot, silently, taking that
|
|
6201
|
+
* person's reputation, theory-of-mind model and attachment bond with it.
|
|
6202
|
+
*
|
|
6203
|
+
* So a referent the mind has actually got to know is stickier than one it has
|
|
6204
|
+
* merely seen often: knowing their NAME is the single strongest signal (it is
|
|
6205
|
+
* what distinguishes a someone from a blip), then how resolved the referent is,
|
|
6206
|
+
* then exposure. Nothing here is about being a person — a named, well-resolved
|
|
6207
|
+
* document outranks a glimpsed stranger, which is correct.
|
|
6208
|
+
*/
|
|
5707
6209
|
private _prune;
|
|
5708
6210
|
private _restoreFromState;
|
|
5709
6211
|
}
|
|
5710
6212
|
|
|
6213
|
+
/**
|
|
6214
|
+
* Referent → a deliverable address, and the room to use when none was chosen.
|
|
6215
|
+
*
|
|
6216
|
+
* Returns null when the referent is already an address (nothing to translate) or
|
|
6217
|
+
* when the mind holds no route at all — in which case the row goes out as-is and
|
|
6218
|
+
* the bridge's own roster fallback still applies, so a message is never silently
|
|
6219
|
+
* dropped for want of a handle.
|
|
6220
|
+
*/
|
|
6221
|
+
type OutboxRouting = (targetEntityId: string, chosenThread: string | undefined) => {
|
|
6222
|
+
targetEntityId: string;
|
|
6223
|
+
threadId?: string;
|
|
6224
|
+
} | null;
|
|
5711
6225
|
/** The caller-supplied fields of an outbox row; the writer stamps id + defaults. */
|
|
5712
6226
|
interface OutboxRow {
|
|
5713
6227
|
targetEntityId: string;
|
|
@@ -5729,11 +6243,24 @@ declare class OutboxWriter {
|
|
|
5729
6243
|
* which made the embedded ids in `conversation.sent` diverge every run).
|
|
5730
6244
|
*/
|
|
5731
6245
|
private _seq;
|
|
6246
|
+
private _routing;
|
|
5732
6247
|
constructor(opts?: {
|
|
5733
6248
|
outbox?: OutboxMessage[];
|
|
5734
6249
|
willId?: string;
|
|
5735
6250
|
});
|
|
5736
6251
|
attachSessionLogger(logger: SessionLogger | null): void;
|
|
6252
|
+
/**
|
|
6253
|
+
* Turn a referent into somewhere the world can actually be spoken to.
|
|
6254
|
+
*
|
|
6255
|
+
* Injected rather than read here, because this writer is deliberately dumb —
|
|
6256
|
+
* it holds no state and must stay replay-safe. Assembly closes over the state
|
|
6257
|
+
* manager (the same shape as `attachMemorySink`).
|
|
6258
|
+
*
|
|
6259
|
+
* This is the ONE seam both send paths cross: ProactiveCommunicator's
|
|
6260
|
+
* `enqueue()` and AuditionEngine's `enqueueReply()`. Translating anywhere else
|
|
6261
|
+
* would mean doing it twice and getting it wrong once.
|
|
6262
|
+
*/
|
|
6263
|
+
attachRouting(resolve: OutboxRouting | null): void;
|
|
5737
6264
|
private _genId;
|
|
5738
6265
|
/**
|
|
5739
6266
|
* Push one canonical outbox row and return its generated id. The single point
|
|
@@ -5835,6 +6362,18 @@ interface TextMessage {
|
|
|
5835
6362
|
content: string;
|
|
5836
6363
|
/** Display name — used in the facet focus content. */
|
|
5837
6364
|
speakerName?: string;
|
|
6365
|
+
/**
|
|
6366
|
+
* True when `threadId` is a PRIVATE thread — this someone and the mind, nobody
|
|
6367
|
+
* else listening. The single fact that decides whether a room is the right
|
|
6368
|
+
* place for a given utterance, and the Discord edge has always computed it
|
|
6369
|
+
* (`isDM`) and discarded it before the mind could see it: a follow-up promised
|
|
6370
|
+
* in a DM went out to a public channel, because the roster's "where did I last
|
|
6371
|
+
* see them" is a different question from "where did I promise this".
|
|
6372
|
+
*
|
|
6373
|
+
* Undefined means the channel did not say, which is honestly different from
|
|
6374
|
+
* false — an unknown room is not known to be public.
|
|
6375
|
+
*/
|
|
6376
|
+
direct?: boolean;
|
|
5838
6377
|
}
|
|
5839
6378
|
interface VoiceChunk {
|
|
5840
6379
|
kind: 'voice';
|
|
@@ -6018,6 +6557,12 @@ declare class AuditionEngine extends BaseSenseEngine {
|
|
|
6018
6557
|
* other percept uses. Wired to `stateManager.setEntity` in assembleMind().
|
|
6019
6558
|
*/
|
|
6020
6559
|
private _memorySink;
|
|
6560
|
+
/**
|
|
6561
|
+
* Sim tick of the most recent facet decision — the only deterministic clock this
|
|
6562
|
+
* off-tick engine has. Stamped from `FacetDecision.tick`, and used to key the
|
|
6563
|
+
* conversation records it writes into state.
|
|
6564
|
+
*/
|
|
6565
|
+
private _lastDecisionTick;
|
|
6021
6566
|
/** Speaker attachment strength accessor (0–1) — weights salience by relationship. */
|
|
6022
6567
|
private _getAttachmentScore;
|
|
6023
6568
|
/** Active-goal topic text accessor — for salience topic-overlap. */
|
|
@@ -6026,6 +6571,8 @@ declare class AuditionEngine extends BaseSenseEngine {
|
|
|
6026
6571
|
private _inflightInbound;
|
|
6027
6572
|
/** In-flight thread per entity — stamps chunk envelopes with the current threadId. */
|
|
6028
6573
|
private _inflightThread;
|
|
6574
|
+
/** Targets with an outreach being composed right now — see authorOutreach. */
|
|
6575
|
+
private _outreachInFlight;
|
|
6029
6576
|
attachExecutiveEngine(exec: ExecutiveEngine): void;
|
|
6030
6577
|
/**
|
|
6031
6578
|
* Inject the OutboxWriter so reply bubbles are delivered through the canonical
|
|
@@ -6069,7 +6616,7 @@ declare class AuditionEngine extends BaseSenseEngine {
|
|
|
6069
6616
|
attachAttachmentScore(fn: (entityId: string) => number): void;
|
|
6070
6617
|
/** Inject an active-goal topic-text accessor (reads GoalManager) for salience overlap. */
|
|
6071
6618
|
attachActiveGoalText(fn: () => string[]): void;
|
|
6072
|
-
/** Override: audition adds the master
|
|
6619
|
+
/** Override: audition adds the facet→master handoff to the base percept schema. */
|
|
6073
6620
|
publishes(): CognitiveEventSchema[];
|
|
6074
6621
|
snapshot(): Record<string, unknown>;
|
|
6075
6622
|
/**
|
|
@@ -6138,6 +6685,52 @@ declare class AuditionEngine extends BaseSenseEngine {
|
|
|
6138
6685
|
* (Section 1.2) routes ingest through the tick loop. The entity carries no
|
|
6139
6686
|
* wall-clock timestamp — `setEntity` stamps createdAt/tick from the sim clock.
|
|
6140
6687
|
*/
|
|
6688
|
+
/**
|
|
6689
|
+
* The inbound as a social signal in state — mirror of `conversation.sent`.
|
|
6690
|
+
*
|
|
6691
|
+
* Shaped for `SocialPerception._scanSocialSignals`, which reads `sourceKeid` for
|
|
6692
|
+
* who acted and `directedAtSelf` for whether it was aimed at us. Valence is left
|
|
6693
|
+
* UNSET on purpose: the words have not been appraised yet, and guessing a number
|
|
6694
|
+
* here would feed reputation and affect a sentiment nobody measured. Absent, the
|
|
6695
|
+
* scanner falls back to its neutral default, so the Will learns *that* someone
|
|
6696
|
+
* engaged (familiarity, recency, reliability) without inventing how it felt.
|
|
6697
|
+
*/
|
|
6698
|
+
/**
|
|
6699
|
+
* A durable, deterministic id for a conversation record.
|
|
6700
|
+
*
|
|
6701
|
+
* `<prefix>-<entity>-<tick>-<hash of the words>`. Every part earns its place:
|
|
6702
|
+
* • entity — whose conversation this is;
|
|
6703
|
+
* • tick — WHEN, from the sim clock, which resumes from the snapshot and so
|
|
6704
|
+
* keeps rising across restarts;
|
|
6705
|
+
* • hash — which utterance, so two things said to one person on one tick stay
|
|
6706
|
+
* two records.
|
|
6707
|
+
*
|
|
6708
|
+
* What it replaces was `<prefix>-<entity>-<N>` with N a process-local counter.
|
|
6709
|
+
* It restarted at 1 on every boot, so each session OVERWROTE the previous
|
|
6710
|
+
* session's records of the same person — a mind that had spoken with someone
|
|
6711
|
+
* across four restarts held one session's worth of evidence that it ever had.
|
|
6712
|
+
* Found by diffing a live snapshot against the Discord transcript it came from:
|
|
6713
|
+
* `conv-sent-reply-discord:1019…-1` held that morning's greeting, and every
|
|
6714
|
+
* earlier conversation keyed to the same id was simply gone.
|
|
6715
|
+
*
|
|
6716
|
+
* No wallClock: these ids live in state, and a wall-clock id makes the recorded
|
|
6717
|
+
* and replayed runs diverge (R2).
|
|
6718
|
+
*/
|
|
6719
|
+
private _sentKey;
|
|
6720
|
+
private _writeReceived;
|
|
6721
|
+
/**
|
|
6722
|
+
* Record that the mind SPOKE to someone, mirroring `_writeReceived`.
|
|
6723
|
+
*
|
|
6724
|
+
* Only ProactiveCommunicator wrote `conversation.sent`, so a reply — which is
|
|
6725
|
+
* most of what a Will says — left no durable trace of having spoken. Everything
|
|
6726
|
+
* that asks "have I already said something to them?" was therefore blind to
|
|
6727
|
+
* conversation: satiation could not damp repeating a relay delivered as a reply,
|
|
6728
|
+
* and an undertaking discharged inside a conversation stayed forever unkept,
|
|
6729
|
+
* which is exactly how the same message went out again and again.
|
|
6730
|
+
*
|
|
6731
|
+
* Speaking is speaking, whichever path carried it.
|
|
6732
|
+
*/
|
|
6733
|
+
private _writeSent;
|
|
6141
6734
|
private _persistExchangeMemory;
|
|
6142
6735
|
private _onFacetDecision;
|
|
6143
6736
|
/**
|
|
@@ -6444,6 +7037,16 @@ declare class AffordanceSynthesizer implements CognitiveEngine {
|
|
|
6444
7037
|
private _schemas;
|
|
6445
7038
|
private _skills;
|
|
6446
7039
|
private _repertoire;
|
|
7040
|
+
/**
|
|
7041
|
+
* This tick's live consequence descriptors — the acts the mind has performed
|
|
7042
|
+
* whose outcome has not yet come back. Refreshed once at the top of react()
|
|
7043
|
+
* because `_build` runs per candidate and reading them is a full-entity scan.
|
|
7044
|
+
*/
|
|
7045
|
+
private _inFlight;
|
|
7046
|
+
/** Ticks an act stays satiating (engine-config-action-selector.repeatWindowTicks). */
|
|
7047
|
+
private _satiationWindow;
|
|
7048
|
+
/** Tick of the last thing said to each entity — outlives the descriptor sweep. */
|
|
7049
|
+
private _spokenAt;
|
|
6447
7050
|
private _bus;
|
|
6448
7051
|
private _defaultCap;
|
|
6449
7052
|
private _lastFieldSize;
|
|
@@ -6577,6 +7180,21 @@ declare class MotorSchemaExecutor implements CognitiveEngine {
|
|
|
6577
7180
|
private _author;
|
|
6578
7181
|
private _grants;
|
|
6579
7182
|
private _bus;
|
|
7183
|
+
/**
|
|
7184
|
+
* Two-phase outreach authoring. A facet cannot be awaited from inside a tick:
|
|
7185
|
+
* `ExecutiveFacet.report()` only QUEUES in tick-discipline mode and the reasoning
|
|
7186
|
+
* launches from `pump()`, which the ExecutiveEngine calls once per tick — so an
|
|
7187
|
+
* in-tick `await` blocks the very loop that would produce the answer. Observed
|
|
7188
|
+
* live: a 61s freeze of the whole mind inside one tick, then an empty result.
|
|
7189
|
+
* (It passes unit tests because bare facets have no inbox and author inline.)
|
|
7190
|
+
*
|
|
7191
|
+
* So `_deliver` REQUESTS words and returns false (the intent holds 'awaiting'),
|
|
7192
|
+
* the facet answers off-tick, and a later tick delivers. Process-local by design:
|
|
7193
|
+
* an authoring call in flight cannot survive a restart, and the intent would
|
|
7194
|
+
* simply re-request.
|
|
7195
|
+
*/
|
|
7196
|
+
private _authoring;
|
|
7197
|
+
private _authored;
|
|
6580
7198
|
constructor(schemas?: MotorSchema[]);
|
|
6581
7199
|
attachBus(bus: CognitiveBus): void;
|
|
6582
7200
|
/** Resolve schemas (incl. learned composites) from the live repertoire first. */
|
|
@@ -6616,6 +7234,13 @@ declare class MotorSchemaExecutor implements CognitiveEngine {
|
|
|
6616
7234
|
* conversation facet); this is the single enaction → delivery path.
|
|
6617
7235
|
*/
|
|
6618
7236
|
private _deliver;
|
|
7237
|
+
/**
|
|
7238
|
+
* Ask a facet for the words, off-tick. Fire-and-forget on purpose: awaiting this
|
|
7239
|
+
* from inside `react()` deadlocks the tick loop against the facet pump. Idempotent
|
|
7240
|
+
* per intent — a request already in flight is not duplicated, so the intent may sit
|
|
7241
|
+
* 'awaiting' across many ticks with exactly one LLM call behind it.
|
|
7242
|
+
*/
|
|
7243
|
+
private _requestAuthoring;
|
|
6619
7244
|
private _emitEnacted;
|
|
6620
7245
|
/**
|
|
6621
7246
|
* Publish `action.outcome` for EVERY enaction — the shared metacognitive/affective
|
|
@@ -6624,6 +7249,32 @@ declare class MotorSchemaExecutor implements CognitiveEngine {
|
|
|
6624
7249
|
* RewardEvaluator reads it as a reward signal. `confidence` carries the agency's
|
|
6625
7250
|
* own forward-model prior so calibration has a real prediction to score.
|
|
6626
7251
|
*/
|
|
7252
|
+
/**
|
|
7253
|
+
* Retire the `ideomotor.intent` that produced this act.
|
|
7254
|
+
*
|
|
7255
|
+
* Nothing deleted these. They were cleared only when the executive next ran and
|
|
7256
|
+
* declined to name the same action again — and the executive runs on an interval,
|
|
7257
|
+
* so between cycles a willed reach-out STOOD in state, was rebuilt into an
|
|
7258
|
+
* affordance every single tick, and competed every single tick. Observed as
|
|
7259
|
+
* dozens of identical lines:
|
|
7260
|
+
*
|
|
7261
|
+
* [selector] willed reach-out → … NOT selected: 0.297 < inspect… 0.340
|
|
7262
|
+
*
|
|
7263
|
+
* losing by four thousandths, over and over, until it won — twice. Fabrice got
|
|
7264
|
+
* the same message byte-for-byte 25 ticks apart, two outbox ids.
|
|
7265
|
+
*
|
|
7266
|
+
* `justEnacted` was built to hold this line and cannot: it is a DECAYING
|
|
7267
|
+
* quantity, capped at `repeatDamping` (0.30), and a standing intent outlasts it
|
|
7268
|
+
* by construction. Damping a permanent pull only ever delays it. So the intention
|
|
7269
|
+
* is discharged by being acted on, which is what an intention is — you meant to
|
|
7270
|
+
* tell someone something, you told them, and it is finished. If the mind still
|
|
7271
|
+
* wants to say more, the next executive cycle forms a new one, now seeing "I said
|
|
7272
|
+
* this 25 ticks ago and have had no answer" in front of it.
|
|
7273
|
+
*
|
|
7274
|
+
* Satiation stays exactly as it was, and still earns its keep: it damps saying
|
|
7275
|
+
* the same thing again for reasons that did NOT come from a standing will.
|
|
7276
|
+
*/
|
|
7277
|
+
private _dischargeWill;
|
|
6627
7278
|
private _emitActionOutcome;
|
|
6628
7279
|
private _emitDispatch;
|
|
6629
7280
|
}
|
|
@@ -6640,6 +7291,35 @@ declare class ReafferenceEngine implements CognitiveEngine {
|
|
|
6640
7291
|
onCognitiveEvent(e: CognitiveEvent): void;
|
|
6641
7292
|
snapshot(): Record<string, unknown>;
|
|
6642
7293
|
react(_delta: Duration, tick: Tick, state: ReadonlySimulationState, _context: SimulationContext): Promise<EngineResult>;
|
|
7294
|
+
/**
|
|
7295
|
+
* Latch each open turn's fate onto its own record and announce it once.
|
|
7296
|
+
*
|
|
7297
|
+
* Two rules earn their keep here:
|
|
7298
|
+
*
|
|
7299
|
+
* • MERGE, never replace. `StateManager.setEntity` overwrites the whole entity,
|
|
7300
|
+
* and a `conversation.sent` carries `outboxMessageIds` — the sole key by which
|
|
7301
|
+
* a later delivery ack can find it. Rewriting the record with only the fields
|
|
7302
|
+
* this method cares about would sever that, silently, for every turn that got
|
|
7303
|
+
* an answer.
|
|
7304
|
+
*
|
|
7305
|
+
* • Latch, don't recompute. `answeredAt`/`unansweredAt` persist, so the event
|
|
7306
|
+
* fires on the one tick the fact changed rather than every tick for the rest
|
|
7307
|
+
* of the session — which for an unanswered turn would be thousands of
|
|
7308
|
+
* identical reputation hits against one person for one silence.
|
|
7309
|
+
*/
|
|
7310
|
+
private _resolveReplies;
|
|
7311
|
+
/**
|
|
7312
|
+
* Publish how a person responded to being spoken to.
|
|
7313
|
+
*
|
|
7314
|
+
* Deliberately NOT an `interaction.occurred`: that event means "someone did
|
|
7315
|
+
* something toward us" and carries a valence for what they did. A silence is
|
|
7316
|
+
* nobody doing anything, and forcing it through that channel would have the
|
|
7317
|
+
* ReputationTracker book a hostile *act* where there was only an absence — the
|
|
7318
|
+
* mind would come to think it was being rebuffed rather than simply not
|
|
7319
|
+
* answered yet. Separate signal, separate meaning, one consumer decides what
|
|
7320
|
+
* either is worth.
|
|
7321
|
+
*/
|
|
7322
|
+
private _emitResponsiveness;
|
|
6643
7323
|
private _emitProceduralized;
|
|
6644
7324
|
/**
|
|
6645
7325
|
* Emit the `action.outcome{planId,stepId}` for an async (host-acked) plan-step
|
|
@@ -6671,6 +7351,12 @@ type EngineRegistry = {
|
|
|
6671
7351
|
affectiveBlender: AffectiveBlender;
|
|
6672
7352
|
workingMemory: WorkingMemory;
|
|
6673
7353
|
episodicConsolidator: EpisodicConsolidator;
|
|
7354
|
+
/**
|
|
7355
|
+
* The vector index, when semantic recall is configured. Exposed so shutdown can
|
|
7356
|
+
* FLUSH it: it lives outside the state snapshot and previously persisted only from
|
|
7357
|
+
* a debounce timer no shutdown path awaited, so it died with the process.
|
|
7358
|
+
*/
|
|
7359
|
+
vectorMemory: VectorMemoryAdapter | null;
|
|
6674
7360
|
semanticIntegrator: SemanticIntegrator;
|
|
6675
7361
|
spacedRepetition: SpacedRepetition;
|
|
6676
7362
|
forgettingCurve: ForgettingCurve;
|
|
@@ -7064,6 +7750,24 @@ interface WillConfig {
|
|
|
7064
7750
|
profile?: string | null;
|
|
7065
7751
|
/** Persona definition seeded into the will.identity entity. */
|
|
7066
7752
|
identity: WillIdentity;
|
|
7753
|
+
/**
|
|
7754
|
+
* This config's `identity` is a PLACEHOLDER — the real one arrives from a PMA
|
|
7755
|
+
* artifact moments later, on the same boot.
|
|
7756
|
+
*
|
|
7757
|
+
* Set by `Will.wake`, which passes `{ prompt: '' }` because a woken mind's
|
|
7758
|
+
* persona belongs to its artifact, not to the caller. Without this flag the
|
|
7759
|
+
* creation-time identity guard inspected that placeholder and warned, on every
|
|
7760
|
+
* single wake, that "identity.values is empty", "identity.style is generic" and
|
|
7761
|
+
* "identity is shallow (strength 0)" — three alarms about a config nobody
|
|
7762
|
+
* intended to use, fired before the real identity had loaded.
|
|
7763
|
+
*
|
|
7764
|
+
* It suppresses only the WARNINGS. Errors still throw (an over-long or
|
|
7765
|
+
* malformed prompt is a hard failure whenever it appears), and the artifact's
|
|
7766
|
+
* OWN identity is fully guarded at the load boundary by PMAController.load,
|
|
7767
|
+
* which is the honest place to ask whether this mind's persona is thin — it is
|
|
7768
|
+
* the only point where the answer is knowable.
|
|
7769
|
+
*/
|
|
7770
|
+
identityFromArtifact?: boolean;
|
|
7067
7771
|
/** Anatomy — 'mind' (default) or the no-LLM 'reflex' shell. */
|
|
7068
7772
|
anatomy?: Anatomy;
|
|
7069
7773
|
/**
|
|
@@ -7099,6 +7803,21 @@ interface WillConfig {
|
|
|
7099
7803
|
* Plan-enforced floor for executiveInterval — the customer cannot go faster.
|
|
7100
7804
|
*/
|
|
7101
7805
|
minExecutiveInterval?: number;
|
|
7806
|
+
/**
|
|
7807
|
+
* Enable the DeliberationCache — a learned fast path that composes an executive
|
|
7808
|
+
* output from highly-similar, highly-competent precedent instead of calling the
|
|
7809
|
+
* LLM. Off unless asked for.
|
|
7810
|
+
*
|
|
7811
|
+
* OFF BY DEFAULT ON PURPOSE, and the default is the interesting part: this
|
|
7812
|
+
* changes how a mind THINKS, not how fast it runs. A cache hit means the mind
|
|
7813
|
+
* acted from precedent without deliberating, which is a real thing minds do and
|
|
7814
|
+
* a real thing an operator must opt into for a specific Will — not something a
|
|
7815
|
+
* dependency bump should switch on underneath one that is already living.
|
|
7816
|
+
*
|
|
7817
|
+
* Pass `true` for the built-in conservative settings, or a config object to tune
|
|
7818
|
+
* the retrieval/competence parameters (see cognition/cache/types).
|
|
7819
|
+
*/
|
|
7820
|
+
deliberationCache?: boolean | DeliberationCacheConfig;
|
|
7102
7821
|
/**
|
|
7103
7822
|
* Goals seeded before the first tick. If omitted or empty, the Will starts
|
|
7104
7823
|
* goalless — the executive engine will generate context-appropriate goals on its
|
|
@@ -8192,6 +8911,8 @@ interface Stimulus {
|
|
|
8192
8911
|
speaker?: string;
|
|
8193
8912
|
/** Conversation/thread id (default = `from`). */
|
|
8194
8913
|
thread?: string;
|
|
8914
|
+
/** True when `thread` is private — just this someone and the Will. See TextMessage.direct. */
|
|
8915
|
+
direct?: boolean;
|
|
8195
8916
|
}
|
|
8196
8917
|
/** A message the Will emitted to someone. */
|
|
8197
8918
|
interface WillMessage {
|
|
@@ -8201,6 +8922,20 @@ interface WillMessage {
|
|
|
8201
8922
|
content: string;
|
|
8202
8923
|
/** Entity id the Will addressed (the speaker you used in say()/tell(), or a bond). */
|
|
8203
8924
|
to: string;
|
|
8925
|
+
/**
|
|
8926
|
+
* The conversation this belongs to — the `thread` from the `perceive()` that
|
|
8927
|
+
* prompted it. Absent when the Will spoke unprompted, which genuinely has no
|
|
8928
|
+
* thread.
|
|
8929
|
+
*
|
|
8930
|
+
* WHERE, not just to whom. The engine knew this the whole way down —
|
|
8931
|
+
* `OutboxMessage.threadId` carries it — and the projection dropped it here, so
|
|
8932
|
+
* a channel adapter had nothing to answer INTO and had to guess from a roster.
|
|
8933
|
+
* Observed live: a DM arrived on `discord:1532693…`, she answered it correctly
|
|
8934
|
+
* and in seconds, and the reply went to the shared server channel because that
|
|
8935
|
+
* was the last room the roster had seen this person in. From the operator's
|
|
8936
|
+
* side she had simply ignored him.
|
|
8937
|
+
*/
|
|
8938
|
+
thread?: string;
|
|
8204
8939
|
}
|
|
8205
8940
|
/**
|
|
8206
8941
|
* A motor act the Will *chose* to enact — a projection of its agency, surfaced
|