@mindot/will 0.1.0 → 0.2.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 +38 -3
- package/dist/index.d.ts +52 -7760
- package/dist/index.js +374 -86
- package/dist/index.js.map +1 -1
- package/dist/mcp/cli.d.ts +1 -0
- package/dist/mcp/cli.js +26048 -0
- package/dist/mcp/cli.js.map +1 -0
- package/dist/mcp/effectors.d.ts +55 -0
- package/dist/mcp/effectors.js +76 -0
- package/dist/mcp/effectors.js.map +1 -0
- package/dist/will-B5eKs3Wv.d.ts +7903 -0
- package/package.json +38 -30
- package/src/cognition/agency/engines/action.selector.ts +3 -0
- package/src/cognition/agency/engines/affordance.synthesizer.ts +26 -12
- package/src/cognition/agency/engines/deliberation.engine.ts +7 -2
- package/src/cognition/agency/engines/motor.schema.executor.ts +2 -0
- package/src/cognition/agency/schemas/external.ts +27 -10
- package/src/cognition/agency/schemas/repertoire.ts +12 -0
- package/src/cognition/agency/types.ts +51 -2
- package/src/cognition/faculties/executive.engine/commands.ts +47 -11
- package/src/cognition/faculties/executive.engine/context.ts +28 -0
- package/src/cognition/faculties/executive.engine/facet.supervisor.ts +15 -1
- package/src/cognition/faculties/executive.engine/facet.ts +32 -6
- package/src/cognition/faculties/executive.engine/prompt.factory.ts +11 -1
- package/src/cognition/faculties/executive.engine/types.ts +24 -2
- package/src/cognition/index.ts +1 -1
- package/src/core/abstracts.ts +39 -12
- package/src/index.ts +6 -0
- package/src/mcp/cli.ts +129 -0
- package/src/mcp/effectors.ts +159 -0
- package/src/mcp/server.ts +167 -0
- package/src/sdk/will.ts +269 -44
- package/src/stem/index.ts +16 -0
- package/src/stem/mind.ts +11 -4
- package/src/stem/tracts/effector.controller.ts +1 -0
- package/src/types.ts +2 -0
package/dist/index.js
CHANGED
|
@@ -998,27 +998,54 @@ var DefaultStateManager = class {
|
|
|
998
998
|
|
|
999
999
|
// src/core/abstracts.ts
|
|
1000
1000
|
var BunStorageAdapter = class {
|
|
1001
|
+
get _isBun() {
|
|
1002
|
+
return typeof Bun !== "undefined";
|
|
1003
|
+
}
|
|
1001
1004
|
async write(path, content) {
|
|
1002
|
-
|
|
1005
|
+
if (this._isBun) {
|
|
1006
|
+
await Bun.write(path, content);
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
const { mkdir, writeFile } = await import('fs/promises');
|
|
1010
|
+
const { dirname } = await import('path');
|
|
1011
|
+
await mkdir(dirname(path), { recursive: true });
|
|
1012
|
+
await writeFile(path, content);
|
|
1003
1013
|
}
|
|
1004
1014
|
async read(path) {
|
|
1005
|
-
|
|
1006
|
-
if (!await file.exists())
|
|
1015
|
+
if (!await this.exists(path))
|
|
1007
1016
|
throw new Error(`File not found: ${path}`);
|
|
1008
|
-
|
|
1017
|
+
if (this._isBun)
|
|
1018
|
+
return Bun.file(path).text();
|
|
1019
|
+
const { readFile } = await import('fs/promises');
|
|
1020
|
+
return readFile(path, "utf8");
|
|
1009
1021
|
}
|
|
1010
1022
|
async readBytes(path) {
|
|
1011
|
-
|
|
1012
|
-
if (!await file.exists())
|
|
1023
|
+
if (!await this.exists(path))
|
|
1013
1024
|
throw new Error(`File not found: ${path}`);
|
|
1014
|
-
|
|
1025
|
+
if (this._isBun)
|
|
1026
|
+
return new Uint8Array(await Bun.file(path).arrayBuffer());
|
|
1027
|
+
const { readFile } = await import('fs/promises');
|
|
1028
|
+
return new Uint8Array(await readFile(path));
|
|
1015
1029
|
}
|
|
1016
1030
|
async exists(path) {
|
|
1017
|
-
|
|
1031
|
+
if (this._isBun)
|
|
1032
|
+
return Bun.file(path).exists();
|
|
1033
|
+
const { access } = await import('fs/promises');
|
|
1034
|
+
try {
|
|
1035
|
+
await access(path);
|
|
1036
|
+
return true;
|
|
1037
|
+
} catch {
|
|
1038
|
+
return false;
|
|
1039
|
+
}
|
|
1018
1040
|
}
|
|
1019
1041
|
async delete(path) {
|
|
1020
|
-
|
|
1021
|
-
|
|
1042
|
+
if (this._isBun) {
|
|
1043
|
+
const file = Bun.file(path);
|
|
1044
|
+
await file.exists() && await file.delete();
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
const { rm } = await import('fs/promises');
|
|
1048
|
+
await rm(path, { force: true });
|
|
1022
1049
|
}
|
|
1023
1050
|
async ensureDir(path) {
|
|
1024
1051
|
const { mkdirSync: mkdirSync6 } = await import('fs');
|
|
@@ -7856,16 +7883,43 @@ function buildIdeomotorIntents(output, state, footprint) {
|
|
|
7856
7883
|
const set = [];
|
|
7857
7884
|
const seen = /* @__PURE__ */ new Set();
|
|
7858
7885
|
const priority = clamp01(output.confidence ?? 0.8);
|
|
7886
|
+
const externalBySchema = /* @__PURE__ */ new Map();
|
|
7887
|
+
for (const e of state.entities.values()) {
|
|
7888
|
+
if (e.type !== "affordance") continue;
|
|
7889
|
+
const m = e.metadata;
|
|
7890
|
+
if (m?.["source"] !== "external") continue;
|
|
7891
|
+
const schema = typeof m["schema"] === "string" ? m["schema"] : void 0;
|
|
7892
|
+
if (schema) externalBySchema.set(schema.toLowerCase(), schema);
|
|
7893
|
+
}
|
|
7859
7894
|
for (const action of output.actions) {
|
|
7860
|
-
|
|
7861
|
-
if (
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
|
|
7895
|
+
const t = action.type.toLowerCase();
|
|
7896
|
+
if (COMMUNICATE_ACTION_TYPES.has(t)) {
|
|
7897
|
+
if (!action.target) continue;
|
|
7898
|
+
const keid2 = resolveKnownEntity(action.target, state);
|
|
7899
|
+
if (!keid2 || seen.has(keid2)) continue;
|
|
7900
|
+
seen.add(keid2);
|
|
7901
|
+
set.push({
|
|
7902
|
+
id: `ideomotor-reach-out-${keid2}`,
|
|
7903
|
+
type: "ideomotor.intent",
|
|
7904
|
+
metadata: { schema: "reach-out", targetEntityId: keid2, priority, origin: "executive", tick: footprint.tickObserved }
|
|
7905
|
+
});
|
|
7906
|
+
continue;
|
|
7907
|
+
}
|
|
7908
|
+
const schema = externalBySchema.get(t);
|
|
7909
|
+
if (!schema || seen.has(`ability:${schema}`)) continue;
|
|
7910
|
+
seen.add(`ability:${schema}`);
|
|
7911
|
+
const keid = action.target ? resolveKnownEntity(action.target, state) : void 0;
|
|
7865
7912
|
set.push({
|
|
7866
|
-
id: `ideomotor
|
|
7913
|
+
id: `ideomotor-${schema}${keid ? `-${keid}` : ""}`,
|
|
7867
7914
|
type: "ideomotor.intent",
|
|
7868
|
-
metadata: {
|
|
7915
|
+
metadata: {
|
|
7916
|
+
schema,
|
|
7917
|
+
...keid ? { targetEntityId: keid } : {},
|
|
7918
|
+
...action.args && typeof action.args === "object" ? { parameters: action.args } : {},
|
|
7919
|
+
priority,
|
|
7920
|
+
origin: "executive",
|
|
7921
|
+
tick: footprint.tickObserved
|
|
7922
|
+
}
|
|
7869
7923
|
});
|
|
7870
7924
|
}
|
|
7871
7925
|
const currentIds = new Set(set.map((s) => s.id));
|
|
@@ -9918,6 +9972,7 @@ async function buildExecutiveContext(state, deps, recallQuery) {
|
|
|
9918
9972
|
plans,
|
|
9919
9973
|
relevantPlanIds,
|
|
9920
9974
|
percepts,
|
|
9975
|
+
abilities: extractAbilities(state),
|
|
9921
9976
|
workingMemory,
|
|
9922
9977
|
memories,
|
|
9923
9978
|
beliefs,
|
|
@@ -9929,6 +9984,23 @@ async function buildExecutiveContext(state, deps, recallQuery) {
|
|
|
9929
9984
|
currentFocus: extractCurrentFocus(state, goals)
|
|
9930
9985
|
};
|
|
9931
9986
|
}
|
|
9987
|
+
var MAX_SURFACED_ABILITIES = 8;
|
|
9988
|
+
function extractAbilities(state) {
|
|
9989
|
+
const out = [];
|
|
9990
|
+
for (const e of state.entities.values()) {
|
|
9991
|
+
if (e.type !== "affordance") continue;
|
|
9992
|
+
const m = e.metadata;
|
|
9993
|
+
if (m?.["source"] !== "external" || m?.["available"] === false) continue;
|
|
9994
|
+
const name = typeof m?.["schema"] === "string" ? m["schema"] : void 0;
|
|
9995
|
+
if (!name) continue;
|
|
9996
|
+
const description = typeof m["description"] === "string" ? m["description"] : void 0;
|
|
9997
|
+
const params = m["parameters"];
|
|
9998
|
+
const target = m["targetEntityId"] ? typeof params?.["targetEntityName"] === "string" ? params["targetEntityName"] : String(m["targetEntityId"]) : void 0;
|
|
9999
|
+
out.push({ name, ...description ? { description } : {}, ...target ? { target } : {} });
|
|
10000
|
+
if (out.length >= MAX_SURFACED_ABILITIES) break;
|
|
10001
|
+
}
|
|
10002
|
+
return out.length > 0 ? out : void 0;
|
|
10003
|
+
}
|
|
9932
10004
|
function extractCurrentFocus(state, goals) {
|
|
9933
10005
|
const m = state.entities.get("task-switch-focus")?.metadata;
|
|
9934
10006
|
if (!m?.goalId) return void 0;
|
|
@@ -10185,7 +10257,7 @@ ${roleDescription}
|
|
|
10185
10257
|
${consciousnessArchitecture}
|
|
10186
10258
|
|
|
10187
10259
|
## Output Guidelines
|
|
10188
|
-
- **actions**: Choose from effectors you know about. If uncertain, describe what you want to achieve in natural language and your body will try to match it.
|
|
10260
|
+
- **actions**: Choose from effectors you know about. If uncertain, describe what you want to achieve in natural language and your body will try to match it. When enacting one of your available abilities that needs specifics (a query, a message, a value), supply them in the action's "args" object \u2014 e.g. {"type": "search_docs", "args": {"query": "tick loop design"}, ...}. Your body enacts the ability with exactly those args.
|
|
10189
10261
|
- **plans**: Include for goals without existing plans or where plans need revision. You may keep multiple plans per goal \u2014 set **planId** to act on a specific existing plan (validate/execute/revise/cancel); omit it to draft a new one. Your current plans are listed under "## Active Plans".
|
|
10190
10262
|
- **newBeliefs**: Extract patterns from experiences visible in your current state. Only record a belief if you can point to a specific observation that supports it \u2014 do not infer experiences you have no record of. Set 'evidence' honestly: 'single_observation' (first time noticing), 'recurring_pattern' (seen multiple times), 'strong_pattern' (deeply established).
|
|
10191
10263
|
- **introspection**: Include when significant events occurred or you notice patterns. When you spot a cognitive bias in your own reasoning, name it in 'identifiedBiases' using its common term where one fits (e.g. overgeneralization, confirmation bias, recency bias) \u2014 this lets your self-assessment line up with the patterns your faculties detect on their own.
|
|
@@ -10408,6 +10480,11 @@ ${context.goals.map((g) => {
|
|
|
10408
10480
|
const recentOutcomesBlock = has("recentActions") ? this._buildRecentOutcomesSection(context.recentActions, state.tick).trim() : "";
|
|
10409
10481
|
const perceptsBlock = has("percepts") ? `## Percepts (What You Notice)
|
|
10410
10482
|
${context.percepts.slice(0, 10).map((p) => `- [${p.category}] ${p.summary} (salience: ${p.salience.toFixed(2)})`).join("\n") || "Nothing notable"}` : "";
|
|
10483
|
+
const abilitiesBlock = context.abilities && context.abilities.length > 0 ? `## Abilities Available Now
|
|
10484
|
+
Things you can do in this situation \u2014 name one as an action's "type" (with "args" for any specifics it needs) and your body enacts it:
|
|
10485
|
+
${context.abilities.map(
|
|
10486
|
+
(a) => `- **${a.name}**${a.target ? ` (toward ${a.target})` : ""}${a.description ? ` \u2014 ${a.description}` : ""}`
|
|
10487
|
+
).join("\n")}` : "";
|
|
10411
10488
|
const ruminationsBlock = has("ruminations") ? `## Active Ruminations (retrieved memories & thoughts)
|
|
10412
10489
|
${context.workingMemory.map((w) => `- [${w.type}] ${w.summary} (activation: ${w.activation.toFixed(2)})`).join("\n") || "Nothing actively held in mind"}` : "";
|
|
10413
10490
|
const memoriesBlock = has("memories") ? this._buildMemoriesSection(context.memories, state.tick) : "";
|
|
@@ -10437,6 +10514,7 @@ You've been focused on ${context.currentFocus.goalDescription ? `"${context.curr
|
|
|
10437
10514
|
actionDiversity.trim(),
|
|
10438
10515
|
recentOutcomesBlock,
|
|
10439
10516
|
perceptsBlock,
|
|
10517
|
+
abilitiesBlock,
|
|
10440
10518
|
ruminationsBlock,
|
|
10441
10519
|
recentIntrospection.trim(),
|
|
10442
10520
|
memoriesBlock,
|
|
@@ -11071,6 +11149,17 @@ var ExecutiveFacet = class {
|
|
|
11071
11149
|
markActive(tick) {
|
|
11072
11150
|
this._lastActiveTick = tick;
|
|
11073
11151
|
}
|
|
11152
|
+
/** _reason() calls currently in flight — a real LLM call spans many ticks. */
|
|
11153
|
+
_inflight = 0;
|
|
11154
|
+
/**
|
|
11155
|
+
* True while the facet has work the reaper must not discard: queued reports
|
|
11156
|
+
* awaiting the pump, or an in-flight _reason() whose decision hasn't landed.
|
|
11157
|
+
* The idle TTL only measures *quiet* facets — reaping a busy one destroys the
|
|
11158
|
+
* listeners its pending decision needs, silently dropping a conversation reply.
|
|
11159
|
+
*/
|
|
11160
|
+
get busy() {
|
|
11161
|
+
return this._inflight > 0 || this._pendingReports.length > 0;
|
|
11162
|
+
}
|
|
11074
11163
|
/**
|
|
11075
11164
|
* Per-facet chunk handler — fires for every LLM token during _reason().
|
|
11076
11165
|
* Set by the creating engine (e.g. AuditionEngine) for entity-scoped streaming.
|
|
@@ -11124,9 +11213,24 @@ var ExecutiveFacet = class {
|
|
|
11124
11213
|
this._pendingReports.push(report);
|
|
11125
11214
|
return;
|
|
11126
11215
|
}
|
|
11216
|
+
this._launchReason(report);
|
|
11217
|
+
}
|
|
11218
|
+
/**
|
|
11219
|
+
* Launch _reason() with in-flight accounting. `busy` must hold for the whole
|
|
11220
|
+
* span (a real LLM call is 10–30s ≈ many ticks) so the supervisor's idle
|
|
11221
|
+
* reaper never destroys a facet whose decision is still coming — that would
|
|
11222
|
+
* clear its listeners and silently drop the reply. Completion re-stamps
|
|
11223
|
+
* activity so the idle TTL measures quiet time *after* the decision, not
|
|
11224
|
+
* after the report that started it.
|
|
11225
|
+
*/
|
|
11226
|
+
_launchReason(report) {
|
|
11227
|
+
this._inflight++;
|
|
11127
11228
|
this._reason(report).catch(
|
|
11128
11229
|
(err) => logger.error(`[executive.facet] ${this.facetId} reasoning error:`, err)
|
|
11129
|
-
)
|
|
11230
|
+
).finally(() => {
|
|
11231
|
+
this._inflight--;
|
|
11232
|
+
this.markActive(this._currentStateRef?.tick ?? this._lastActiveTick);
|
|
11233
|
+
});
|
|
11130
11234
|
}
|
|
11131
11235
|
/**
|
|
11132
11236
|
* Per-tick pump — called by the FacetSupervisor from the ExecutiveEngine's
|
|
@@ -11142,9 +11246,7 @@ var ExecutiveFacet = class {
|
|
|
11142
11246
|
const batch = this._pendingReports;
|
|
11143
11247
|
this._pendingReports = [];
|
|
11144
11248
|
for (const report of batch)
|
|
11145
|
-
this.
|
|
11146
|
-
(err) => logger.error(`[executive.facet] ${this.facetId} reasoning error:`, err)
|
|
11147
|
-
);
|
|
11249
|
+
this._launchReason(report);
|
|
11148
11250
|
}
|
|
11149
11251
|
subscribe(listener) {
|
|
11150
11252
|
this._listeners.add(listener);
|
|
@@ -12321,9 +12423,11 @@ var FacetSupervisor = class {
|
|
|
12321
12423
|
this._reapIdle(state.tick);
|
|
12322
12424
|
}
|
|
12323
12425
|
_reapIdle(tick) {
|
|
12324
|
-
for (const [id, facet] of [...this._facets])
|
|
12426
|
+
for (const [id, facet] of [...this._facets]) {
|
|
12427
|
+
if (facet.busy) continue;
|
|
12325
12428
|
if (tick - facet.lastActiveTick > this._idleTtlTicks)
|
|
12326
12429
|
this._reap(id, "idle");
|
|
12430
|
+
}
|
|
12327
12431
|
}
|
|
12328
12432
|
/** Destroy + deregister a facet and notify its owner. Shared by the reaper + LRU eviction. */
|
|
12329
12433
|
_reap(facetId, reason) {
|
|
@@ -12350,6 +12454,12 @@ var FacetSupervisor = class {
|
|
|
12350
12454
|
_leastRecentlyActive() {
|
|
12351
12455
|
let id = null;
|
|
12352
12456
|
let min = Infinity;
|
|
12457
|
+
for (const [fid, facet] of this._facets)
|
|
12458
|
+
if (!facet.busy && facet.lastActiveTick < min) {
|
|
12459
|
+
min = facet.lastActiveTick;
|
|
12460
|
+
id = fid;
|
|
12461
|
+
}
|
|
12462
|
+
if (id) return id;
|
|
12353
12463
|
for (const [fid, facet] of this._facets)
|
|
12354
12464
|
if (facet.lastActiveTick < min) {
|
|
12355
12465
|
min = facet.lastActiveTick;
|
|
@@ -18402,24 +18512,30 @@ var AffordanceSynthesizer = class {
|
|
|
18402
18512
|
})
|
|
18403
18513
|
});
|
|
18404
18514
|
}
|
|
18405
|
-
const
|
|
18406
|
-
|
|
18515
|
+
const personSchemas = schemas.filter((s) => s.binds === "entity");
|
|
18516
|
+
const objectSchemas = schemas.filter((s) => s.binds === "object");
|
|
18517
|
+
if (personSchemas.length > 0 || objectSchemas.length > 0)
|
|
18407
18518
|
for (const [id, e] of state.entities) {
|
|
18408
18519
|
if (e.type !== "known-entity") continue;
|
|
18409
18520
|
const m = e.metadata;
|
|
18410
|
-
|
|
18521
|
+
const kind = str(m?.["kind"]);
|
|
18522
|
+
const applicable = kind === "sentient" ? personSchemas : kind === "thing" ? objectSchemas : null;
|
|
18523
|
+
if (!applicable || applicable.length === 0) continue;
|
|
18411
18524
|
const keid = str(m?.["keid"]) ?? id;
|
|
18412
18525
|
const fam = num(m?.["familiarity"], 0);
|
|
18413
18526
|
const val = num(m?.["valence"], 0);
|
|
18414
18527
|
const res = num(m?.["resolutionConfidence"], 0);
|
|
18415
|
-
|
|
18416
|
-
|
|
18417
|
-
|
|
18418
|
-
|
|
18419
|
-
|
|
18420
|
-
|
|
18421
|
-
|
|
18422
|
-
|
|
18528
|
+
const salience = fam * 0.6 + Math.max(0, val) * 0.3 + res * 0.1 + (goalTargets.get(keid) ?? 0);
|
|
18529
|
+
const name = str(m?.["name"]) ?? keid;
|
|
18530
|
+
for (const schema of applicable)
|
|
18531
|
+
candidates.push({
|
|
18532
|
+
salience,
|
|
18533
|
+
affordance: this._build(schema, tick, state, valence, energyLow, skills, {
|
|
18534
|
+
evokedBy: id,
|
|
18535
|
+
targetEntityId: keid,
|
|
18536
|
+
parameters: { targetEntityName: name }
|
|
18537
|
+
})
|
|
18538
|
+
});
|
|
18423
18539
|
}
|
|
18424
18540
|
for (const [id, e] of state.entities) {
|
|
18425
18541
|
if (e.type !== "ideomotor.intent") continue;
|
|
@@ -18511,6 +18627,7 @@ var AffordanceSynthesizer = class {
|
|
|
18511
18627
|
habitStrength,
|
|
18512
18628
|
available: this._available(schema.preconditions, (k) => metric(state, k, 0)),
|
|
18513
18629
|
tags: schema.tags ?? [],
|
|
18630
|
+
...schema.description ? { description: schema.description } : {},
|
|
18514
18631
|
planBias: ctx.planBias,
|
|
18515
18632
|
planId: ctx.planId,
|
|
18516
18633
|
stepId: ctx.stepId,
|
|
@@ -18533,6 +18650,7 @@ var AffordanceSynthesizer = class {
|
|
|
18533
18650
|
habitStrength: a.habitStrength,
|
|
18534
18651
|
available: a.available,
|
|
18535
18652
|
tags: a.tags,
|
|
18653
|
+
description: a.description,
|
|
18536
18654
|
planBias: a.planBias,
|
|
18537
18655
|
planId: a.planId,
|
|
18538
18656
|
stepId: a.stepId,
|
|
@@ -18739,6 +18857,9 @@ var ActionSelector = class {
|
|
|
18739
18857
|
targetEntityId: s.affordance.targetEntityId,
|
|
18740
18858
|
parameters: s.affordance.parameters,
|
|
18741
18859
|
activation: s.activation,
|
|
18860
|
+
// Carry the ability's meaning so the Deliberator weighs what each
|
|
18861
|
+
// option is FOR, not bare labels.
|
|
18862
|
+
...s.affordance.description ? { description: s.affordance.description } : {},
|
|
18742
18863
|
// Channel B: flag a candidate that is an active plan's frontier step, so
|
|
18743
18864
|
// the deliberation facet can own "this is my plan's next step" in-character.
|
|
18744
18865
|
...s.affordance.source === "plan" ? { fromPlan: true } : {}
|
|
@@ -18998,8 +19119,9 @@ var DeliberationEngine = class {
|
|
|
18998
19119
|
lines.push("Your automatic action-selection was uncertain. Candidate actions:");
|
|
18999
19120
|
candidates.forEach((c, i) => {
|
|
19000
19121
|
const to = c.targetEntityId ? ` toward ${c.targetEntityId}` : "";
|
|
19001
|
-
const
|
|
19002
|
-
|
|
19122
|
+
const what = c.description ? ` \u2014 ${c.description}` : "";
|
|
19123
|
+
const plan = c.fromPlan ? " (your current plan's next step)" : "";
|
|
19124
|
+
lines.push(`${i + 1}. ${c.schema}${to}${what}${plan}`);
|
|
19003
19125
|
});
|
|
19004
19126
|
return lines.join("\n");
|
|
19005
19127
|
}
|
|
@@ -19476,7 +19598,9 @@ var MotorSchemaExecutor = class {
|
|
|
19476
19598
|
intentId: intent.id,
|
|
19477
19599
|
targetEntityId: intent.targetEntityId,
|
|
19478
19600
|
parameters: intent.parameters,
|
|
19479
|
-
tick
|
|
19601
|
+
tick,
|
|
19602
|
+
// The ability's declared meaning, carried to the host handler.
|
|
19603
|
+
description: this._resolve(intent.schema)?.description
|
|
19480
19604
|
}
|
|
19481
19605
|
});
|
|
19482
19606
|
} catch (err) {
|
|
@@ -19570,6 +19694,15 @@ var SchemaRepertoire = class {
|
|
|
19570
19694
|
if (!this._skills.has(schema.id))
|
|
19571
19695
|
this._skills.set(schema.id, freshSkill(schema.id, 0.4, 0));
|
|
19572
19696
|
}
|
|
19697
|
+
/**
|
|
19698
|
+
* Register a host effector's primitive schema at runtime (post-create
|
|
19699
|
+
* `.effector()`). Unlike a composite it is NOT marked learned — it is a
|
|
19700
|
+
* capacity the host granted, which the synthesizer surfaces immediately and
|
|
19701
|
+
* reafference then builds skill on. Idempotent; re-registering updates it.
|
|
19702
|
+
*/
|
|
19703
|
+
registerExternal(schema) {
|
|
19704
|
+
this._templates.set(schema.id, schema);
|
|
19705
|
+
}
|
|
19573
19706
|
// ── skills ────────────────────────────────────────────────────
|
|
19574
19707
|
skills() {
|
|
19575
19708
|
return this._skills;
|
|
@@ -19703,6 +19836,7 @@ function schemaEntity(s) {
|
|
|
19703
19836
|
preconditions: s.preconditions,
|
|
19704
19837
|
composedOf: s.composedOf,
|
|
19705
19838
|
baseValence: s.baseValence,
|
|
19839
|
+
description: s.description,
|
|
19706
19840
|
tags: s.tags
|
|
19707
19841
|
}
|
|
19708
19842
|
};
|
|
@@ -19721,6 +19855,7 @@ function readSchema(m) {
|
|
|
19721
19855
|
preconditions: meta["preconditions"],
|
|
19722
19856
|
composedOf: Array.isArray(meta["composedOf"]) ? meta["composedOf"] : void 0,
|
|
19723
19857
|
baseValence: typeof meta["baseValence"] === "number" ? meta["baseValence"] : void 0,
|
|
19858
|
+
description: typeof meta["description"] === "string" ? meta["description"] : void 0,
|
|
19724
19859
|
tags: Array.isArray(meta["tags"]) ? meta["tags"] : void 0
|
|
19725
19860
|
};
|
|
19726
19861
|
}
|
|
@@ -21821,7 +21956,7 @@ var ProactiveCommunicator = class {
|
|
|
21821
21956
|
}
|
|
21822
21957
|
};
|
|
21823
21958
|
}
|
|
21824
|
-
async _handleOutboundMessage(
|
|
21959
|
+
async _handleOutboundMessage(effectorName2, request, commands) {
|
|
21825
21960
|
const targetEntityId = request.targetEntityId ?? request.parameters?.targetEntityId;
|
|
21826
21961
|
const targetEntityName = request.parameters?.targetEntityName ?? targetEntityId ?? "them";
|
|
21827
21962
|
const rawMessages = request.parameters?.messages;
|
|
@@ -21829,7 +21964,7 @@ var ProactiveCommunicator = class {
|
|
|
21829
21964
|
if (!targetEntityId) {
|
|
21830
21965
|
return {
|
|
21831
21966
|
success: false,
|
|
21832
|
-
description: `You want to ${
|
|
21967
|
+
description: `You want to ${effectorName2} but there is no one specific to reach out to.`,
|
|
21833
21968
|
commands,
|
|
21834
21969
|
feedback: {
|
|
21835
21970
|
outcomeQuality: 0,
|
|
@@ -21841,7 +21976,7 @@ var ProactiveCommunicator = class {
|
|
|
21841
21976
|
if (bubbles.length === 0) {
|
|
21842
21977
|
return {
|
|
21843
21978
|
success: false,
|
|
21844
|
-
description: `You wanted to ${
|
|
21979
|
+
description: `You wanted to ${effectorName2} ${targetEntityName} but didn't write anything.`,
|
|
21845
21980
|
commands,
|
|
21846
21981
|
feedback: { outcomeQuality: 0, surprise: 0.1, lessons: ["Provide a messages array with the actual words."] }
|
|
21847
21982
|
};
|
|
@@ -21852,12 +21987,12 @@ var ProactiveCommunicator = class {
|
|
|
21852
21987
|
const isAck = request.parameters?.isAck ?? false;
|
|
21853
21988
|
const outboxMessageIds = [];
|
|
21854
21989
|
bubbles.forEach((bubble, i) => {
|
|
21855
|
-
logger.info(`[communication] pushing to outbox: ${
|
|
21990
|
+
logger.info(`[communication] pushing to outbox: ${effectorName2} \u2192 ${targetEntityId} "${bubble.slice(0, 80)}"`);
|
|
21856
21991
|
outboxMessageIds.push(this._writer.enqueue({
|
|
21857
21992
|
targetEntityId,
|
|
21858
21993
|
targetEntityName,
|
|
21859
21994
|
content: bubble,
|
|
21860
|
-
effectorName,
|
|
21995
|
+
effectorName: effectorName2,
|
|
21861
21996
|
replyToMessageId
|
|
21862
21997
|
}, `-${i}`));
|
|
21863
21998
|
});
|
|
@@ -21872,7 +22007,7 @@ var ProactiveCommunicator = class {
|
|
|
21872
22007
|
targetEntityName,
|
|
21873
22008
|
messageCount: bubbles.length,
|
|
21874
22009
|
preview: bubbles[0]?.slice(0, 100) ?? "",
|
|
21875
|
-
effectorName,
|
|
22010
|
+
effectorName: effectorName2,
|
|
21876
22011
|
tick: deliveryTick,
|
|
21877
22012
|
delivered: false,
|
|
21878
22013
|
isAck,
|
|
@@ -21950,28 +22085,40 @@ var InstructionIntake = class {
|
|
|
21950
22085
|
|
|
21951
22086
|
// src/cognition/agency/schemas/external.ts
|
|
21952
22087
|
var DEFAULT_EXTERNAL_COST = 0.15;
|
|
22088
|
+
var clamp = (n, lo, hi) => n < lo ? lo : n > hi ? hi : n;
|
|
21953
22089
|
function externalSchemas(effectors) {
|
|
21954
22090
|
const seen = /* @__PURE__ */ new Set();
|
|
21955
22091
|
const out = [];
|
|
21956
|
-
for (const
|
|
22092
|
+
for (const decl of effectors ?? []) {
|
|
22093
|
+
const name = typeof decl === "string" ? decl : decl?.name;
|
|
21957
22094
|
if (typeof name !== "string" || name.length === 0) continue;
|
|
21958
22095
|
if (EXPLICIT_EFFECTORS.has(name)) continue;
|
|
21959
22096
|
if (INNATE_SCHEMA_BY_ID.has(name)) continue;
|
|
21960
22097
|
if (seen.has(name)) continue;
|
|
21961
22098
|
seen.add(name);
|
|
22099
|
+
const meta = typeof decl === "string" ? null : decl;
|
|
22100
|
+
const binds = meta?.binds === "entity" ? "entity" : meta?.binds === "object" ? "object" : "none";
|
|
22101
|
+
const tags = [.../* @__PURE__ */ new Set([...meta?.tags ?? [], "external", "host"])];
|
|
21962
22102
|
out.push({
|
|
21963
22103
|
id: name,
|
|
21964
22104
|
kind: "primitive",
|
|
21965
22105
|
source: "external",
|
|
21966
|
-
cost: DEFAULT_EXTERNAL_COST,
|
|
21967
|
-
binds
|
|
21968
|
-
baseValence: 0,
|
|
21969
|
-
|
|
22106
|
+
cost: typeof meta?.cost === "number" ? clamp(meta.cost, 0, 1) : DEFAULT_EXTERNAL_COST,
|
|
22107
|
+
binds,
|
|
22108
|
+
baseValence: typeof meta?.valence === "number" ? clamp(meta.valence, -1, 1) : 0,
|
|
22109
|
+
...meta?.preconditions ? { preconditions: meta.preconditions } : {},
|
|
22110
|
+
...meta?.description ? { description: meta.description } : {},
|
|
22111
|
+
tags
|
|
21970
22112
|
});
|
|
21971
22113
|
}
|
|
21972
22114
|
return out;
|
|
21973
22115
|
}
|
|
21974
22116
|
|
|
22117
|
+
// src/cognition/agency/types.ts
|
|
22118
|
+
function effectorName(d) {
|
|
22119
|
+
return typeof d === "string" ? d : d.name;
|
|
22120
|
+
}
|
|
22121
|
+
|
|
21975
22122
|
// src/cognition/config.mirror.entities.ts
|
|
21976
22123
|
function buildEngineConfigEntities(config, executiveInterval) {
|
|
21977
22124
|
const selfBelonging = parseFloat(process.env.WILL_SELF_BELONGING ?? "0.35");
|
|
@@ -22529,7 +22676,7 @@ function assembleMind(willId, config) {
|
|
|
22529
22676
|
const profile = config.profile ? resolveProfile(config.profile) : void 0;
|
|
22530
22677
|
const idGuard = validateWillIdentity({
|
|
22531
22678
|
identity: config.identity,
|
|
22532
|
-
effectors: Array.isArray(config.allowedGenericEffectors) ? config.allowedGenericEffectors : profile?.effectors ?? null,
|
|
22679
|
+
effectors: (Array.isArray(config.allowedGenericEffectors) ? config.allowedGenericEffectors : profile?.effectors ?? null)?.map(effectorName) ?? null,
|
|
22533
22680
|
profileContext: profile?.context
|
|
22534
22681
|
});
|
|
22535
22682
|
if (!idGuard.ok)
|
|
@@ -22609,7 +22756,8 @@ function _constructCognition({ simulation, willId, config, randomSeed, executive
|
|
|
22609
22756
|
dreamSimulator.attachConsolidator(episodicConsolidator);
|
|
22610
22757
|
const goalManager = new GoalManager();
|
|
22611
22758
|
const resolvedEffectors = Array.isArray(config.allowedGenericEffectors) ? config.allowedGenericEffectors : profile?.effectors ?? null;
|
|
22612
|
-
const
|
|
22759
|
+
const resolvedEffectorNames = resolvedEffectors?.map(effectorName) ?? null;
|
|
22760
|
+
const accessGrants = new AccessGrants(resolvedEffectorNames);
|
|
22613
22761
|
const executiveEngine = new ExecutiveEngine({ executiveInterval, cooldownTicks: 5 });
|
|
22614
22762
|
executiveEngine.willId = willId;
|
|
22615
22763
|
executiveEngine.modelId = resolveModelId(
|
|
@@ -24718,6 +24866,7 @@ var effectorController = class {
|
|
|
24718
24866
|
parameters: payload.parameters ?? {},
|
|
24719
24867
|
targetEntityId: payload.targetEntityId,
|
|
24720
24868
|
reasoning: payload.reasoning ?? "",
|
|
24869
|
+
...typeof payload.description === "string" ? { description: payload.description } : {},
|
|
24721
24870
|
tick: payload.tick ?? 0,
|
|
24722
24871
|
timestamp: Date.now()
|
|
24723
24872
|
});
|
|
@@ -25561,6 +25710,19 @@ var WillStem = class {
|
|
|
25561
25710
|
setAllowedEffectors(id, effectors) {
|
|
25562
25711
|
this._effector.setAllowed(this._get(id), effectors);
|
|
25563
25712
|
}
|
|
25713
|
+
/**
|
|
25714
|
+
* Register a host effector on a *running* Will (post-create `.effector()`).
|
|
25715
|
+
* Builds its external schema and adds it to the live repertoire so the Will
|
|
25716
|
+
* can actually perceive + enact it — a grant alone only gates; without the
|
|
25717
|
+
* schema the ability could never be afforded. Comms names are no-ops here
|
|
25718
|
+
* (governed by AccessGrants). This is a runtime mutation, like a grant change;
|
|
25719
|
+
* the deterministic/replayable path is declaring effectors at create time.
|
|
25720
|
+
*/
|
|
25721
|
+
registerEffector(id, declaration) {
|
|
25722
|
+
const repertoire = this._get(id).cognition.schemaRepertoire;
|
|
25723
|
+
for (const schema of externalSchemas([declaration]))
|
|
25724
|
+
repertoire.registerExternal(schema);
|
|
25725
|
+
}
|
|
25564
25726
|
/**
|
|
25565
25727
|
* Called by the host/WorldInterface after executing a host-owned effector.
|
|
25566
25728
|
* `invocationId` is the correlation handle the host echoed (the awaiting
|
|
@@ -26015,6 +26177,7 @@ var SocketIoTransport = class {
|
|
|
26015
26177
|
};
|
|
26016
26178
|
|
|
26017
26179
|
// src/sdk/will.ts
|
|
26180
|
+
var AFFECT_EPSILON = 0.02;
|
|
26018
26181
|
var Will = class _Will {
|
|
26019
26182
|
/** The underlying WillStem — drop here for the full contract. */
|
|
26020
26183
|
stem;
|
|
@@ -26022,9 +26185,15 @@ var Will = class _Will {
|
|
|
26022
26185
|
id;
|
|
26023
26186
|
name;
|
|
26024
26187
|
_effectors = /* @__PURE__ */ new Map();
|
|
26188
|
+
/** Rich declarations for create-time effectors → seed the affordance repertoire. */
|
|
26189
|
+
_effectorDecls = /* @__PURE__ */ new Map();
|
|
26025
26190
|
_messageHandlers = /* @__PURE__ */ new Set();
|
|
26026
26191
|
_stateHandlers = /* @__PURE__ */ new Set();
|
|
26192
|
+
_effectorHandlers = /* @__PURE__ */ new Set();
|
|
26193
|
+
_emotionHandlers = /* @__PURE__ */ new Set();
|
|
26027
26194
|
_errorHandlers = /* @__PURE__ */ new Set();
|
|
26195
|
+
_utteranceWaiters = /* @__PURE__ */ new Set();
|
|
26196
|
+
_lastAffect = null;
|
|
26028
26197
|
_unsub = null;
|
|
26029
26198
|
constructor(stem, id, name) {
|
|
26030
26199
|
this.stem = stem;
|
|
@@ -26036,8 +26205,8 @@ var Will = class _Will {
|
|
|
26036
26205
|
const id = opts.id ?? `${slug(opts.name)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
26037
26206
|
const stem = new WillStem();
|
|
26038
26207
|
const will = new _Will(stem, id, opts.name);
|
|
26039
|
-
for (const [name,
|
|
26040
|
-
will.
|
|
26208
|
+
for (const [name, entry] of Object.entries(opts.effectors ?? {}))
|
|
26209
|
+
will._register(name, entry);
|
|
26041
26210
|
await stem.createWill(will._buildConfig(id, opts));
|
|
26042
26211
|
will._attach();
|
|
26043
26212
|
return will;
|
|
@@ -26051,8 +26220,8 @@ var Will = class _Will {
|
|
|
26051
26220
|
const id = opts.id ?? `${slug(opts.name)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
26052
26221
|
const stem = new WillStem();
|
|
26053
26222
|
const will = new _Will(stem, id, opts.name);
|
|
26054
|
-
for (const [name,
|
|
26055
|
-
will.
|
|
26223
|
+
for (const [name, entry] of Object.entries(opts.effectors ?? {}))
|
|
26224
|
+
will._register(name, entry);
|
|
26056
26225
|
await stem.createWill(
|
|
26057
26226
|
will._buildConfig(id, { ...opts, identity: { prompt: "", ...opts.identity } }),
|
|
26058
26227
|
true
|
|
@@ -26062,36 +26231,92 @@ var Will = class _Will {
|
|
|
26062
26231
|
will._attach();
|
|
26063
26232
|
return will;
|
|
26064
26233
|
}
|
|
26065
|
-
// ──
|
|
26234
|
+
// ── Perceiving ─────────────────────────────────────────────
|
|
26066
26235
|
/**
|
|
26067
|
-
*
|
|
26068
|
-
*
|
|
26236
|
+
* Deliver a stimulus into the Will's sensory field. This is the one true
|
|
26237
|
+
* intake — `say`/`tell` are sugar over it. It returns once the stimulus is
|
|
26238
|
+
* *delivered*, NOT once the Will has responded: a response (if any) is a
|
|
26239
|
+
* projection that arrives later on the `message` event, or via
|
|
26240
|
+
* `nextUtterance()`. The Will may also stay silent — that is not an error.
|
|
26069
26241
|
*/
|
|
26242
|
+
async perceive(stimulus) {
|
|
26243
|
+
const from = stimulus.from ?? "user";
|
|
26244
|
+
await this.stem.ingestText(this.id, {
|
|
26245
|
+
kind: "text",
|
|
26246
|
+
entityId: from,
|
|
26247
|
+
threadId: stimulus.thread ?? from,
|
|
26248
|
+
content: stimulus.text,
|
|
26249
|
+
speakerName: stimulus.speaker ?? (from === "user" ? "You" : from)
|
|
26250
|
+
});
|
|
26251
|
+
}
|
|
26252
|
+
/** Perceive from the default user. Sugar over `perceive`. */
|
|
26070
26253
|
async say(text) {
|
|
26071
|
-
return this.
|
|
26254
|
+
return this.perceive({ text, from: "user", speaker: "You" });
|
|
26072
26255
|
}
|
|
26073
|
-
/**
|
|
26256
|
+
/** Perceive from a specific interlocutor (multi-party). Sugar over `perceive`. */
|
|
26074
26257
|
async tell(entityId, speakerName, text) {
|
|
26075
|
-
|
|
26076
|
-
|
|
26077
|
-
|
|
26078
|
-
|
|
26079
|
-
|
|
26080
|
-
|
|
26258
|
+
return this.perceive({ text, from: entityId, speaker: speakerName });
|
|
26259
|
+
}
|
|
26260
|
+
/**
|
|
26261
|
+
* Await the Will's *next spontaneous utterance* — a thin, honest adapter over
|
|
26262
|
+
* the `message` projection stream for request/response callers. Resolves with
|
|
26263
|
+
* the message, or `null` if the Will stays silent within `within` ms (default
|
|
26264
|
+
* 5000). `null` is a real outcome — the Will chose not to speak — not a
|
|
26265
|
+
* failure. Pass `to` to only accept an utterance addressed to that entity.
|
|
26266
|
+
*
|
|
26267
|
+
* await will.perceive( { from: 'ada', text: 'Hi!' } )
|
|
26268
|
+
* const reply = await will.nextUtterance( { to: 'ada', within: 3000 } )
|
|
26269
|
+
* // reply is a WillMessage, or null if Ada got the silent treatment.
|
|
26270
|
+
*/
|
|
26271
|
+
nextUtterance(opts = {}) {
|
|
26272
|
+
return new Promise((resolve) => {
|
|
26273
|
+
const timer = setTimeout(() => {
|
|
26274
|
+
this._utteranceWaiters.delete(waiter);
|
|
26275
|
+
resolve(null);
|
|
26276
|
+
}, opts.within ?? 5e3);
|
|
26277
|
+
timer.unref?.();
|
|
26278
|
+
const waiter = { to: opts.to, resolve, timer };
|
|
26279
|
+
this._utteranceWaiters.add(waiter);
|
|
26081
26280
|
});
|
|
26082
26281
|
}
|
|
26083
26282
|
// ── Abilities ──────────────────────────────────────────────
|
|
26084
26283
|
/**
|
|
26085
|
-
* Register an ability the Will can choose to enact
|
|
26086
|
-
*
|
|
26087
|
-
*
|
|
26088
|
-
*
|
|
26089
|
-
|
|
26090
|
-
|
|
26091
|
-
|
|
26284
|
+
* Register an ability the Will can choose to enact, at runtime. `entry` is a
|
|
26285
|
+
* bare handler or a full spec (`{ handler, description?, cost?, valence?,
|
|
26286
|
+
* preconditions?, binds?, tags? }`). When the Will decides to use `name`, your
|
|
26287
|
+
* handler runs with the arguments it chose; the return value feeds back as the
|
|
26288
|
+
* outcome (the reafference loop that lets the Will learn the ability).
|
|
26289
|
+
*
|
|
26290
|
+
* The ability's schema is added to the live repertoire so it can actually be
|
|
26291
|
+
* *afforded* immediately (a grant alone only gates), then granted. Note: this
|
|
26292
|
+
* is a runtime mutation — the deterministic/replayable path is declaring
|
|
26293
|
+
* effectors in `create()`'s `effectors` map.
|
|
26294
|
+
*/
|
|
26295
|
+
effector(name, entry) {
|
|
26296
|
+
this._register(name, entry);
|
|
26297
|
+
this.stem.registerEffector(this.id, this._effectorDecls.get(name));
|
|
26092
26298
|
this.stem.setAllowedEffectors(this.id, [...COMMUNICATION, ...this._effectors.keys()]);
|
|
26093
26299
|
return this;
|
|
26094
26300
|
}
|
|
26301
|
+
/** Split an effectors-map entry into a handler + an EffectorDeclaration. */
|
|
26302
|
+
_register(name, entry) {
|
|
26303
|
+
if (typeof entry === "function") {
|
|
26304
|
+
this._effectors.set(name, entry);
|
|
26305
|
+
this._effectorDecls.set(name, name);
|
|
26306
|
+
return;
|
|
26307
|
+
}
|
|
26308
|
+
this._effectors.set(name, entry.handler);
|
|
26309
|
+
const hasMeta = entry.description !== void 0 || entry.cost !== void 0 || entry.valence !== void 0 || entry.preconditions !== void 0 || entry.binds !== void 0 || entry.tags !== void 0;
|
|
26310
|
+
this._effectorDecls.set(name, hasMeta ? {
|
|
26311
|
+
name,
|
|
26312
|
+
...entry.description !== void 0 ? { description: entry.description } : {},
|
|
26313
|
+
...entry.cost !== void 0 ? { cost: entry.cost } : {},
|
|
26314
|
+
...entry.valence !== void 0 ? { valence: entry.valence } : {},
|
|
26315
|
+
...entry.preconditions !== void 0 ? { preconditions: entry.preconditions } : {},
|
|
26316
|
+
...entry.binds !== void 0 ? { binds: entry.binds } : {},
|
|
26317
|
+
...entry.tags !== void 0 ? { tags: entry.tags } : {}
|
|
26318
|
+
} : name);
|
|
26319
|
+
}
|
|
26095
26320
|
// ── Introspection ──────────────────────────────────────────
|
|
26096
26321
|
/** A compact snapshot of the mind's current inner state. */
|
|
26097
26322
|
state() {
|
|
@@ -26114,9 +26339,22 @@ var Will = class _Will {
|
|
|
26114
26339
|
};
|
|
26115
26340
|
}
|
|
26116
26341
|
on(event, handler) {
|
|
26117
|
-
|
|
26118
|
-
|
|
26119
|
-
|
|
26342
|
+
switch (event) {
|
|
26343
|
+
case "message":
|
|
26344
|
+
this._messageHandlers.add(handler);
|
|
26345
|
+
break;
|
|
26346
|
+
case "state":
|
|
26347
|
+
this._stateHandlers.add(handler);
|
|
26348
|
+
break;
|
|
26349
|
+
case "effector":
|
|
26350
|
+
this._effectorHandlers.add(handler);
|
|
26351
|
+
break;
|
|
26352
|
+
case "emotion":
|
|
26353
|
+
this._emotionHandlers.add(handler);
|
|
26354
|
+
break;
|
|
26355
|
+
default:
|
|
26356
|
+
this._errorHandlers.add(handler);
|
|
26357
|
+
}
|
|
26120
26358
|
return this;
|
|
26121
26359
|
}
|
|
26122
26360
|
// ── Lifecycle ──────────────────────────────────────────────
|
|
@@ -26127,9 +26365,18 @@ var Will = class _Will {
|
|
|
26127
26365
|
this.stem.resumeWill(this.id);
|
|
26128
26366
|
}
|
|
26129
26367
|
/**
|
|
26130
|
-
*
|
|
26131
|
-
*
|
|
26132
|
-
*
|
|
26368
|
+
* Checkpoint the living mind into a portable PMA artifact — NON-destructive.
|
|
26369
|
+
* The Will keeps ticking; the snapshot is a point-in-time copy you can archive
|
|
26370
|
+
* or wake elsewhere. Use this for periodic saves; use `hibernate()` to sleep.
|
|
26371
|
+
*/
|
|
26372
|
+
async save() {
|
|
26373
|
+
return this.stem.distillPMA(this.id);
|
|
26374
|
+
}
|
|
26375
|
+
/**
|
|
26376
|
+
* Distil the mind into a portable PMA artifact and archive it — DESTRUCTIVE:
|
|
26377
|
+
* the tick loop stops (the Will sleeps). The returned snapshot restores the
|
|
26378
|
+
* same self via `Will.wake()` — across a restart, a fork, or a machine
|
|
26379
|
+
* boundary. For a copy that leaves the Will running, use `save()`.
|
|
26133
26380
|
*/
|
|
26134
26381
|
async hibernate() {
|
|
26135
26382
|
const pma = this.stem.distillPMA(this.id);
|
|
@@ -26138,6 +26385,11 @@ var Will = class _Will {
|
|
|
26138
26385
|
}
|
|
26139
26386
|
/** Tear the Will down (its tick loop stops; state is discarded unless persisted). */
|
|
26140
26387
|
async stop() {
|
|
26388
|
+
for (const w of this._utteranceWaiters) {
|
|
26389
|
+
clearTimeout(w.timer);
|
|
26390
|
+
w.resolve(null);
|
|
26391
|
+
}
|
|
26392
|
+
this._utteranceWaiters.clear();
|
|
26141
26393
|
this._unsub?.();
|
|
26142
26394
|
this._unsub = null;
|
|
26143
26395
|
await this.stem.archiveWill(this.id);
|
|
@@ -26160,7 +26412,7 @@ var Will = class _Will {
|
|
|
26160
26412
|
persistentMemory: opts.persist ?? false,
|
|
26161
26413
|
snapshotInterval: 100,
|
|
26162
26414
|
tickIntervalMs: opts.tickMs ?? 1e3,
|
|
26163
|
-
allowedGenericEffectors: [...COMMUNICATION, ...this.
|
|
26415
|
+
allowedGenericEffectors: [...COMMUNICATION, ...this._effectorDecls.values()],
|
|
26164
26416
|
initialGoals: opts.initialGoals ?? [],
|
|
26165
26417
|
...opts.seed !== void 0 ? { randomSeed: opts.seed, clock: { fixedDeltaMs: 1e3, startTime: 0 } } : {}
|
|
26166
26418
|
};
|
|
@@ -26175,13 +26427,20 @@ var Will = class _Will {
|
|
|
26175
26427
|
} catch {
|
|
26176
26428
|
}
|
|
26177
26429
|
}
|
|
26178
|
-
for (const inv of invocations)
|
|
26430
|
+
for (const inv of invocations) {
|
|
26431
|
+
this._emitEffectorAct({ name: inv.effectorName, args: inv.parameters, reasoning: inv.reasoning, to: inv.targetEntityId });
|
|
26179
26432
|
void this._runEffector(inv);
|
|
26180
|
-
|
|
26181
|
-
|
|
26182
|
-
|
|
26183
|
-
|
|
26184
|
-
|
|
26433
|
+
}
|
|
26434
|
+
if (this._stateHandlers.size > 0 || this._emotionHandlers.size > 0) {
|
|
26435
|
+
try {
|
|
26436
|
+
const s = this.state();
|
|
26437
|
+
for (const h of this._stateHandlers) try {
|
|
26438
|
+
h(s);
|
|
26439
|
+
} catch {
|
|
26440
|
+
}
|
|
26441
|
+
if (this._emotionHandlers.size > 0) this._maybeEmitAffect(s.metrics.valence, s.metrics.arousal);
|
|
26442
|
+
} catch (e) {
|
|
26443
|
+
this._emitError(e);
|
|
26185
26444
|
}
|
|
26186
26445
|
}
|
|
26187
26446
|
}) ?? null;
|
|
@@ -26196,7 +26455,11 @@ var Will = class _Will {
|
|
|
26196
26455
|
return;
|
|
26197
26456
|
}
|
|
26198
26457
|
try {
|
|
26199
|
-
const raw = await handler(inv.parameters, {
|
|
26458
|
+
const raw = await handler(inv.parameters, {
|
|
26459
|
+
reasoning: inv.reasoning,
|
|
26460
|
+
targetEntityId: inv.targetEntityId,
|
|
26461
|
+
...inv.description ? { description: inv.description } : {}
|
|
26462
|
+
});
|
|
26200
26463
|
const result = typeof raw === "string" ? { success: true, description: raw } : raw;
|
|
26201
26464
|
this.stem.confirmEffectorExecution(this.id, inv.decisionRecordId, result);
|
|
26202
26465
|
} catch (err) {
|
|
@@ -26213,6 +26476,31 @@ var Will = class _Will {
|
|
|
26213
26476
|
} catch (e) {
|
|
26214
26477
|
this._emitError(e);
|
|
26215
26478
|
}
|
|
26479
|
+
if (this._utteranceWaiters.size > 0) {
|
|
26480
|
+
for (const w of [...this._utteranceWaiters]) {
|
|
26481
|
+
if (w.to !== void 0 && w.to !== m.to) continue;
|
|
26482
|
+
clearTimeout(w.timer);
|
|
26483
|
+
this._utteranceWaiters.delete(w);
|
|
26484
|
+
w.resolve(m);
|
|
26485
|
+
}
|
|
26486
|
+
}
|
|
26487
|
+
}
|
|
26488
|
+
_emitEffectorAct(a) {
|
|
26489
|
+
for (const h of this._effectorHandlers) try {
|
|
26490
|
+
h(a);
|
|
26491
|
+
} catch (e) {
|
|
26492
|
+
this._emitError(e);
|
|
26493
|
+
}
|
|
26494
|
+
}
|
|
26495
|
+
_maybeEmitAffect(valence, arousal) {
|
|
26496
|
+
const last = this._lastAffect;
|
|
26497
|
+
if (last && Math.abs(last.valence - valence) < AFFECT_EPSILON && Math.abs(last.arousal - arousal) < AFFECT_EPSILON) return;
|
|
26498
|
+
this._lastAffect = { valence, arousal };
|
|
26499
|
+
for (const h of this._emotionHandlers) try {
|
|
26500
|
+
h({ valence, arousal });
|
|
26501
|
+
} catch (e) {
|
|
26502
|
+
this._emitError(e);
|
|
26503
|
+
}
|
|
26216
26504
|
}
|
|
26217
26505
|
_emitError(e) {
|
|
26218
26506
|
for (const h of this._errorHandlers) try {
|