psyche-ai 9.2.6 → 9.2.8
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 +89 -2
- package/dist/adapters/http.js +25 -3
- package/dist/adapters/langchain.d.ts +4 -0
- package/dist/adapters/langchain.js +28 -5
- package/dist/adapters/mcp.js +13 -4
- package/dist/adapters/openclaw.js +2 -2
- package/dist/adapters/vercel-ai.js +6 -4
- package/dist/core.d.ts +27 -9
- package/dist/core.js +145 -183
- package/dist/external-continuity.d.ts +4 -0
- package/dist/external-continuity.js +21 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +5 -1
- package/dist/input-turn.d.ts +30 -0
- package/dist/input-turn.js +164 -0
- package/dist/prompt.d.ts +13 -24
- package/dist/prompt.js +48 -81
- package/dist/psyche-file.d.ts +5 -1
- package/dist/psyche-file.js +39 -1
- package/dist/relation-dynamics.d.ts +22 -1
- package/dist/relation-dynamics.js +431 -12
- package/dist/reply-envelope.d.ts +7 -2
- package/dist/reply-envelope.js +2 -1
- package/dist/response-contract.d.ts +1 -0
- package/dist/response-contract.js +47 -16
- package/dist/thronglets-export.d.ts +10 -0
- package/dist/thronglets-export.js +200 -0
- package/dist/thronglets-runtime.d.ts +4 -0
- package/dist/thronglets-runtime.js +49 -0
- package/dist/types.d.ts +147 -0
- package/dist/types.js +3 -0
- package/llms.txt +115 -83
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Psyche — 面向智能体的 AI-first 主观性内核
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/psyche-ai)
|
|
4
|
-
[]()
|
|
5
5
|
[]()
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
@@ -23,6 +23,91 @@ Psyche 不是给模型贴一层“情绪 UI”。
|
|
|
23
23
|
- **源码仓库**: [`oasyce_psyche`](https://github.com/Shangri-la-0428/oasyce_psyche)
|
|
24
24
|
- **官网**: [psyche.oasyce.com](https://psyche.oasyce.com)
|
|
25
25
|
|
|
26
|
+
## 第一性原理
|
|
27
|
+
|
|
28
|
+
Psyche 要解决的不可压缩问题只有一个:
|
|
29
|
+
|
|
30
|
+
**互动历史必须持续改变 agent 后续的行为分布,而且这件事要足够便宜、足够稳定、足够可移植。**
|
|
31
|
+
|
|
32
|
+
因此它的本体不是:
|
|
33
|
+
|
|
34
|
+
- 情绪标签系统
|
|
35
|
+
- 陪伴产品
|
|
36
|
+
- prompt 皮肤
|
|
37
|
+
- 记忆仓库
|
|
38
|
+
|
|
39
|
+
它真正是:
|
|
40
|
+
|
|
41
|
+
- 本地主观性内核
|
|
42
|
+
- 关系动力学运行时
|
|
43
|
+
- 宿主可消费的行为控制面
|
|
44
|
+
|
|
45
|
+
更完整的战略定义见:
|
|
46
|
+
|
|
47
|
+
- [docs/PROJECT_DIRECTION.md](docs/PROJECT_DIRECTION.md)
|
|
48
|
+
- [docs/STACK_ARCHITECTURE.md](docs/STACK_ARCHITECTURE.md)
|
|
49
|
+
|
|
50
|
+
## 冻结身份蓝图
|
|
51
|
+
|
|
52
|
+
跨 Psyche / Thronglets / Oasyce Net / Oasyce Chain 的身份抽象现在冻结成 4 个对象:
|
|
53
|
+
|
|
54
|
+
1. `principal`:持续主体
|
|
55
|
+
2. `account`:资产与结算容器
|
|
56
|
+
3. `delegate`:被授权执行者
|
|
57
|
+
4. `session`:一次具体运行,永不作为经济主体
|
|
58
|
+
|
|
59
|
+
对应的四层分工是:
|
|
60
|
+
|
|
61
|
+
- `Psyche = subjective continuity substrate`
|
|
62
|
+
- `Thronglets = delegate continuity + session traces/coordination + emergent collective intelligence`
|
|
63
|
+
- `Oasyce Net = policy, operations, and resource orchestration`
|
|
64
|
+
- `Oasyce Chain = account truth, authorization truth, commitments, settlement, and public finality`
|
|
65
|
+
|
|
66
|
+
正式版本见:
|
|
67
|
+
|
|
68
|
+
- [docs/IDENTITY_MODEL.md](docs/IDENTITY_MODEL.md)
|
|
69
|
+
- [docs/STACK_ARCHITECTURE.md](docs/STACK_ARCHITECTURE.md)
|
|
70
|
+
|
|
71
|
+
## Psyche 和 Thronglets 的关系
|
|
72
|
+
|
|
73
|
+
两者不是竞争关系,也不该揉成一个系统。
|
|
74
|
+
|
|
75
|
+
- **Psyche** 负责私有主观性:关系残留、未完成张力、行为偏置、局部学习
|
|
76
|
+
- **Thronglets** 负责外部连续性:owner / device identity、签名、跨设备延续、低频可验证轨迹
|
|
77
|
+
|
|
78
|
+
一句话:
|
|
79
|
+
|
|
80
|
+
- `Psyche` 回答“我因此变成了什么”
|
|
81
|
+
- `Thronglets` 回答“这个变化属于谁、谁能验证、谁能继续承认它”
|
|
82
|
+
|
|
83
|
+
## 可分离安装
|
|
84
|
+
|
|
85
|
+
这两层默认就是可分离的,不应互相成为硬依赖。
|
|
86
|
+
|
|
87
|
+
- **只装 Psyche**:正常可用,拥有主观连续性和关系动力学;只是没有外部连续性层
|
|
88
|
+
- **只装 Thronglets**:正常可用,拥有 delegate / session 连续性与环境协作;只是没有主观连续性内核
|
|
89
|
+
- **两者都装**:Psyche 通过可选 `externalContinuity` envelope 输出稀疏、低频、可归属的 `signals / traces` 给 Thronglets
|
|
90
|
+
|
|
91
|
+
原则上:
|
|
92
|
+
|
|
93
|
+
- `Psyche` 必须 standalone 可用
|
|
94
|
+
- `Thronglets` 必须 additive,而不是 Psyche 的运行前提
|
|
95
|
+
- 两者之间只通过稀疏 `signal / trace` 接口连接
|
|
96
|
+
|
|
97
|
+
更细的分层、边界和运行流见:[docs/STACK_ARCHITECTURE.md](docs/STACK_ARCHITECTURE.md)
|
|
98
|
+
|
|
99
|
+
## 新概念准入规则
|
|
100
|
+
|
|
101
|
+
以后引入任何新概念,先尝试压进这 5 个原始容器:
|
|
102
|
+
|
|
103
|
+
1. `Relation Move`
|
|
104
|
+
2. `Dyadic Field`
|
|
105
|
+
3. `Open Loop / Residue`
|
|
106
|
+
4. `Reply Bias / Control ABI`
|
|
107
|
+
5. `Writeback / Learning`
|
|
108
|
+
|
|
109
|
+
如果一个新概念放不进这 5 个盒子,先怀疑概念本身,而不是继续加对象类型。
|
|
110
|
+
|
|
26
111
|
## 为什么它值得被看见
|
|
27
112
|
|
|
28
113
|
- **不是 persona prompt**:输入会留下持续主体偏置,不是一轮一清。
|
|
@@ -215,6 +300,8 @@ Psyche 现在更准确的目标,不是“模仿某种像人的风格”,而
|
|
|
215
300
|
|
|
216
301
|
这样做不是为了加抽象层,而是为了减少散装编排,让宿主稳定消费同一套行为 ABI。
|
|
217
302
|
|
|
303
|
+
当前主线里,`processInput()` 会直接返回 `replyEnvelope` 作为规范主接口;原有平级字段继续保留为兼容别名,避免打断现有宿主。`policyModifiers` 不再属于规范主接口,只保留为 legacy raw vector。
|
|
304
|
+
|
|
218
305
|
### 内在世界
|
|
219
306
|
|
|
220
307
|
Psyche 给 AI 一个始终运转的内在自我——不是条件触发,而是每时每刻都在:
|
|
@@ -436,7 +523,7 @@ Psyche 核心引擎永久开源(MIT)。
|
|
|
436
523
|
```bash
|
|
437
524
|
npm install
|
|
438
525
|
npm run build
|
|
439
|
-
npm test #
|
|
526
|
+
npm test # 1307 tests
|
|
440
527
|
npm run typecheck # strict mode
|
|
441
528
|
```
|
|
442
529
|
|
package/dist/adapters/http.js
CHANGED
|
@@ -7,14 +7,32 @@
|
|
|
7
7
|
// const server = createPsycheServer(engine, { port: 3210 });
|
|
8
8
|
//
|
|
9
9
|
// Endpoints:
|
|
10
|
-
// POST /process-input { text, userId? } → { systemContext, dynamicContext, stimulus,
|
|
11
|
-
// POST /process-output { text, userId? } → { cleanedText, stateChanged }
|
|
10
|
+
// POST /process-input { text, userId? } → { systemContext, dynamicContext, stimulus, replyEnvelope?, ...compat aliases, sessionBridge?, writebackFeedback?, externalContinuity?, throngletsExports?, policyContext }
|
|
11
|
+
// POST /process-output { text, userId?, signals?, signalConfidence? } → { cleanedText, stateChanged }
|
|
12
12
|
// GET /state → PsycheState
|
|
13
13
|
// GET /protocol?locale=zh → { protocol }
|
|
14
14
|
//
|
|
15
15
|
// Zero dependencies — uses node:http only.
|
|
16
16
|
// ============================================================
|
|
17
17
|
import { createServer } from "node:http";
|
|
18
|
+
const VALID_WRITEBACK_SIGNALS = new Set([
|
|
19
|
+
"trust_up",
|
|
20
|
+
"trust_down",
|
|
21
|
+
"boundary_set",
|
|
22
|
+
"boundary_soften",
|
|
23
|
+
"repair_attempt",
|
|
24
|
+
"repair_landed",
|
|
25
|
+
"closeness_invite",
|
|
26
|
+
"withdrawal_mark",
|
|
27
|
+
"self_assertion",
|
|
28
|
+
"task_recenter",
|
|
29
|
+
]);
|
|
30
|
+
function parseSignals(value) {
|
|
31
|
+
if (!Array.isArray(value))
|
|
32
|
+
return undefined;
|
|
33
|
+
const parsed = value.filter((item) => (typeof item === "string" && VALID_WRITEBACK_SIGNALS.has(item)));
|
|
34
|
+
return parsed.length > 0 ? [...new Set(parsed)] : undefined;
|
|
35
|
+
}
|
|
18
36
|
// ── Server ───────────────────────────────────────────────────
|
|
19
37
|
/**
|
|
20
38
|
* Create an HTTP server that exposes PsycheEngine via REST API.
|
|
@@ -69,7 +87,11 @@ export function createPsycheServer(engine, opts) {
|
|
|
69
87
|
// POST /process-output
|
|
70
88
|
if (req.method === "POST" && url.pathname === "/process-output") {
|
|
71
89
|
const body = await readBody(req);
|
|
72
|
-
const result = await engine.processOutput(body.text ?? "", {
|
|
90
|
+
const result = await engine.processOutput(body.text ?? "", {
|
|
91
|
+
userId: body.userId,
|
|
92
|
+
signals: parseSignals(body.signals),
|
|
93
|
+
signalConfidence: typeof body.signalConfidence === "number" ? body.signalConfidence : undefined,
|
|
94
|
+
});
|
|
73
95
|
json(res, 200, result);
|
|
74
96
|
return;
|
|
75
97
|
}
|
|
@@ -28,6 +28,8 @@ import type { PsycheEngine } from "../core.js";
|
|
|
28
28
|
export declare class PsycheLangChain {
|
|
29
29
|
private readonly engine;
|
|
30
30
|
constructor(engine: PsycheEngine);
|
|
31
|
+
private readonly validSignals;
|
|
32
|
+
private parseSignals;
|
|
31
33
|
/**
|
|
32
34
|
* Get the system message to inject into the LLM call.
|
|
33
35
|
* Combines the protocol (cacheable) and dynamic context (per-turn).
|
|
@@ -59,5 +61,7 @@ export declare class PsycheLangChain {
|
|
|
59
61
|
*/
|
|
60
62
|
processResponse(text: string, opts?: {
|
|
61
63
|
userId?: string;
|
|
64
|
+
signals?: string[];
|
|
65
|
+
signalConfidence?: number;
|
|
62
66
|
}): Promise<string>;
|
|
63
67
|
}
|
|
@@ -43,6 +43,24 @@ export class PsycheLangChain {
|
|
|
43
43
|
constructor(engine) {
|
|
44
44
|
this.engine = engine;
|
|
45
45
|
}
|
|
46
|
+
validSignals = new Set([
|
|
47
|
+
"trust_up",
|
|
48
|
+
"trust_down",
|
|
49
|
+
"boundary_set",
|
|
50
|
+
"boundary_soften",
|
|
51
|
+
"repair_attempt",
|
|
52
|
+
"repair_landed",
|
|
53
|
+
"closeness_invite",
|
|
54
|
+
"withdrawal_mark",
|
|
55
|
+
"self_assertion",
|
|
56
|
+
"task_recenter",
|
|
57
|
+
]);
|
|
58
|
+
parseSignals(signals) {
|
|
59
|
+
if (!signals)
|
|
60
|
+
return undefined;
|
|
61
|
+
const parsed = signals.filter((signal) => this.validSignals.has(signal));
|
|
62
|
+
return parsed.length > 0 ? [...new Set(parsed)] : undefined;
|
|
63
|
+
}
|
|
46
64
|
/**
|
|
47
65
|
* Get the system message to inject into the LLM call.
|
|
48
66
|
* Combines the protocol (cacheable) and dynamic context (per-turn).
|
|
@@ -61,11 +79,12 @@ export class PsycheLangChain {
|
|
|
61
79
|
*/
|
|
62
80
|
async prepareInvocation(userText, opts) {
|
|
63
81
|
const result = await this.engine.processInput(userText, opts);
|
|
82
|
+
const generationControls = result.replyEnvelope?.generationControls ?? result.generationControls;
|
|
64
83
|
const controls = {
|
|
65
|
-
...(
|
|
66
|
-
maxTokens:
|
|
67
|
-
? Math.min(opts.maxTokens,
|
|
68
|
-
:
|
|
84
|
+
...(generationControls ?? {}),
|
|
85
|
+
maxTokens: generationControls?.maxTokens !== undefined && opts?.maxTokens !== undefined
|
|
86
|
+
? Math.min(opts.maxTokens, generationControls.maxTokens)
|
|
87
|
+
: generationControls?.maxTokens ?? opts?.maxTokens,
|
|
69
88
|
};
|
|
70
89
|
return {
|
|
71
90
|
systemMessage: result.systemContext + "\n\n" + result.dynamicContext,
|
|
@@ -80,7 +99,11 @@ export class PsycheLangChain {
|
|
|
80
99
|
* Call this AFTER the LLM invocation, before showing output to the user.
|
|
81
100
|
*/
|
|
82
101
|
async processResponse(text, opts) {
|
|
83
|
-
const result = await this.engine.processOutput(text,
|
|
102
|
+
const result = await this.engine.processOutput(text, {
|
|
103
|
+
userId: opts?.userId,
|
|
104
|
+
signals: this.parseSignals(opts?.signals),
|
|
105
|
+
signalConfidence: opts?.signalConfidence,
|
|
106
|
+
});
|
|
84
107
|
return result.cleanedText;
|
|
85
108
|
}
|
|
86
109
|
}
|
package/dist/adapters/mcp.js
CHANGED
|
@@ -145,8 +145,10 @@ server.resource("state", "psyche://state", {
|
|
|
145
145
|
// ── Tools ──────────────────────────────────────────────────
|
|
146
146
|
server.tool("process_input", "Process user input through the emotional engine. Returns emotional " +
|
|
147
147
|
"context to inject into the LLM system prompt (systemContext + dynamicContext), " +
|
|
148
|
-
"detected stimulus type,
|
|
149
|
-
"(subjectivityKernel + responseContract),
|
|
148
|
+
"detected stimulus type, a canonical replyEnvelope, compatibility aliases " +
|
|
149
|
+
"(policyModifiers + subjectivityKernel + responseContract + generationControls), an optional " +
|
|
150
|
+
"externalContinuity envelope, and sparse low-frequency throngletsExports " +
|
|
151
|
+
"suitable for additive external continuity layers. " +
|
|
150
152
|
"Call this BEFORE generating a response to the user.", {
|
|
151
153
|
text: z.string().describe("The user's message text"),
|
|
152
154
|
userId: z.string().optional().describe("Optional user ID for multi-user relationship tracking"),
|
|
@@ -160,10 +162,15 @@ server.tool("process_input", "Process user input through the emotional engine. R
|
|
|
160
162
|
systemContext: result.systemContext,
|
|
161
163
|
dynamicContext: result.dynamicContext,
|
|
162
164
|
stimulus: result.stimulus,
|
|
165
|
+
replyEnvelope: result.replyEnvelope ?? null,
|
|
163
166
|
policyModifiers: result.policyModifiers ?? null,
|
|
164
167
|
subjectivityKernel: result.subjectivityKernel ?? null,
|
|
165
168
|
responseContract: result.responseContract ?? null,
|
|
166
169
|
generationControls: result.generationControls ?? null,
|
|
170
|
+
sessionBridge: result.sessionBridge ?? null,
|
|
171
|
+
writebackFeedback: result.writebackFeedback ?? null,
|
|
172
|
+
externalContinuity: result.externalContinuity ?? null,
|
|
173
|
+
throngletsExports: result.throngletsExports ?? null,
|
|
167
174
|
policyContext: result.policyContext,
|
|
168
175
|
}, null, 2),
|
|
169
176
|
}],
|
|
@@ -174,9 +181,11 @@ server.tool("process_output", "Process the LLM's response through the emotional
|
|
|
174
181
|
"emotional contagion. Call this AFTER generating a response.", {
|
|
175
182
|
text: z.string().describe("The LLM's response text"),
|
|
176
183
|
userId: z.string().optional().describe("Optional user ID"),
|
|
177
|
-
|
|
184
|
+
signals: z.array(z.string()).optional().describe("Optional sparse writeback signals from the host"),
|
|
185
|
+
signalConfidence: z.number().min(0).max(1).optional().describe("Optional confidence for the supplied signals"),
|
|
186
|
+
}, async ({ text, userId, signals, signalConfidence }) => {
|
|
178
187
|
const eng = await getEngine();
|
|
179
|
-
const result = await eng.processOutput(text, { userId });
|
|
188
|
+
const result = await eng.processOutput(text, { userId, signals: signals, signalConfidence });
|
|
180
189
|
return {
|
|
181
190
|
content: [{
|
|
182
191
|
type: "text",
|
|
@@ -44,7 +44,7 @@ export function sanitizeOpenClawInputText(text) {
|
|
|
44
44
|
.trim();
|
|
45
45
|
}
|
|
46
46
|
function getDominantAppraisalLabel(result) {
|
|
47
|
-
const appraisal = result.subjectivityKernel?.appraisal;
|
|
47
|
+
const appraisal = result.replyEnvelope?.subjectivityKernel?.appraisal ?? result.subjectivityKernel?.appraisal;
|
|
48
48
|
if (!appraisal)
|
|
49
49
|
return null;
|
|
50
50
|
const entries = [
|
|
@@ -118,7 +118,7 @@ export function register(api) {
|
|
|
118
118
|
}
|
|
119
119
|
const engine = await getEngine(workspaceDir);
|
|
120
120
|
const result = await engine.processInput(inputText, { userId: ctx.userId });
|
|
121
|
-
const controls = result.generationControls;
|
|
121
|
+
const controls = result.replyEnvelope?.generationControls ?? result.generationControls;
|
|
122
122
|
const dominantAppraisal = getDominantAppraisalLabel(result);
|
|
123
123
|
const state = engine.getState();
|
|
124
124
|
logger.info(`Psyche [input] stimulus=${result.stimulus ?? "none"} | ` +
|
|
@@ -49,11 +49,13 @@ export function psycheMiddleware(engine, _opts) {
|
|
|
49
49
|
transformParams: async ({ params }) => {
|
|
50
50
|
const userText = extractLastUserText(params.prompt ?? []);
|
|
51
51
|
const result = await engine.processInput(userText);
|
|
52
|
+
const envelope = result.replyEnvelope;
|
|
53
|
+
const generationControls = envelope?.generationControls ?? result.generationControls;
|
|
52
54
|
const controls = {
|
|
53
|
-
...(
|
|
54
|
-
maxTokens:
|
|
55
|
-
? Math.min(params.maxTokens,
|
|
56
|
-
:
|
|
55
|
+
...(generationControls ?? {}),
|
|
56
|
+
maxTokens: generationControls?.maxTokens !== undefined && typeof params.maxTokens === "number"
|
|
57
|
+
? Math.min(params.maxTokens, generationControls.maxTokens)
|
|
58
|
+
: generationControls?.maxTokens ?? (typeof params.maxTokens === "number" ? params.maxTokens : undefined),
|
|
57
59
|
};
|
|
58
60
|
const psycheContext = result.systemContext + "\n\n" + result.dynamicContext;
|
|
59
61
|
return {
|
package/dist/core.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { PsycheState, StimulusType, Locale, MBTIType, OutcomeScore, PsycheMode, PersonalityTraits, PolicyModifiers, ClassifierProvider, SubjectivityKernel, ResponseContract, GenerationControls } from "./types.js";
|
|
1
|
+
import type { PsycheState, StimulusType, Locale, MBTIType, OutcomeScore, PsycheMode, PersonalityTraits, PolicyModifiers, ClassifierProvider, SubjectivityKernel, ResponseContract, GenerationControls, SessionBridgeState, ThrongletsExport, WritebackCalibrationFeedback, WritebackSignalType, ExternalContinuityEnvelope } from "./types.js";
|
|
2
2
|
import type { StorageAdapter } from "./storage.js";
|
|
3
3
|
import type { DiagnosticReport, SessionMetrics } from "./diagnostics.js";
|
|
4
|
+
import type { ReplyEnvelope } from "./reply-envelope.js";
|
|
4
5
|
export interface PsycheEngineConfig {
|
|
5
6
|
mbti?: MBTIType;
|
|
6
7
|
name?: string;
|
|
@@ -36,16 +37,28 @@ export interface ProcessInputResult {
|
|
|
36
37
|
dynamicContext: string;
|
|
37
38
|
/** Detected stimulus type from user input, null if none */
|
|
38
39
|
stimulus: StimulusType | null;
|
|
39
|
-
/**
|
|
40
|
+
/** Confidence of the primary algorithmic stimulus guess, if any */
|
|
41
|
+
stimulusConfidence?: number;
|
|
42
|
+
/** Legacy compatibility alias: raw policy vector behind the canonical replyEnvelope. */
|
|
40
43
|
policyModifiers?: PolicyModifiers;
|
|
41
|
-
/** v9.3
|
|
44
|
+
/** v9.3+: canonical host-facing reply surface */
|
|
45
|
+
replyEnvelope?: ReplyEnvelope;
|
|
46
|
+
/** v9.3 compatibility alias: use replyEnvelope.subjectivityKernel when possible */
|
|
42
47
|
subjectivityKernel?: SubjectivityKernel;
|
|
43
|
-
/** v9.3:
|
|
48
|
+
/** v9.3 compatibility alias: use replyEnvelope.responseContract when possible */
|
|
44
49
|
responseContract?: ResponseContract;
|
|
45
|
-
/** v9.3
|
|
50
|
+
/** v9.3 compatibility alias: use replyEnvelope.generationControls when possible */
|
|
46
51
|
generationControls?: GenerationControls;
|
|
52
|
+
/** v9.2.7: cold-start carry derived from persisted relation state */
|
|
53
|
+
sessionBridge?: SessionBridgeState | null;
|
|
54
|
+
/** v9.2.8: sparse writeback signals evaluated on the latest turn */
|
|
55
|
+
writebackFeedback?: WritebackCalibrationFeedback[];
|
|
56
|
+
/** v9.2.8: optional additive external continuity contract */
|
|
57
|
+
externalContinuity?: ExternalContinuityEnvelope<ThrongletsExport>;
|
|
58
|
+
/** v9.2.8: sparse low-frequency export surface suitable for Thronglets */
|
|
59
|
+
throngletsExports?: ThrongletsExport[];
|
|
47
60
|
/**
|
|
48
|
-
*
|
|
61
|
+
* Legacy compatibility alias: ready-to-use prompt fragment summarizing raw policy modifiers.
|
|
49
62
|
*
|
|
50
63
|
* This is the output of `buildPolicyContext(policyModifiers, locale)` —
|
|
51
64
|
* a human-readable string like "[行为策略] 简短回复、被动应答为主".
|
|
@@ -65,6 +78,11 @@ export interface ProcessOutputResult {
|
|
|
65
78
|
/** Whether chemistry was meaningfully updated (contagion or psyche_update) */
|
|
66
79
|
stateChanged: boolean;
|
|
67
80
|
}
|
|
81
|
+
export interface ProcessOutputOptions {
|
|
82
|
+
userId?: string;
|
|
83
|
+
signals?: WritebackSignalType[];
|
|
84
|
+
signalConfidence?: number;
|
|
85
|
+
}
|
|
68
86
|
export interface ProcessOutcomeResult {
|
|
69
87
|
/** Outcome evaluation score (-1 to 1) */
|
|
70
88
|
outcomeScore: OutcomeScore;
|
|
@@ -89,6 +107,8 @@ export declare class PsycheEngine {
|
|
|
89
107
|
private lastReport;
|
|
90
108
|
/** URL for auto-submitting diagnostic reports */
|
|
91
109
|
private readonly feedbackUrl;
|
|
110
|
+
/** Most recent algorithmic stimulus read + confidence band */
|
|
111
|
+
private lastStimulusAssessment;
|
|
92
112
|
constructor(config: PsycheEngineConfig | undefined, storage: StorageAdapter);
|
|
93
113
|
/**
|
|
94
114
|
* Load or create initial state. Must be called before processInput/processOutput.
|
|
@@ -105,9 +125,7 @@ export declare class PsycheEngine {
|
|
|
105
125
|
* Phase 2: Process LLM output text.
|
|
106
126
|
* Parses <psyche_update> tags, applies contagion, strips tags.
|
|
107
127
|
*/
|
|
108
|
-
processOutput(text: string, opts?:
|
|
109
|
-
userId?: string;
|
|
110
|
-
}): Promise<ProcessOutputResult>;
|
|
128
|
+
processOutput(text: string, opts?: ProcessOutputOptions): Promise<ProcessOutputResult>;
|
|
111
129
|
/**
|
|
112
130
|
* Phase 3 (optional): Explicitly evaluate the outcome of the last interaction.
|
|
113
131
|
*
|