spl-agent-engine 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,24 @@
1
+ """
2
+ SPL Agent Engine — Composable feature modules.
3
+
4
+ Each module is self-contained and can be mixed into a persona:
5
+ - identity: multi-identity system with identity conflict
6
+ - goal: goal hierarchy and goal-engine dynamics
7
+ - bias: cognitive bias profiles (optimistic / paranoid / depressive)
8
+ - value: value system and dissonance
9
+ - world: world-model priors (optimistic / pessimistic / traumatized)
10
+ """
11
+
12
+ from .identity import IdentityNode, IdentityEngine
13
+ from .goal import GoalNode, GoalEngine
14
+ from .bias import BiasProfile, BiasEngine
15
+ from .value import ValueProfile, ValueEngine
16
+ from .world import WorldModel
17
+
18
+ __all__ = [
19
+ "IdentityNode", "IdentityEngine",
20
+ "GoalNode", "GoalEngine",
21
+ "BiasProfile", "BiasEngine",
22
+ "ValueProfile", "ValueEngine",
23
+ "WorldModel",
24
+ ]
@@ -0,0 +1,162 @@
1
+ # ================================================================
2
+ # 认知偏见系统(Cognitive Bias Profile)—— 【自设模块】
3
+ # ================================================================
4
+ # 偏见是角色对信息的系统性扭曲,不同角色有不同的偏见图谱。
5
+ #
6
+ # 这是"角色的人格滤镜"——同样一件事,不同偏见的人感受完全不同。
7
+ # 偏见直接影响核心引擎的 _core_appraisal_gain(认知增益阶段)。
8
+ #
9
+ # 用法:在自定义 Mapper 或引擎外层集成 BiasProfile,
10
+ # 调用 apply_appraisal_bias() 调制 perceived vector。
11
+ # ================================================================
12
+
13
+ from dataclasses import dataclass
14
+ from typing import Dict
15
+
16
+
17
+ @dataclass
18
+ class BiasProfile:
19
+ """
20
+ 角色认知偏见图谱。
21
+
22
+ 不是"有没有偏见"——所有人都有。这是"有什么样的偏见"。
23
+ """
24
+
25
+ # ── 注意偏差(Attentional Biases)──
26
+ negativity_bias: float = 0.7 # 负面信息优先加工 [0,1]
27
+ threat_vigilance: float = 0.5 # 威胁警觉(高→草木皆兵)[0,1]
28
+ positivity_offset: float = 0.3 # 正面信息基线捕获 [0,1]
29
+
30
+ # ── 解释偏差(Interpretive Biases)──
31
+ confirmation_bias: float = 0.6 # 确认偏见(只信符合预期的)[0,1]
32
+ hostile_attribution: float = 0.3 # 敌意归因(中性→恶意)[0,1]
33
+ benevolent_attribution: float = 0.4 # 善意归因(中性→善意)[0,1]
34
+
35
+ # ── 记忆偏差(Memory Biases)──
36
+ mood_congruent_memory: float = 0.5 # 情绪一致性记忆(心情差→只想起坏事)
37
+ peak_end_rule: float = 0.6 # 峰终定律权重(只记住高峰和结尾)
38
+ rosy_retrospection: float = 0.3 # 玫瑰色回顾(美化过去)
39
+
40
+ # ── 归因偏差(Attributional Biases)──
41
+ self_serving_bias: float = 0.5 # 自我服务偏差(成功内归因→失败外归因)
42
+ fundamental_attribution: float = 0.6 # 基本归因错误(别人的错是性格,自己的错是环境)
43
+
44
+ # ── 社会偏差(Social Biases)──
45
+ in_group_bias: float = 0.4 # 内群体偏好
46
+ authority_bias: float = 0.3 # 权威服从倾向
47
+ projection_bias: float = 0.4 # 投射倾向(自己怎么想就觉得别人也这么想)
48
+
49
+
50
+ class BiasEngine:
51
+ """
52
+ 偏见引擎:把 BiasProfile 应用到认知处理管道。
53
+
54
+ 在核心引擎的 _core_appraisal_gain 之后、_vector_to_fluid 之前调用。
55
+ """
56
+
57
+ def __init__(self, profile: BiasProfile = None):
58
+ self.profile = profile or BiasProfile()
59
+
60
+ def apply_appraisal_bias(self, perceived: Dict[str, float],
61
+ world_model=None) -> Dict[str, float]:
62
+ """
63
+ 对认知增益后的 perceived vector 施加偏见调制。
64
+
65
+ 调用时机:engine._core_appraisal_gain() 之后。
66
+
67
+ Args:
68
+ perceived: 认知增益后的内感受向量
69
+ world_model: 可选的世界模型引用,用于确认偏见
70
+
71
+ Returns:
72
+ 偏见调制后的向量
73
+ """
74
+ out = dict(perceived)
75
+ p = self.profile
76
+
77
+ # ── 负面偏差:放大 threat,放大负向 belonging ──
78
+ if out.get("threat", 0.0) > 0:
79
+ out["threat"] *= (1.0 + p.negativity_bias * 0.6)
80
+ if out.get("belonging", 0.0) < 0:
81
+ out["belonging"] *= (1.0 + p.negativity_bias * 0.4)
82
+
83
+ # ── 威胁警觉:任何微弱 threat 都被放大 ──
84
+ if 0 < out.get("threat", 0.0) < 0.2:
85
+ out["threat"] *= (1.0 + p.threat_vigilance)
86
+
87
+ # ── 敌意归因:对中性 threat 加码 ──
88
+ if out.get("threat", 0.0) > 0 and p.hostile_attribution > 0.5:
89
+ out["threat"] *= (1.0 + (p.hostile_attribution - 0.5))
90
+
91
+ # ── 确认偏见:如果世界模型认为人不值得信任,threat 被强化 ──
92
+ if world_model and world_model.trust_people < 0.3:
93
+ if out.get("threat", 0.0) > 0:
94
+ out["threat"] *= (1.0 + p.confirmation_bias * 0.5)
95
+ if out.get("belonging", 0.0) > 0:
96
+ out["belonging"] *= (1.0 - p.confirmation_bias * 0.3)
97
+
98
+ return out
99
+
100
+ def modulate_memory_strength(self, event_type: str, strength: float) -> float:
101
+ """
102
+ 调制记忆写入强度——有偏见的记忆系统。
103
+
104
+ 负面事件记忆更牢固(负向偏见),符合预期的记忆更牢固(确认偏见)。
105
+ """
106
+ p = self.profile
107
+ if event_type in ["insult", "betrayal", "criticism", "threat"]:
108
+ strength *= (1.0 + p.negativity_bias)
109
+ elif event_type in ["compliment", "trust_signal"]:
110
+ # 正面事件,确认偏见影响编码
111
+ strength *= (1.0 - p.confirmation_bias * 0.3)
112
+ # 情绪一致性:如果负面偏见很高,负面记忆更牢固
113
+ if p.negativity_bias > 0.6 and strength > 0:
114
+ strength *= (1.0 + p.mood_congruent_memory * 0.2)
115
+ return min(1.0, max(0.0, strength))
116
+
117
+ def interpret_neutral(self, signal_valence: float) -> float:
118
+ """
119
+ 解释中性信号:偏见决定了中性信号被推向正面还是负面。
120
+
121
+ Args:
122
+ signal_valence: 信号效价(~0 = 中性)
123
+
124
+ Returns:
125
+ 被偏见扭曲后的效价
126
+ """
127
+ p = self.profile
128
+ # 敌意归因 → 推向负面;善意归因 → 推向正面
129
+ net_bias = p.hostile_attribution - p.benevolent_attribution
130
+ return max(-1.0, min(1.0, signal_valence + net_bias * 0.5 * (1.0 - abs(signal_valence))))
131
+
132
+
133
+ # ── 预设角色模板 ──
134
+
135
+ def paranoid_bias() -> BiasProfile:
136
+ """偏执型偏见——高威胁警觉 + 高敌意归因"""
137
+ return BiasProfile(
138
+ negativity_bias=0.9, threat_vigilance=0.85,
139
+ hostile_attribution=0.8, benevolent_attribution=0.1,
140
+ confirmation_bias=0.8, projection_bias=0.7,
141
+ mood_congruent_memory=0.7,
142
+ )
143
+
144
+
145
+ def optimistic_bias() -> BiasProfile:
146
+ """乐观型偏见——高正面偏倚 + 低威胁警觉"""
147
+ return BiasProfile(
148
+ negativity_bias=0.3, threat_vigilance=0.2,
149
+ positivity_offset=0.7, hostile_attribution=0.1,
150
+ benevolent_attribution=0.7, rosy_retrospection=0.6,
151
+ self_serving_bias=0.7,
152
+ )
153
+
154
+
155
+ def depressive_bias() -> BiasProfile:
156
+ """抑郁型偏见——高负面 + 低自我服务"""
157
+ return BiasProfile(
158
+ negativity_bias=0.9, threat_vigilance=0.7,
159
+ positivity_offset=0.1, hostile_attribution=0.5,
160
+ confirmation_bias=0.7, self_serving_bias=0.1,
161
+ mood_congruent_memory=0.8, rosy_retrospection=0.1,
162
+ )
@@ -0,0 +1,174 @@
1
+ # ================================================================
2
+ # 目标系统(Goal Engine)—— 【自设模块】
3
+ # ================================================================
4
+ # 目标是角色行为的驱动力。目标受阻产生挫折感,
5
+ # 目标达成产生成就感。不同角色有不同的目标层级。
6
+ #
7
+ # 用法:在 Agent 初始化时加载 GoalEngine,
8
+ # 用 update_progress() 更新目标进度,
9
+ # 用 get_emotion_vector() 获取目标状态的情绪影响。
10
+ # ================================================================
11
+
12
+ from dataclasses import dataclass, field
13
+ from typing import List, Dict, Optional
14
+ import math
15
+
16
+
17
+ @dataclass
18
+ class GoalNode:
19
+ """一个目标节点"""
20
+ name: str # 目标名称
21
+ importance: float # 重要性 [0,1]
22
+ progress: float = 0.0 # 当前进度 [0,1]
23
+ urgency: float = 0.5 # 紧迫度 [0,1]
24
+ difficulty: float = 0.5 # 难度 [0,1]
25
+ dependencies: List[str] = field(default_factory=list) # 依赖的其他目标
26
+ stalled: bool = False # 是否卡住了
27
+
28
+
29
+ class GoalEngine:
30
+ """
31
+ 目标引擎:管理目标的层级结构和进度。
32
+
33
+ 核心机制:
34
+ 1. 目标受阻(progress 停滞 + urgency 高)→ 挫折情绪
35
+ 2. 目标达成(progress → 1.0)→ 成就感
36
+ 3. 目标冲突(A 的进度牺牲了 B)→ 内在张力
37
+ 4. 当前主目标决定注意力分配和行为优先级
38
+ """
39
+
40
+ def __init__(self):
41
+ self.goals: List[GoalNode] = []
42
+ self.completed_goals: List[GoalNode] = []
43
+
44
+ def add_goal(self, name: str, importance: float, urgency: float = 0.5,
45
+ difficulty: float = 0.5, dependencies: List[str] = None):
46
+ """添加一个目标。"""
47
+ self.goals.append(GoalNode(
48
+ name=name, importance=importance,
49
+ urgency=urgency, difficulty=difficulty,
50
+ dependencies=dependencies or [],
51
+ ))
52
+
53
+ def update_progress(self, goal_name: str, delta: float):
54
+ """
55
+ 更新目标进度。
56
+
57
+ Args:
58
+ goal_name: 目标名
59
+ delta: 进度变化 [-1, 1]
60
+ """
61
+ for goal in self.goals:
62
+ if goal.name == goal_name:
63
+ old_progress = goal.progress
64
+ goal.progress = max(0.0, min(1.0, goal.progress + delta))
65
+
66
+ # 进度停止 → 标记为卡住
67
+ if abs(goal.progress - old_progress) < 0.01 and goal.progress < 0.9:
68
+ goal.stalled = True
69
+ else:
70
+ goal.stalled = False
71
+
72
+ # 目标达成
73
+ if goal.progress >= 0.99:
74
+ self.completed_goals.append(goal)
75
+ self.goals.remove(goal)
76
+ break
77
+
78
+ def set_urgency(self, goal_name: str, urgency: float):
79
+ """更新目标紧迫度。"""
80
+ for goal in self.goals:
81
+ if goal.name == goal_name:
82
+ goal.urgency = max(0.0, min(1.0, urgency))
83
+ break
84
+
85
+ def get_primary_goal(self) -> Optional[GoalNode]:
86
+ """获取当前主目标(重要性 × 紧迫度 × (1-进度) 最大)。"""
87
+ if not self.goals:
88
+ return None
89
+ return max(self.goals, key=lambda g:
90
+ g.importance * g.urgency * (1.0 - g.progress) * g.difficulty)
91
+
92
+ def goal_conflict_level(self) -> float:
93
+ """
94
+ 计算目标间的冲突水平。
95
+
96
+ 高重要性目标之间的进度权衡会产生冲突。
97
+ """
98
+ if len(self.goals) < 2:
99
+ return 0.0
100
+ # 依赖冲突:如果 A 的完成阻碍了 B
101
+ conflict = 0.0
102
+ for g in self.goals:
103
+ for dep_name in g.dependencies:
104
+ for other in self.goals:
105
+ if other.name == dep_name and other.progress < 0.3:
106
+ conflict += g.importance * g.urgency
107
+ return min(1.0, conflict * 0.5)
108
+
109
+ def get_emotion_vector(self) -> Dict[str, float]:
110
+ """
111
+ 将目标状态转化为情绪向量。
112
+
113
+ 定期调用,注入 core.process_vector() 作为基底。
114
+ """
115
+ vector = {}
116
+ primary = self.get_primary_goal()
117
+
118
+ if primary:
119
+ # 重要目标卡住 → 挫折/张力
120
+ if primary.stalled and primary.importance > 0.5:
121
+ frustration = primary.importance * primary.urgency * 0.3
122
+ vector["tension_base"] = vector.get("tension_base", 0.0) + frustration
123
+ # 如果卡住的是高难度目标 → 可能触发羞耻("我做不到")
124
+ if primary.difficulty > 0.7:
125
+ vector["shame_trigger"] = 0.15 * primary.importance
126
+
127
+ # 目标进展 → 轻微喜悦
128
+ if primary.progress > 0.5:
129
+ progress_joy = primary.importance * (primary.progress - 0.5) * 0.2
130
+ vector["belonging"] = vector.get("belonging", 0.0) + progress_joy
131
+
132
+ # 高紧迫度 → 张力
133
+ if primary.urgency > 0.7:
134
+ vector["tension_base"] = vector.get("tension_base", 0.0) + primary.urgency * 0.2
135
+
136
+ # 目标冲突 → 张力
137
+ conflict = self.goal_conflict_level()
138
+ if conflict > 0.1:
139
+ vector["tension_base"] = vector.get("tension_base", 0.0) + conflict * 0.3
140
+
141
+ # 近期完成目标 → 喜悦+自尊提升
142
+ if self.completed_goals:
143
+ total_importance = sum(g.importance for g in self.completed_goals[-3:])
144
+ vector["belonging"] = vector.get("belonging", 0.0) + total_importance * 0.15
145
+
146
+ return vector
147
+
148
+ def snapshot(self) -> dict:
149
+ """目标系统快照。"""
150
+ return {
151
+ "active_goals": [
152
+ {"name": g.name, "importance": g.importance,
153
+ "progress": g.progress, "urgency": g.urgency,
154
+ "stalled": g.stalled}
155
+ for g in self.goals
156
+ ],
157
+ "primary": self.get_primary_goal().name if self.get_primary_goal() else None,
158
+ "completed": len(self.completed_goals),
159
+ "conflict": self.goal_conflict_level(),
160
+ }
161
+
162
+
163
+ # ── 预设:苏瑾的目标配置 ──
164
+
165
+ def sujin_goals() -> GoalEngine:
166
+ """苏瑾的目标层级"""
167
+ engine = GoalEngine()
168
+ engine.add_goal("赢得客户信任", importance=0.8, urgency=0.7, difficulty=0.7)
169
+ engine.add_goal("保持专业独立性", importance=0.75, urgency=0.5, difficulty=0.6)
170
+ engine.add_goal("交付高质量方案", importance=0.9, urgency=0.8, difficulty=0.8)
171
+ # 此目标依赖"赢得客户信任"
172
+ engine.add_goal("建立长期战略合作", importance=0.7, urgency=0.4, difficulty=0.8,
173
+ dependencies=["赢得客户信任"])
174
+ return engine
@@ -0,0 +1,162 @@
1
+ # ================================================================
2
+ # 身份系统(Identity Engine)—— 【自设模块】
3
+ # ================================================================
4
+ # 角色拥有多重身份(职业身份、家庭角色、社会角色),
5
+ # 身份之间有和谐也有冲突。冲突产生持续的心理张力。
6
+ #
7
+ # 用法:在 Agent 初始化时加载 IdentityEngine,
8
+ # 定期检查冲突并将张力注入核心引擎。
9
+ # ================================================================
10
+
11
+ from dataclasses import dataclass, field
12
+ from typing import List, Dict, Optional
13
+
14
+
15
+ @dataclass
16
+ class IdentityNode:
17
+ """一个身份节点"""
18
+ name: str # 身份名称("顾问"、"母亲"、"合伙人")
19
+ strength: float # 身份强度 [0,1](有多认同这个身份)
20
+ priority: float # 优先度 [0,1](在冲突时有多优先)
21
+ satisfaction: float = 0.5 # 身份满意度 [0,1](在这个角色中感到多满意)
22
+ threat_level: float = 0.0 # 该身份受到的威胁 [0,1]
23
+
24
+
25
+ @dataclass
26
+ class IdentityEngine:
27
+ """
28
+ 身份引擎:管理多重身份及其冲突。
29
+
30
+ 核心洞察:
31
+ - 身份冲突会产生持续的基底张力(不只是瞬时情绪)
32
+ - 身份威胁比对个体的攻击更伤人("你不配做顾问" > "你这个方案不行")
33
+ - 身份满意度的变化影响自尊
34
+ """
35
+
36
+ identities: List[IdentityNode] = field(default_factory=list)
37
+ conflict_matrix: Dict[str, Dict[str, float]] = field(default_factory=dict)
38
+ # conflict_history 追踪冲突趋势(上升 vs 下降)
39
+ conflict_history: List[float] = field(default_factory=list)
40
+
41
+ def add_identity(self, name: str, strength: float = 0.7,
42
+ priority: float = 0.5, satisfaction: float = 0.5):
43
+ """添加一个身份。"""
44
+ node = IdentityNode(
45
+ name=name, strength=strength,
46
+ priority=priority, satisfaction=satisfaction,
47
+ )
48
+ self.identities.append(node)
49
+ # 初始化冲突矩阵
50
+ for other in self.identities:
51
+ if other.name != name:
52
+ self.conflict_matrix.setdefault(name, {})[other.name] = 0.0
53
+ self.conflict_matrix.setdefault(other.name, {})[name] = 0.0
54
+
55
+ def set_conflict(self, id1: str, id2: str, level: float):
56
+ """
57
+ 设置两个身份之间的冲突水平 [0,1]。
58
+
59
+ 比如:"顾问"和"朋友"之间的冲突 = 0.6
60
+ 意味着在这两个角色之间切换时,有 60% 的内在张力。
61
+ """
62
+ self.conflict_matrix.setdefault(id1, {})[id2] = max(0.0, min(1.0, level))
63
+ self.conflict_matrix.setdefault(id2, {})[id1] = max(0.0, min(1.0, level))
64
+
65
+ def total_conflict(self) -> float:
66
+ """
67
+ 计算当前所有身份冲突的总和。
68
+
69
+ 返回值 [0,1]:0 = 完全和谐,1 = 极度撕裂。
70
+ """
71
+ if len(self.identities) < 2:
72
+ return 0.0
73
+ total = 0.0
74
+ count = 0
75
+ for i in range(len(self.identities)):
76
+ for j in range(i + 1, len(self.identities)):
77
+ a = self.identities[i]
78
+ b = self.identities[j]
79
+ conflict_level = self.conflict_matrix.get(a.name, {}).get(b.name, 0.0)
80
+ # 冲突强度 = 身份强度乘积 × 冲突水平 × 优先度差
81
+ tension = (conflict_level
82
+ * a.strength
83
+ * b.strength
84
+ * abs(a.priority - b.priority))
85
+ total += tension
86
+ count += 1
87
+ return min(1.0, total / max(1, count) * 2.0)
88
+
89
+ def threaten_identity(self, identity_name: str, threat_magnitude: float):
90
+ """
91
+ 对某个身份施加威胁。
92
+
93
+ 触发:当角色感知到某个身份被攻击/否定时调用。
94
+ 返回一个可用于注入核心引擎的情绪向量。
95
+ """
96
+ for ident in self.identities:
97
+ if ident.name == identity_name:
98
+ ident.threat_level = min(1.0, ident.threat_level + threat_magnitude)
99
+ ident.satisfaction = max(0.0, ident.satisfaction - threat_magnitude * 0.5)
100
+ break
101
+
102
+ def affirm_identity(self, identity_name: str, boost: float):
103
+ """肯定某个身份(提升满意度和强度)。"""
104
+ for ident in self.identities:
105
+ if ident.name == identity_name:
106
+ ident.satisfaction = min(1.0, ident.satisfaction + boost)
107
+ ident.strength = min(1.0, ident.strength + boost * 0.3)
108
+ ident.threat_level = max(0.0, ident.threat_level - boost * 0.5)
109
+ break
110
+
111
+ def get_emotion_vector(self) -> Dict[str, float]:
112
+ """
113
+ 将当前身份状态转化为可供核心引擎消化的情绪向量。
114
+
115
+ 这个向量应该定期(或在事件处理前)注入 core.process_vector()。
116
+ """
117
+ tc = self.total_conflict()
118
+
119
+ # 身份冲突 → 持续张力基底
120
+ vector = {"tension_base": tc * 0.3}
121
+
122
+ # 身份威胁 → shame_trigger("我不配当X")
123
+ max_threat = max((i.threat_level for i in self.identities), default=0.0)
124
+ if max_threat > 0.3:
125
+ vector["shame_trigger"] = max_threat * 0.4
126
+
127
+ # 低身份满意度 → 归属感下降
128
+ min_satisfaction = min((i.satisfaction for i in self.identities), default=1.0)
129
+ if min_satisfaction < 0.4:
130
+ vector["belonging"] = -0.2 * (0.5 - min_satisfaction)
131
+
132
+ # 高身份满意度 → 喜悦基线
133
+ avg_satisfaction = (sum(i.satisfaction for i in self.identities) /
134
+ max(1, len(self.identities)))
135
+ if avg_satisfaction > 0.7:
136
+ vector["belonging"] = 0.15 * (avg_satisfaction - 0.5)
137
+
138
+ return vector
139
+
140
+ def snapshot(self) -> dict:
141
+ """身份系统快照。"""
142
+ return {
143
+ "identities": [
144
+ {"name": i.name, "strength": i.strength,
145
+ "priority": i.priority, "satisfaction": i.satisfaction,
146
+ "threat": i.threat_level}
147
+ for i in self.identities
148
+ ],
149
+ "total_conflict": self.total_conflict(),
150
+ }
151
+
152
+
153
+ # ── 预设:苏瑾的身份配置 ──
154
+
155
+ def sujin_identity() -> IdentityEngine:
156
+ """苏瑾的多重身份配置"""
157
+ engine = IdentityEngine()
158
+ engine.add_identity("资深行业顾问", strength=0.9, priority=0.8, satisfaction=0.7)
159
+ engine.add_identity("战略合作伙伴", strength=0.6, priority=0.6, satisfaction=0.5)
160
+ # 顾问(理性距离) vs 朋友(情感亲近)存在天然冲突
161
+ engine.set_conflict("资深行业顾问", "战略合作伙伴", 0.35)
162
+ return engine