@mindot/will 0.7.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.
Files changed (88) hide show
  1. package/README.md +87 -22
  2. package/dist/channels/discord.d.ts +67 -6
  3. package/dist/channels/discord.js +112 -6
  4. package/dist/channels/discord.js.map +1 -1
  5. package/dist/channels/whatsapp.d.ts +1 -1
  6. package/dist/channels/whatsapp.js +4 -1
  7. package/dist/channels/whatsapp.js.map +1 -1
  8. package/dist/cli.js +13733 -11057
  9. package/dist/cli.js.map +1 -1
  10. package/dist/index.d.ts +2 -2
  11. package/dist/index.js +3729 -1199
  12. package/dist/index.js.map +1 -1
  13. package/dist/mcp/effectors.d.ts +1 -1
  14. package/dist/{will-DAW0l-lY.d.ts → will-DbDj_TEH.d.ts} +1214 -93
  15. package/package.json +1 -1
  16. package/src/channels/discord.ts +189 -11
  17. package/src/channels/types.ts +90 -0
  18. package/src/channels/whatsapp.ts +13 -4
  19. package/src/cli.ts +9 -4
  20. package/src/cognition/agency/consequence.ts +122 -1
  21. package/src/cognition/agency/conversation.aim.ts +260 -0
  22. package/src/cognition/agency/engines/action.selector.ts +85 -3
  23. package/src/cognition/agency/engines/affordance.synthesizer.ts +90 -1
  24. package/src/cognition/agency/engines/motor.schema.executor.ts +152 -10
  25. package/src/cognition/agency/engines/reafference.engine.ts +129 -2
  26. package/src/cognition/agency/proactive.communicator.ts +19 -3
  27. package/src/cognition/agency/reconcile.learning.ts +16 -2
  28. package/src/cognition/agency/restart.ts +66 -0
  29. package/src/cognition/agency/schemas/repertoire.ts +12 -5
  30. package/src/cognition/agency/selection.scoring.ts +33 -0
  31. package/src/cognition/agency/types.ts +35 -0
  32. package/src/cognition/cache/composition.ts +232 -0
  33. package/src/cognition/cache/deliberation.cache.ts +219 -0
  34. package/src/cognition/cache/fingerprint.ts +120 -0
  35. package/src/cognition/cache/types.ts +105 -0
  36. package/src/cognition/config.mirror.entities.ts +109 -1
  37. package/src/cognition/event.schemas.ts +22 -0
  38. package/src/cognition/faculties/autobiographical.narrator.ts +5 -10
  39. package/src/cognition/faculties/episodic.consolidator.ts +59 -3
  40. package/src/cognition/faculties/executive.engine/commands.ts +189 -14
  41. package/src/cognition/faculties/executive.engine/context.ts +67 -13
  42. package/src/cognition/faculties/executive.engine/deliberate.reasoning.ts +1 -1
  43. package/src/cognition/faculties/executive.engine/engine.ts +686 -187
  44. package/src/cognition/faculties/executive.engine/escalation.buffer.ts +162 -44
  45. package/src/cognition/faculties/executive.engine/facet.supervisor.ts +310 -65
  46. package/src/cognition/faculties/executive.engine/facet.ts +89 -26
  47. package/src/cognition/faculties/executive.engine/gating.ts +14 -14
  48. package/src/cognition/faculties/executive.engine/parser.ts +21 -1
  49. package/src/cognition/faculties/executive.engine/prompt.factory.ts +169 -20
  50. package/src/cognition/faculties/executive.engine/types.ts +69 -0
  51. package/src/cognition/faculties/goal.manager.ts +94 -14
  52. package/src/cognition/faculties/known.entity.tracker.ts +267 -28
  53. package/src/cognition/faculties/moral.evaluator.ts +8 -3
  54. package/src/cognition/faculties/persona.consolidator.ts +141 -0
  55. package/src/cognition/faculties/reputation.tracker.ts +66 -2
  56. package/src/cognition/faculties/self.model.updater.ts +19 -12
  57. package/src/cognition/faculties/social.perception.ts +47 -3
  58. package/src/cognition/faculties/threat.evaluator.ts +7 -0
  59. package/src/cognition/faculties/working.memory.ts +10 -20
  60. package/src/cognition/identity.entity.ts +205 -0
  61. package/src/cognition/index.ts +11 -0
  62. package/src/cognition/memory/vector.adapter.ts +12 -3
  63. package/src/cognition/memory/vector.embedder.ts +54 -7
  64. package/src/cognition/persona.prior.ts +6 -0
  65. package/src/cognition/senses/audition.engine/engine.ts +404 -46
  66. package/src/cognition/senses/base.sense.engine.ts +1 -1
  67. package/src/cognition/senses/index.ts +12 -0
  68. package/src/cognition/social.identity.ts +273 -0
  69. package/src/cognition/utilities/token.tracker.ts +246 -98
  70. package/src/core/orchestrator.ts +38 -0
  71. package/src/host/boot.ts +78 -22
  72. package/src/index.ts +35 -0
  73. package/src/llm/index.ts +415 -97
  74. package/src/llm/routing.ts +204 -0
  75. package/src/llm/summarizer.ts +5 -1
  76. package/src/llm/wire.contracts.ts +19 -0
  77. package/src/pma/index.ts +67 -53
  78. package/src/runners/thin-shim.runner.ts +18 -6
  79. package/src/sdk/will.ts +121 -22
  80. package/src/stem/assembly.audit.ts +1 -0
  81. package/src/stem/guards/identity.coherence.ts +17 -6
  82. package/src/stem/index.ts +82 -5
  83. package/src/stem/mind.ts +327 -79
  84. package/src/stem/policy/arbiter.ts +49 -14
  85. package/src/stem/policy/rule.table.ts +2 -2
  86. package/src/stem/tracts/effector.controller.ts +56 -9
  87. package/src/stem/tracts/outbox.writer.ts +40 -2
  88. package/src/cognition/faculties/executive.engine/messages.ts +0 -102
@@ -2,35 +2,97 @@
2
2
  // src/cognition/faculties/executive.engine/escalation.buffer.ts
3
3
  // ─────────────────────────────────────────────────────────────
4
4
  //
5
- // EscalationBuffer — pending auditionexecutive escalations (R5-g-2).
5
+ // EscalationBuffer — facetmaster handoffs awaiting a tick boundary (R5-g-2).
6
6
  //
7
- // The AuditionEngine publishes `audition.task.signal` events when a facet
8
- // conversation surfaces work the master should own. Those events arrive
9
- // between tick boundaries, while state is read-only, so they can't be written
10
- // as percepts directly. This buffer holds them until the next
11
- // onReasoningComplete(), where they are drained into high-salience percept
12
- // entities (StateCommands.set) so Exteroception surfaces them as
13
- // "## Percepts (What I Notice)" on the following master cycle.
7
+ // A focused facet sometimes surfaces something only the singular seat can own:
8
+ // work to plan, or an intention toward someone it is not itself talking to. It
9
+ // publishes `executive.facet.handoff`; those events arrive between tick
10
+ // boundaries, while state is read-only, so they can't be written as percepts
11
+ // directly. This buffer holds them until the next onReasoningComplete(), where
12
+ // they are drained into high-salience percept entities (StateCommands.set) so
13
+ // Exteroception surfaces them as "## Percepts (What I Notice)" on the following
14
+ // master cycle.
14
15
  //
15
- // The master reads these as environmental signals — NEVER as incoming
16
- // messages — and responds by creating plans/goals, never by emitting [REPLY];
17
- // the facet handles the actual communication.
16
+ // The master reads these as things IT noticed about its own situation — NEVER
17
+ // as incoming messages — and responds by creating plans/goals or by deciding
18
+ // whether it still means to make a contact. It never replies; the facet that
19
+ // raised the handoff owns the talking.
18
20
  //
19
- // Extracted verbatim from ExecutiveEngine (R5-g-2) as a pure collaborator.
20
- // The salience-spike that wakes the master after a push stays in the engine
21
- // (it touches gating state, not this buffer).
21
+ // ── Why the topic is not `audition.task.signal` ──────────────
22
+ //
23
+ // It used to be, and the payload was conversation-shaped: `{ entityId, threadId,
24
+ // … }`. That made the master's handoff channel the private property of ONE sense
25
+ // engine. A planning facet, a supervision facet, a deliberation facet — none of
26
+ // them had any way to hand anything to the master at all, and every facet type
27
+ // added afterwards would have had to mint its own topic and its own handler
28
+ // beside `_onAuditionTaskSignal`. The master does not need to know which faculty
29
+ // raised a handoff; it needs to know that a focused part of it formed something
30
+ // its singular seat must own. One topic, one handler, a discriminated `kind`.
22
31
  // ─────────────────────────────────────────────────────────────
23
32
 
24
33
  import type { EntityInput } from '#core/types'
25
34
 
26
- export interface PendingEscalation {
27
- entityId: string
28
- threadId: string
35
+ /**
36
+ * Work the master should plan or re-goal. The facet has already said whatever
37
+ * needed saying to the person in front of it; this is the cognitive remainder.
38
+ */
39
+ export interface EscalationHandoff {
40
+ kind: 'escalation'
41
+ reasoning: string
42
+ }
43
+
44
+ /**
45
+ * An intention toward a THIRD party — "I'll reach out to FKEM now" — formed
46
+ * while attending to something else. The facet never opens that channel itself,
47
+ * so this is the only thing standing between having decided to make contact and
48
+ * having made it.
49
+ */
50
+ export interface UndertakingHandoff {
51
+ kind: 'undertaking'
52
+ target: string
53
+ gist?: string
29
54
  reasoning: string
30
- tick: number
31
55
  }
32
56
 
33
- /** Requester context captured from the first buffered escalation, used to tag new goals. */
57
+ /** Everything a facet can hand up. Add a variant here, not a new topic. */
58
+ export type HandoffBody = EscalationHandoff | UndertakingHandoff
59
+
60
+ /**
61
+ * Schema validator for `executive.facet.handoff` — every facet type publishes
62
+ * through it, so the shape is checked at the bus rather than trusted per-caller.
63
+ * Returns null when valid, else the reason.
64
+ */
65
+ export function validateFacetHandoff( payload: unknown ): string | null {
66
+ if( !payload || typeof payload !== 'object') return 'payload must be object'
67
+ const body = ( payload as { body?: unknown } ).body
68
+ if( !body || typeof body !== 'object') return 'payload.body is required'
69
+ const kind = ( body as { kind?: unknown } ).kind
70
+ if( kind === 'escalation') return null
71
+ if( kind === 'undertaking')
72
+ return typeof ( body as { target?: unknown } ).target === 'string'
73
+ && ( body as { target: string } ).target.trim().length > 0
74
+ ? null
75
+ : 'undertaking handoff requires a non-empty target'
76
+ return `unknown handoff kind: ${String( kind )}`
77
+ }
78
+
79
+ export interface PendingHandoff {
80
+ /** Which facet raised it — for tracing a percept back to the thread that made it. */
81
+ facetId?: string
82
+ /**
83
+ * Who the facet was attending to, when it was attending to a someone. Absent
84
+ * for facets whose focus has no person in it (planning, deliberation) — which
85
+ * is exactly the case the old conversation-shaped payload could not express.
86
+ */
87
+ subjectEntityId?: string
88
+ subjectName?: string
89
+ threadId?: string
90
+ /** Sim tick at which the facet formed this. Undertaking discharge keys on it. */
91
+ tick: number
92
+ body: HandoffBody
93
+ }
94
+
95
+ /** Requester context captured from the first buffered handoff, used to tag new goals. */
34
96
  export interface EscalationRequester {
35
97
  entityId: string
36
98
  threadId: string
@@ -39,49 +101,105 @@ export interface EscalationRequester {
39
101
  export interface DrainedEscalations {
40
102
  /** High-salience percept entities to merge into StateCommands.set. */
41
103
  percepts: EntityInput[]
42
- /** First escalation's requester context, or undefined when the buffer was empty. */
104
+ /** First handoff's requester context, or undefined when none carried one. */
43
105
  requester?: EscalationRequester
44
106
  }
45
107
 
108
+ /** "in my conversation with X" when there was one, "while I was working" otherwise. */
109
+ function whereItHappened( h: PendingHandoff ): string {
110
+ const who = h.subjectName ?? h.subjectEntityId
111
+ return who ? `In my conversation with ${who}` : 'While I was working on something else'
112
+ }
113
+
46
114
  export class EscalationBuffer {
47
- private _pending: PendingEscalation[] = []
115
+ private _pending: PendingHandoff[] = []
48
116
 
49
- /** Buffer one escalation for injection on the next master cycle. */
50
- push( escalation: PendingEscalation ): void {
51
- this._pending.push( escalation )
117
+ /** Buffer one handoff for injection on the next master cycle. */
118
+ push( handoff: PendingHandoff ): void {
119
+ this._pending.push( handoff )
52
120
  }
53
121
 
54
122
  get size(): number { return this._pending.length }
55
123
  get isEmpty(): boolean { return this._pending.length === 0 }
56
124
 
57
125
  /**
58
- * Convert every buffered escalation into a high-salience percept entity and
59
- * clear the buffer. Returns the percepts plus the first escalation's
60
- * requester context (used to tag goals the master creates in response).
126
+ * Convert every buffered handoff into a high-salience percept entity and clear
127
+ * the buffer. Returns the percepts plus the first handoff's requester context
128
+ * (used to tag goals the master creates in response).
61
129
  */
62
130
  drainToPercepts(): DrainedEscalations {
63
131
  const percepts: EntityInput[] = []
64
- for( const esc of this._pending ){
65
- percepts.push({
66
- id: `escalation-percept-${esc.entityId}-${esc.tick}`,
67
- type: 'percept',
68
- metadata: {
69
- category: 'task-escalation',
70
- summary: `[Task from conversation with ${esc.entityId}] ${esc.reasoning}`,
71
- salience: 0.85,
72
- source: 'audition-facet',
73
- entityId: esc.entityId,
74
- threadId: esc.threadId,
75
- // Guides the master's response: plan, don't reply
76
- directive: 'Create a plan or update goals. Do not emit [REPLY] — the facet handles communication.',
132
+ let seq = 0
133
+ for( const h of this._pending ){
134
+ // Distinct ids per drain: two handoffs from one thread on one tick are two
135
+ // separate things the mind noticed, and keying on (subject, tick) alone would
136
+ // silently collapse them into whichever came last.
137
+ const id = `escalation-percept-${h.subjectEntityId ?? h.facetId ?? 'self'}-${h.tick}-${seq++}`
138
+
139
+ const common = {
140
+ salience: 0.85,
141
+ source: 'executive-facet',
142
+ ...( h.subjectEntityId ? { entityId: h.subjectEntityId } : {} ),
143
+ ...( h.threadId ? { threadId: h.threadId } : {} ),
144
+ ...( h.facetId ? { facetId: h.facetId } : {} ),
145
+ }
146
+
147
+ percepts.push( h.body.kind === 'undertaking'
148
+ ? {
149
+ id,
150
+ type: 'percept',
151
+ metadata: {
152
+ ...common,
153
+ category: 'undertaking',
154
+ // First person: this is the mind noticing what IT said it would do, not
155
+ // a report handed to it. What makes it act is that the words are still
156
+ // unsent — an undertaking it has already honoured reads the same until
157
+ // it checks, which is exactly the check we want it making.
158
+ // Everything actionable goes in `summary`: that is the only field the
159
+ // executive context actually renders (context.ts extractPercepts reads
160
+ // summary/content and nothing else).
161
+ //
162
+ // The closing clause is the whole point. A mind that has SAID it will make
163
+ // contact remembers deciding, and cannot tell from the inside whether the
164
+ // words went out — so it follows up on a message it never sent. Naming the
165
+ // gap is what lets it check. It stays a decision either way: it may have
166
+ // changed its mind, or judge this the wrong moment, and a reach-out
167
+ // competes with everything else like any other action.
168
+ summary: `${whereItHappened( h )} I said I would reach ${h.body.target}`
169
+ + ( h.body.gist ? ` — what I meant to say: "${h.body.gist.slice( 0, 220 )}"` : '')
170
+ + `. Nothing has gone to them yet; saying it in that conversation did not send it.`
171
+ + ` If I still mean it, I reach out with target '${h.body.target}'.`
172
+ + ` If I no longer do, I let it go — but I do not leave it half-done while telling them it is handled.`,
173
+ // Who was promised, and when the promise was made. The executive
174
+ // reconciles against these (see _reconcileUndertakings): once the mind
175
+ // has actually reached this target since `tick`, the percept is retired
176
+ // rather than left standing as a claim the words are still unsent.
177
+ undertakingTarget: h.body.target,
178
+ tick: h.tick,
179
+ },
77
180
  }
78
- })
181
+ : {
182
+ id,
183
+ type: 'percept',
184
+ metadata: {
185
+ ...common,
186
+ category: 'task-escalation',
187
+ // The steer lives IN the summary because that is the only field the
188
+ // executive context renders (context.ts extractPercepts reads
189
+ // summary/content and nothing else). It sat in a sibling `directive`
190
+ // field for its whole life and never once reached the master.
191
+ summary: `[Task from ${h.subjectName ?? h.subjectEntityId ?? 'my own focused work'}] ${h.body.reasoning}`
192
+ + ' — this is mine to plan or re-goal; the part of me that raised it handles the talking.',
193
+ tick: h.tick,
194
+ },
195
+ } )
79
196
  }
80
197
 
81
- // Capture requester context before clearing — used to tag new goals.
82
- const first = this._pending[0]
198
+ // Capture requester context before clearing — used to tag new goals. Only a
199
+ // handoff that came from a conversation has one.
200
+ const first = this._pending.find( h => h.subjectEntityId )
83
201
  const requester: EscalationRequester | undefined =
84
- first ? { entityId: first.entityId, threadId: first.threadId } : undefined
202
+ first ? { entityId: first.subjectEntityId!, threadId: first.threadId ?? '' } : undefined
85
203
 
86
204
  this._pending = []
87
205