@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.
- package/README.md +87 -22
- 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 +13733 -11057
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3729 -1199
- package/dist/index.js.map +1 -1
- package/dist/mcp/effectors.d.ts +1 -1
- package/dist/{will-DAW0l-lY.d.ts → will-DbDj_TEH.d.ts} +1214 -93
- 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 +85 -3
- 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 +129 -2
- package/src/cognition/agency/proactive.communicator.ts +19 -3
- package/src/cognition/agency/reconcile.learning.ts +16 -2
- package/src/cognition/agency/restart.ts +66 -0
- package/src/cognition/agency/schemas/repertoire.ts +12 -5
- 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 +109 -1
- 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 +686 -187
- 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 +89 -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 +169 -20
- 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 +11 -0
- package/src/cognition/memory/vector.adapter.ts +12 -3
- package/src/cognition/memory/vector.embedder.ts +54 -7
- 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 +246 -98
- package/src/core/orchestrator.ts +38 -0
- package/src/host/boot.ts +78 -22
- package/src/index.ts +35 -0
- package/src/llm/index.ts +415 -97
- package/src/llm/routing.ts +204 -0
- package/src/llm/summarizer.ts +5 -1
- package/src/llm/wire.contracts.ts +19 -0
- package/src/pma/index.ts +67 -53
- package/src/runners/thin-shim.runner.ts +18 -6
- package/src/sdk/will.ts +121 -22
- package/src/stem/assembly.audit.ts +1 -0
- package/src/stem/guards/identity.coherence.ts +17 -6
- package/src/stem/index.ts +82 -5
- package/src/stem/mind.ts +327 -79
- package/src/stem/policy/arbiter.ts +49 -14
- package/src/stem/policy/rule.table.ts +2 -2
- package/src/stem/tracts/effector.controller.ts +56 -9
- package/src/stem/tracts/outbox.writer.ts +40 -2
- package/src/cognition/faculties/executive.engine/messages.ts +0 -102
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type { TokenTracker } from '#cognition/utilities/token.tracker'
|
|
15
|
+
import type { LLMCallFunction } from '#cognition/utilities/token.tracker'
|
|
16
|
+
import { LLMSemaphore, withGate } from '#llm/gate'
|
|
17
|
+
|
|
18
|
+
/** Embedding is only ever a read or a write. */
|
|
19
|
+
export type EmbedFunction = Extract<LLMCallFunction, 'recall' | 'index'>
|
|
15
20
|
|
|
16
21
|
export interface EmbeddingProvider {
|
|
17
22
|
readonly modelName: string
|
|
@@ -40,13 +45,27 @@ export class OpenAICompatibleEmbedder implements EmbeddingProvider {
|
|
|
40
45
|
private _maxConcurrency: number
|
|
41
46
|
private _timeoutMs: number
|
|
42
47
|
private _tokenTracker: TokenTracker | null
|
|
48
|
+
/**
|
|
49
|
+
* Own gate — the same LLMSemaphore the LLM calls use, on a separate instance so
|
|
50
|
+
* embeddings and reasoning do not compete for one another's slots. It bounds the
|
|
51
|
+
* fan-out that produced the 10.7s tail, and `withGate` additionally retries a 429
|
|
52
|
+
* with backoff, which a bare `embed()` previously surfaced as a hard failure.
|
|
53
|
+
*/
|
|
54
|
+
private _gate: LLMSemaphore
|
|
43
55
|
|
|
44
56
|
constructor( config: {
|
|
45
57
|
modelName: string
|
|
46
58
|
dimensions: number
|
|
47
59
|
apiUrl: string
|
|
48
60
|
apiKey?: string | null
|
|
49
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* Max embedding requests in flight at once — across ALL callers, not just one
|
|
63
|
+
* embedBatch(). Default 4, chosen from measured provider behaviour rather than
|
|
64
|
+
* taste: gemini-embedding-001 answers a lone request in ~1.1s, but queues hard
|
|
65
|
+
* under fan-out — at 8 in flight the slowest three took 10.7s (all HTTP 200, no
|
|
66
|
+
* 429, simply serialized). That tail is what made recall exceed its 5s budget
|
|
67
|
+
* and return "no recall" while a mind with six live facets was asking.
|
|
68
|
+
*/
|
|
50
69
|
maxConcurrency?: number
|
|
51
70
|
/** @deprecated use maxConcurrency — kept as its fallback for back-compat. */
|
|
52
71
|
batchSize?: number
|
|
@@ -55,7 +74,7 @@ export class OpenAICompatibleEmbedder implements EmbeddingProvider {
|
|
|
55
74
|
/**
|
|
56
75
|
* Per-Will token tracker. When provided, each embedding call records its
|
|
57
76
|
* input-token usage under the 'embedding' category so memory-vector spend is
|
|
58
|
-
* visible alongside LLM spend instead of being a silent
|
|
77
|
+
* visible alongside LLM spend instead of being a silent cost leak.
|
|
59
78
|
*/
|
|
60
79
|
tokenTracker?: TokenTracker | null
|
|
61
80
|
} ){
|
|
@@ -63,12 +82,24 @@ export class OpenAICompatibleEmbedder implements EmbeddingProvider {
|
|
|
63
82
|
this.dimensions = config.dimensions
|
|
64
83
|
this._apiUrl = config.apiUrl
|
|
65
84
|
this._apiKey = config.apiKey ?? null
|
|
66
|
-
this._maxConcurrency = Math.max( 1, config.maxConcurrency ?? config.batchSize ??
|
|
85
|
+
this._maxConcurrency = Math.max( 1, config.maxConcurrency ?? config.batchSize ?? 4 )
|
|
86
|
+
this._gate = new LLMSemaphore( this._maxConcurrency )
|
|
67
87
|
this._timeoutMs = config.timeoutMs ?? 30_000
|
|
68
88
|
this._tokenTracker = config.tokenTracker ?? null
|
|
69
89
|
}
|
|
70
90
|
|
|
71
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Embed one item, gated. Every caller funnels through here — a facet building a
|
|
93
|
+
* prompt, the master recalling, the consolidator indexing — so the gate is the
|
|
94
|
+
* only place total in-flight fan-out is bounded. Waiting for a slot is strictly
|
|
95
|
+
* better than the alternative it replaces: an ungated request that returns after
|
|
96
|
+
* the recall budget has already expired is a request whose answer is thrown away.
|
|
97
|
+
*/
|
|
98
|
+
async embed( content: unknown, fn: EmbedFunction = 'recall'): Promise<number[]> {
|
|
99
|
+
return withGate( () => this._embedOnce( content, fn ), `embed:${ this.modelName }`, this._gate )
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private async _embedOnce( content: unknown, fn: EmbedFunction ): Promise<number[]> {
|
|
72
103
|
let response: Response
|
|
73
104
|
try {
|
|
74
105
|
response = await fetch(`${this._apiUrl}/embeddings`, {
|
|
@@ -106,6 +137,21 @@ export class OpenAICompatibleEmbedder implements EmbeddingProvider {
|
|
|
106
137
|
if( !Array.isArray( embedding ) || embedding.length === 0 )
|
|
107
138
|
throw new Error(`Embedding response was empty or malformed for model ${this.modelName}`)
|
|
108
139
|
|
|
140
|
+
// The configured width must match what the provider actually returns. This class
|
|
141
|
+
// sends no `dimensions` param, so the index is sized from config alone — and a
|
|
142
|
+
// wrong number does not fail, it silently builds an index that can never match.
|
|
143
|
+
// Providers differ per model family and change defaults between versions, so the
|
|
144
|
+
// number is checked against reality once rather than trusted. Failing here is safe:
|
|
145
|
+
// indexing degrades to "deferred" and recall to "no recall", both already
|
|
146
|
+
// best-effort, and the message carries the value to set.
|
|
147
|
+
if( embedding.length !== this.dimensions )
|
|
148
|
+
throw new Error(
|
|
149
|
+
`Embedding width mismatch for ${ this.modelName }: provider returned ${ embedding.length } ` +
|
|
150
|
+
`dimensions, index is configured for ${ this.dimensions }. ` +
|
|
151
|
+
`Set WILL_EMBEDDING_DIMENSIONS=${ embedding.length } (and delete any existing ` +
|
|
152
|
+
`vector_index built at the old width).`
|
|
153
|
+
)
|
|
154
|
+
|
|
109
155
|
// Meter embedding token usage (input-only — embeddings have no completion).
|
|
110
156
|
// Recorded under the 'embedding' category so per-Will dashboards can split
|
|
111
157
|
// memory-vector spend from LLM reasoning spend.
|
|
@@ -118,6 +164,7 @@ export class OpenAICompatibleEmbedder implements EmbeddingProvider {
|
|
|
118
164
|
totalTokens: usedTok,
|
|
119
165
|
category: 'embedding',
|
|
120
166
|
attribute: 'memory',
|
|
167
|
+
process: 'cog', // background: no deliberation happens here
|
|
121
168
|
function: fn, // 'recall' (query) | 'index' (write)
|
|
122
169
|
scope: this.modelName,
|
|
123
170
|
tick: 0,
|
|
@@ -128,7 +175,7 @@ export class OpenAICompatibleEmbedder implements EmbeddingProvider {
|
|
|
128
175
|
return embedding
|
|
129
176
|
}
|
|
130
177
|
|
|
131
|
-
async embedBatch( contents: unknown[], fn:
|
|
178
|
+
async embedBatch( contents: unknown[], fn: EmbedFunction = 'index'): Promise<number[][]> {
|
|
132
179
|
// Bounded fan-out: cap concurrent requests at _maxConcurrency instead of
|
|
133
180
|
// firing all of them at once (FN16), while preserving input order.
|
|
134
181
|
const results: number[][] = new Array( contents.length )
|
|
@@ -170,7 +217,7 @@ export class MockEmbedder implements EmbeddingProvider {
|
|
|
170
217
|
this._seed = seed
|
|
171
218
|
}
|
|
172
219
|
|
|
173
|
-
async embed( content: unknown, _fn:
|
|
220
|
+
async embed( content: unknown, _fn: EmbedFunction = 'recall'): Promise<number[]> {
|
|
174
221
|
const str = typeof content === 'string' ? content : JSON.stringify( content )
|
|
175
222
|
const hash = this._hashString( str )
|
|
176
223
|
const embedding: number[] = []
|
|
@@ -184,7 +231,7 @@ export class MockEmbedder implements EmbeddingProvider {
|
|
|
184
231
|
return embedding
|
|
185
232
|
}
|
|
186
233
|
|
|
187
|
-
async embedBatch( contents: unknown[], fn:
|
|
234
|
+
async embedBatch( contents: unknown[], fn: EmbedFunction = 'index'): Promise<number[][]> {
|
|
188
235
|
return Promise.all( contents.map( c => this.embed( c, fn ) ) )
|
|
189
236
|
}
|
|
190
237
|
|
|
@@ -118,6 +118,7 @@ const PRIOR_DESCRIPTIONS: Record<string, { lower: string; raise: string }> = {
|
|
|
118
118
|
'engine-config-inhibition.baseInhibitionStrength': { lower: 'acting on impulse more freely', raise: 'holding myself in check more firmly before acting' },
|
|
119
119
|
'engine-config-self-model.minNewExperiences': { lower: 're-evaluating who I am on less new experience', raise: 'requiring more new experience before re-evaluating who I am' },
|
|
120
120
|
'engine-config-attention.shiftInertia': { lower: 'shifting my attention more readily', raise: 'holding my attention more fixedly' },
|
|
121
|
+
'engine-config-attention.maxFoci': { lower: 'attending to one thing at a time, narrowly', raise: 'keeping several things in view at once' },
|
|
121
122
|
'engine-config-goal-manager.gritPriority': { lower: 'refusing to give up on more of what matters to me', raise: 'letting go of goals more readily' },
|
|
122
123
|
'engine-config-goal-manager.gritPatienceScale': { lower: 'losing patience with stuck goals sooner', raise: 'staying the course on hard goals far longer' },
|
|
123
124
|
'engine-config-goal-manager.frustrationTolerance': { lower: 'giving up faster when frustrated', raise: 'holding steady through frustration' },
|
|
@@ -129,6 +130,7 @@ const PRIOR_DESCRIPTIONS: Record<string, { lower: string; raise: string }> = {
|
|
|
129
130
|
'engine-config-executive.riskTolerance': { lower: 'playing it safer', raise: 'taking bigger risks' },
|
|
130
131
|
'engine-config-frustration.irritabilityRate': { lower: 'letting frustration snowball into a bad mood more slowly', raise: 'getting wound up into a bad mood faster' },
|
|
131
132
|
'engine-config-executive.deliberateThreshold': { lower: 'stopping to think things through more readily', raise: 'going with my gut more, deliberating less' },
|
|
133
|
+
'engine-config-executive.maxFacets': { lower: 'keeping fewer things going at once, one at a time', raise: 'holding more conversations and threads at once' },
|
|
132
134
|
'engine-config-reward.socialWeight': { lower: 'caring less about social warmth', raise: 'finding warmth and connection more rewarding' },
|
|
133
135
|
'engine-config-frustration.angerReactivity': { lower: 'letting slights go, yielding rather than bristling', raise: 'bristling harder when I feel wronged' },
|
|
134
136
|
'engine-config-novelty.significanceThreshold': { lower: 'noticing what is new and unusual more readily', raise: 'needing more for something to strike me as new' },
|
|
@@ -143,6 +145,10 @@ const PRIOR_DESCRIPTIONS: Record<string, { lower: string; raise: string }> = {
|
|
|
143
145
|
'engine-config-action-selector.switchCost': { lower: 'dropping what I am doing for a new pull more easily', raise: 'seeing an action through, harder to knock off course once underway' },
|
|
144
146
|
'engine-config-action-selector.riskWeight': { lower: 'weighing the downside of what I do less — acting bolder', raise: 'weighing what could go wrong more heavily before I act' },
|
|
145
147
|
'engine-config-action-selector.noveltyWeight': { lower: 'feeling less pull toward the untried', raise: 'drawn more strongly to do the untried and unpracticed' },
|
|
148
|
+
'engine-config-action-selector.repeatDamping': { lower: 'following up sooner when I have had no answer', raise: 'giving people room after I have said my piece' },
|
|
149
|
+
'engine-config-action-selector.repeatWindowTicks': { lower: 'coming back to something sooner after I have said it', raise: 'letting what I have said stand for longer before returning to it' },
|
|
150
|
+
'engine-config-action-selector.replyWindowTicks': { lower: 'reading a silence as an answer sooner', raise: 'giving someone longer before I take their quiet as telling me anything' },
|
|
151
|
+
'engine-config-action-selector.socialWeight': { lower: 'reaching for people regardless of whether they answer me', raise: 'drawn toward the people who actually answer me' },
|
|
146
152
|
'engine-config-moral.eventThreshold': { lower: 'holding myself to my principles more sharply', raise: 'letting moral lapses weigh on me less' },
|
|
147
153
|
'engine-config-frustration.decayRate': { lower: 'staying frustrated for longer after a setback', raise: 'shaking off frustration and bouncing back faster' },
|
|
148
154
|
'engine-config-reward.socialWarmthBoost': { lower: 'being warmed less by a kind exchange', raise: 'being warmed more by every kind exchange' },
|