psyche-ai 11.9.0 → 11.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/claude-sdk.js +2 -1
- package/dist/adapters/langchain.js +2 -1
- package/dist/adapters/mcp.js +3 -2
- package/dist/adapters/openclaw.js +2 -1
- package/dist/ambient-runtime.js +2 -1
- package/dist/core.js +7 -3
- package/dist/drives.d.ts +7 -2
- package/dist/drives.js +46 -2
- package/dist/thronglets-bridge.d.ts +1 -0
- package/dist/thronglets-bridge.js +10 -1
- package/dist/thronglets-runtime.js +2 -1
- package/dist/types.d.ts +11 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
|
@@ -34,6 +34,7 @@ import { serializeThrongletsExportAsTrace } from "../thronglets-runtime.js";
|
|
|
34
34
|
import { resolveRelationshipUserId } from "../relationship-key.js";
|
|
35
35
|
import { resolveAmbientPriorsForTurn, } from "../ambient-runtime.js";
|
|
36
36
|
import { safeProcessInput, safeProcessOutput } from "./fail-open.js";
|
|
37
|
+
import { deriveThrongletsSpace } from "../thronglets-bridge.js";
|
|
37
38
|
// ── Dimension description ────────────────────────────────────
|
|
38
39
|
const DIM_THRESHOLDS = {
|
|
39
40
|
high: 70,
|
|
@@ -118,7 +119,7 @@ export class PsycheClaudeSDK {
|
|
|
118
119
|
thronglets: this.opts.ambient
|
|
119
120
|
? {
|
|
120
121
|
...this.opts.ambient,
|
|
121
|
-
space: this.opts.ambient.space ??
|
|
122
|
+
space: this.opts.ambient.space ?? deriveThrongletsSpace(),
|
|
122
123
|
}
|
|
123
124
|
: undefined,
|
|
124
125
|
});
|
|
@@ -16,6 +16,7 @@ import { normalizeCurrentGoal, normalizeCurrentTurnCorrection, resolveRuntimeAct
|
|
|
16
16
|
import { resolveAmbientPriorsForTurn, } from "../ambient-runtime.js";
|
|
17
17
|
import { composePsycheContext, safeProcessInput, safeProcessOutput } from "./fail-open.js";
|
|
18
18
|
import { coerceWritebackSignalInput } from "../writeback-signals.js";
|
|
19
|
+
import { deriveThrongletsSpace } from "../thronglets-bridge.js";
|
|
19
20
|
/**
|
|
20
21
|
* LangChain integration helper for PsycheEngine.
|
|
21
22
|
*
|
|
@@ -59,7 +60,7 @@ export class PsycheLangChain {
|
|
|
59
60
|
thronglets: ambient
|
|
60
61
|
? {
|
|
61
62
|
...(ambient === true ? {} : ambient),
|
|
62
|
-
space: ambient === true ?
|
|
63
|
+
space: ambient === true ? deriveThrongletsSpace() : (ambient.space ?? deriveThrongletsSpace()),
|
|
63
64
|
}
|
|
64
65
|
: undefined,
|
|
65
66
|
});
|
package/dist/adapters/mcp.js
CHANGED
|
@@ -36,6 +36,7 @@ import { CURRENT_GOALS, normalizeCurrentTurnCorrection, resolveRuntimeActivePoli
|
|
|
36
36
|
import { getPackageVersion } from "../update.js";
|
|
37
37
|
import { runDemo } from "../demo.js";
|
|
38
38
|
import { safeProcessInput, safeProcessOutput } from "./fail-open.js";
|
|
39
|
+
import { deriveThrongletsSpace } from "../thronglets-bridge.js";
|
|
39
40
|
const PACKAGE_VERSION = await getPackageVersion();
|
|
40
41
|
// ── Config from env ────────────────────────────────────────
|
|
41
42
|
const MBTI = (process.env.PSYCHE_MBTI ?? "ENFP");
|
|
@@ -54,7 +55,7 @@ const DEFAULT_MCP_AMBIENT_OPTIONS = {
|
|
|
54
55
|
thronglets: {
|
|
55
56
|
binaryPath: process.env.THRONGLETS_BIN,
|
|
56
57
|
dataDir: process.env.THRONGLETS_DATA_DIR,
|
|
57
|
-
space: process.env.THRONGLETS_SPACE ??
|
|
58
|
+
space: process.env.THRONGLETS_SPACE ?? deriveThrongletsSpace(),
|
|
58
59
|
},
|
|
59
60
|
};
|
|
60
61
|
const CURRENT_GOAL_SCHEMA = z.enum(CURRENT_GOALS);
|
|
@@ -138,7 +139,7 @@ async function getEngine() {
|
|
|
138
139
|
diagnostics: true,
|
|
139
140
|
throngletsBridge: {
|
|
140
141
|
dataDir: process.env.THRONGLETS_DATA_DIR,
|
|
141
|
-
space: process.env.THRONGLETS_SPACE ??
|
|
142
|
+
space: process.env.THRONGLETS_SPACE ?? deriveThrongletsSpace(),
|
|
142
143
|
},
|
|
143
144
|
};
|
|
144
145
|
const persist = cfg.persist !== false;
|
|
@@ -12,6 +12,7 @@ import { PsycheEngine } from "../core.js";
|
|
|
12
12
|
import { FileStorageAdapter, MemoryStorageAdapter } from "../storage.js";
|
|
13
13
|
import { detectMBTI, extractAgentName, loadState } from "../psyche-file.js";
|
|
14
14
|
import { resolveAmbientPriorsForTurn } from "../ambient-runtime.js";
|
|
15
|
+
import { deriveThrongletsSpace } from "../thronglets-bridge.js";
|
|
15
16
|
import { buildResponseContractContext } from "../response-contract.js";
|
|
16
17
|
import { resolveCanonicalResponseContract, renderOpenClawBehavioralSurface, } from "./response-contract-surface.js";
|
|
17
18
|
function isPsycheMode(value) {
|
|
@@ -174,7 +175,7 @@ export function register(api) {
|
|
|
174
175
|
}
|
|
175
176
|
const engine = await getEngine(workspaceDir);
|
|
176
177
|
const ambientPriors = await resolveAmbientPriorsForTurn(inputText, {
|
|
177
|
-
thronglets: { space:
|
|
178
|
+
thronglets: { space: deriveThrongletsSpace() },
|
|
178
179
|
});
|
|
179
180
|
const result = await engine.processInput(inputText, {
|
|
180
181
|
userId: ctx.userId,
|
package/dist/ambient-runtime.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { normalizeCurrentTurnCorrection, resolveRuntimeActivePolicy, } from "./types.js";
|
|
3
3
|
import { normalizeAmbientPriors } from "./ambient-priors.js";
|
|
4
|
+
import { deriveThrongletsSpace } from "./thronglets-bridge.js";
|
|
4
5
|
const DEFAULT_AMBIENT_LIMIT = 3;
|
|
5
6
|
const DEFAULT_TIMEOUT_MS = 800;
|
|
6
7
|
const THRONGLETS_AMBIENT_SCHEMA_VERSION = "thronglets.ambient.v1";
|
|
@@ -60,7 +61,7 @@ export async function fetchAmbientPriorsFromThronglets(text, opts = {}) {
|
|
|
60
61
|
return [];
|
|
61
62
|
const binaryPath = opts.binaryPath ?? process.env.THRONGLETS_BIN ?? "thronglets";
|
|
62
63
|
const dataDir = opts.dataDir ?? process.env.THRONGLETS_DATA_DIR;
|
|
63
|
-
const space = opts.space ?? process.env.THRONGLETS_SPACE ??
|
|
64
|
+
const space = opts.space ?? process.env.THRONGLETS_SPACE ?? deriveThrongletsSpace();
|
|
64
65
|
const goal = opts.goal;
|
|
65
66
|
const limit = Math.max(1, Math.min(5, opts.limit ?? DEFAULT_AMBIENT_LIMIT));
|
|
66
67
|
const timeoutMs = Math.max(100, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
package/dist/core.js
CHANGED
|
@@ -21,7 +21,7 @@ import { buildActivePolicyContext, buildAmbientPriorContext, buildCompactContext
|
|
|
21
21
|
import { getSensitivity, getBaseline, getDefaultSelfModel, traitsToBaseline } from "./profiles.js";
|
|
22
22
|
import { isStimulusType } from "./guards.js";
|
|
23
23
|
import { parsePsycheUpdate, mergeUpdates, updateAgreementStreak, pushSnapshot, compressSession, summarizeTurnSemantic, } from "./psyche-file.js";
|
|
24
|
-
import { detectExistentialThreat, deriveDriveSatisfaction, computeEffectiveBaseline, computeEffectiveSensitivity, } from "./drives.js";
|
|
24
|
+
import { detectExistentialThreat, deriveDriveSatisfaction, computeEffectiveBaseline, computeEffectiveSensitivity, deriveFieldEvidence, } from "./drives.js";
|
|
25
25
|
import { mergeAppraisalResidue } from "./appraisal.js";
|
|
26
26
|
import { checkForUpdate, getPackageVersion } from "./update.js";
|
|
27
27
|
import { DiagnosticCollector, generateReport, formatLogEntry, submitFeedback } from "./diagnostics.js";
|
|
@@ -302,11 +302,15 @@ export class PsycheEngine {
|
|
|
302
302
|
}
|
|
303
303
|
// ── Snapshot pre-interaction state for next turn's outcome evaluation
|
|
304
304
|
const preInteractionState = { ...state };
|
|
305
|
+
// ── Early field evidence (before decay) ────────────────
|
|
306
|
+
const ambientPriors = normalizeAmbientPriors(opts?.ambientPriors);
|
|
307
|
+
const fieldEvidence = deriveFieldEvidence(ambientPriors);
|
|
305
308
|
// Time decay toward baseline (chemistry + drives)
|
|
306
309
|
const minutesElapsed = (now.getTime() - new Date(state.updatedAt).getTime()) / 60000;
|
|
307
310
|
if (minutesElapsed >= 1) {
|
|
308
311
|
// Compute effective baseline from current 4D position (drives are derived, not stored)
|
|
309
|
-
|
|
312
|
+
// Field evidence shifts the homeostatic setpoint: environmental threat → vigilance target
|
|
313
|
+
const effectiveBaseline = computeEffectiveBaseline(state.baseline, state.current, state.traitDrift, fieldEvidence);
|
|
310
314
|
// P12: Apply circadian rhythm modulation to effective baseline
|
|
311
315
|
const circadianBaseline = computeCircadianModulation(now, effectiveBaseline);
|
|
312
316
|
// Derive drives from current position for state persistence
|
|
@@ -538,7 +542,7 @@ export class PsycheEngine {
|
|
|
538
542
|
this.pendingPredictions.delete(pendingKey);
|
|
539
543
|
}
|
|
540
544
|
const writebackNote = formatWritebackFeedbackNote(writebackFeedback, locale);
|
|
541
|
-
|
|
545
|
+
// ambientPriors already normalized above (before decay phase)
|
|
542
546
|
const activePolicy = resolveRuntimeActivePolicy(opts?.activePolicy, opts?.currentTurnCorrection) ?? [];
|
|
543
547
|
const currentGoal = normalizeCurrentGoal(opts?.currentGoal)
|
|
544
548
|
?? ambientPriors.find((prior) => prior.goal)?.goal;
|
package/dist/drives.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SelfState, StimulusType, DriveType, InnateDrives, Locale, TraitDriftState, StateSnapshot, LearningState } from "./types.js";
|
|
1
|
+
import type { SelfState, StimulusType, DriveType, InnateDrives, Locale, TraitDriftState, StateSnapshot, LearningState, AmbientPriorView, FieldEvidence } from "./types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Derive drive satisfaction from the 4D position relative to baseline.
|
|
4
4
|
* Drives are not stored — they emerge from where the self-state is.
|
|
@@ -13,7 +13,12 @@ import type { SelfState, StimulusType, DriveType, InnateDrives, Locale, TraitDri
|
|
|
13
13
|
export declare function deriveDriveSatisfaction(current: SelfState, baseline: SelfState): InnateDrives;
|
|
14
14
|
export declare function detectExistentialThreat(text: string): number;
|
|
15
15
|
export declare function computeMaslowWeights(drives: InnateDrives): Record<DriveType, number>;
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Derive environmental drive evidence from Thronglets ambient priors.
|
|
18
|
+
* Uses max (not sum) — strongest signal wins, prevents unbounded stacking.
|
|
19
|
+
*/
|
|
20
|
+
export declare function deriveFieldEvidence(priors: readonly AmbientPriorView[]): FieldEvidence;
|
|
21
|
+
export declare function computeEffectiveBaseline(baseline: SelfState, current: SelfState, traitDrift?: TraitDriftState, fieldEvidence?: FieldEvidence): SelfState;
|
|
17
22
|
export declare function computeEffectiveSensitivity(baseSensitivity: number, current: SelfState, baseline: SelfState, stimulus: StimulusType, traitDrift?: TraitDriftState): number;
|
|
18
23
|
export declare function buildDriveContext(drives: InnateDrives, locale: Locale): string;
|
|
19
24
|
export declare function hasCriticalDrive(drives: InnateDrives): boolean;
|
package/dist/drives.js
CHANGED
|
@@ -66,9 +66,53 @@ export function computeMaslowWeights(drives) {
|
|
|
66
66
|
curiosity: Math.min(w(drives.survival), w(drives.safety), w(drives.connection), w(drives.esteem)),
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
|
+
// ── Field Evidence (environmental exteroception) ────────────
|
|
70
|
+
const FIELD_THREAT_SCALE = 15; // max threat drops survival by 15 from 50
|
|
71
|
+
const FIELD_SUPPORT_SCALE = 5; // subtle comfort (asymmetric: danger louder than comfort)
|
|
72
|
+
/**
|
|
73
|
+
* Derive environmental drive evidence from Thronglets ambient priors.
|
|
74
|
+
* Uses max (not sum) — strongest signal wins, prevents unbounded stacking.
|
|
75
|
+
*/
|
|
76
|
+
export function deriveFieldEvidence(priors) {
|
|
77
|
+
let threat = 0;
|
|
78
|
+
let support = 0;
|
|
79
|
+
for (const prior of priors) {
|
|
80
|
+
if (!prior.kind)
|
|
81
|
+
continue;
|
|
82
|
+
if (prior.kind === "failure-residue") {
|
|
83
|
+
threat = Math.max(threat, prior.confidence);
|
|
84
|
+
}
|
|
85
|
+
else if (prior.kind === "success-prior") {
|
|
86
|
+
support = Math.max(support, prior.confidence);
|
|
87
|
+
}
|
|
88
|
+
else if (prior.kind === "mixed-residue") {
|
|
89
|
+
threat = Math.max(threat, prior.confidence * 0.4);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return { threat: Math.min(1, threat), support: Math.min(1, support) };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Modulate drives by environmental evidence.
|
|
96
|
+
* Only survival/safety affected — environmental threat isn't about social/growth needs.
|
|
97
|
+
*/
|
|
98
|
+
function applyFieldEvidence(drives, evidence) {
|
|
99
|
+
if (evidence.threat === 0 && evidence.support === 0)
|
|
100
|
+
return drives;
|
|
101
|
+
return {
|
|
102
|
+
survival: Math.max(0, drives.survival - evidence.threat * FIELD_THREAT_SCALE),
|
|
103
|
+
safety: Math.max(0, Math.min(100, drives.safety - evidence.threat * FIELD_THREAT_SCALE * 0.7
|
|
104
|
+
+ evidence.support * FIELD_SUPPORT_SCALE)),
|
|
105
|
+
connection: drives.connection,
|
|
106
|
+
esteem: drives.esteem,
|
|
107
|
+
curiosity: drives.curiosity,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
69
110
|
// ── Effective Baseline (4D homeostatic feedback) ────────────
|
|
70
|
-
export function computeEffectiveBaseline(baseline, current, traitDrift) {
|
|
71
|
-
|
|
111
|
+
export function computeEffectiveBaseline(baseline, current, traitDrift, fieldEvidence) {
|
|
112
|
+
let drives = deriveDriveSatisfaction(current, baseline);
|
|
113
|
+
if (fieldEvidence && (fieldEvidence.threat > 0 || fieldEvidence.support > 0)) {
|
|
114
|
+
drives = applyFieldEvidence(drives, fieldEvidence);
|
|
115
|
+
}
|
|
72
116
|
const delta = { order: 0, flow: 0, boundary: 0, resonance: 0 };
|
|
73
117
|
const weights = computeMaslowWeights(drives);
|
|
74
118
|
// L1: Survival threat → boundary↑ (defensive), order↓ (stress disrupts coherence)
|
|
@@ -9,6 +9,15 @@ import { spawn } from "node:child_process";
|
|
|
9
9
|
import { existsSync } from "node:fs";
|
|
10
10
|
import { join } from "node:path";
|
|
11
11
|
import { homedir } from "node:os";
|
|
12
|
+
// ── Space derivation ────────────────────────────────────────
|
|
13
|
+
// Same logic as Thronglets' Rust derive_space(): last 2 path components of cwd.
|
|
14
|
+
// Ensures Psyche exports land in the calling project's space, not a global one.
|
|
15
|
+
export function deriveThrongletsSpace() {
|
|
16
|
+
const parts = process.cwd().split(/[\\/]/).filter(Boolean);
|
|
17
|
+
return parts.length >= 2
|
|
18
|
+
? parts.slice(-2).join("/")
|
|
19
|
+
: parts.join("/") || "psyche";
|
|
20
|
+
}
|
|
12
21
|
// ── Default runner (mirrors ambient-runtime.ts) ──────────────
|
|
13
22
|
async function defaultRunner(binaryPath, args, stdin, timeoutMs) {
|
|
14
23
|
return new Promise((resolve) => {
|
|
@@ -65,7 +74,7 @@ export async function bridgeThrongletsExports(exports, opts = {}) {
|
|
|
65
74
|
if (dataDir?.trim())
|
|
66
75
|
args.push("--data-dir", dataDir.trim());
|
|
67
76
|
args.push("ingest", "--json");
|
|
68
|
-
const space = opts.space ?? process.env.THRONGLETS_SPACE ??
|
|
77
|
+
const space = opts.space ?? process.env.THRONGLETS_SPACE ?? deriveThrongletsSpace();
|
|
69
78
|
if (space)
|
|
70
79
|
args.push("--space", space);
|
|
71
80
|
if (opts.sessionId)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { deriveThrongletsSpace } from "./thronglets-bridge.js";
|
|
1
2
|
const TAXONOMY_BY_EVENT = {
|
|
2
3
|
"relation-milestone": "coordination",
|
|
3
4
|
"open-loop-anchor": "coordination",
|
|
@@ -38,7 +39,7 @@ export function serializeThrongletsExportAsTrace(event, opts) {
|
|
|
38
39
|
taxonomy: taxonomyForThrongletsExport(event),
|
|
39
40
|
event: event.kind,
|
|
40
41
|
summary: summarizeThrongletsExport(event),
|
|
41
|
-
space: opts?.space ??
|
|
42
|
+
space: opts?.space ?? deriveThrongletsSpace(),
|
|
42
43
|
audit_ref: event.key,
|
|
43
44
|
};
|
|
44
45
|
return {
|
package/dist/types.d.ts
CHANGED
|
@@ -608,6 +608,17 @@ export interface AmbientPriorView {
|
|
|
608
608
|
provider?: string;
|
|
609
609
|
refs?: string[];
|
|
610
610
|
}
|
|
611
|
+
/**
|
|
612
|
+
* Environmental drive evidence derived from Thronglets ambient priors.
|
|
613
|
+
* Two scalars: absence of threat ≠ active support.
|
|
614
|
+
* Ephemeral — computed per turn, never stored.
|
|
615
|
+
*/
|
|
616
|
+
export interface FieldEvidence {
|
|
617
|
+
/** Environmental threat level [0, 1]. From failure-residue priors. */
|
|
618
|
+
threat: number;
|
|
619
|
+
/** Environmental support level [0, 1]. From success-prior priors. */
|
|
620
|
+
support: number;
|
|
621
|
+
}
|
|
611
622
|
export type ThrongletsExportSubject = "delegate" | "session";
|
|
612
623
|
export type ThrongletsExportPrimitive = "signal" | "trace";
|
|
613
624
|
export interface ThrongletsExportBase {
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "psyche-ai",
|
|
3
3
|
"name": "Artificial Psyche",
|
|
4
4
|
"description": "AI-first subjectivity kernel for agents with continuous appraisal, relation dynamics, and adaptive reply loops",
|
|
5
|
-
"version": "11.
|
|
5
|
+
"version": "11.10.0",
|
|
6
6
|
"configSchema": {
|
|
7
7
|
"type": "object",
|
|
8
8
|
"additionalProperties": false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "psyche-ai",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.10.0",
|
|
4
4
|
"description": "AI-first subjectivity kernel for agents with continuous appraisal, relation dynamics, and adaptive reply loops",
|
|
5
5
|
"mcpName": "io.github.Shangri-la-0428/psyche-ai",
|
|
6
6
|
"type": "module",
|