alive-ai 0.1.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.
Files changed (168) hide show
  1. package/Dockerfile +24 -0
  2. package/LICENSE +21 -0
  3. package/README.md +143 -0
  4. package/alive_ai/__init__.py +3 -0
  5. package/brain/__init__.py +59 -0
  6. package/brain/almost_said.py +154 -0
  7. package/brain/bid_detector.py +636 -0
  8. package/brain/conversation_flow.py +135 -0
  9. package/brain/curiosity.py +328 -0
  10. package/brain/default_mode.py +1438 -0
  11. package/brain/dreams.py +220 -0
  12. package/brain/embeddings/__init__.py +82 -0
  13. package/brain/emotional_memory.py +949 -0
  14. package/brain/global_activity.py +173 -0
  15. package/brain/group_dynamics.py +63 -0
  16. package/brain/linguistic.py +235 -0
  17. package/brain/llm/__init__.py +63 -0
  18. package/brain/llm/base.py +33 -0
  19. package/brain/llm/fallback_router.py +309 -0
  20. package/brain/llm/manifest.md +30 -0
  21. package/brain/llm/ollama.py +218 -0
  22. package/brain/llm/openrouter.py +151 -0
  23. package/brain/llm/provider.py +205 -0
  24. package/brain/llm/unified.py +423 -0
  25. package/brain/llm/zai.py +169 -0
  26. package/brain/manifest.md +23 -0
  27. package/brain/memory/__init__.py +123 -0
  28. package/brain/memory/episodic.py +92 -0
  29. package/brain/memory/fact_extractor.py +209 -0
  30. package/brain/memory/index.py +54 -0
  31. package/brain/memory/manager.py +151 -0
  32. package/brain/memory/summarizer.py +102 -0
  33. package/brain/memory/vector_store.py +297 -0
  34. package/brain/memory/working.py +43 -0
  35. package/brain/narrative.py +343 -0
  36. package/brain/stt/__init__.py +4 -0
  37. package/brain/stt/google_stt.py +83 -0
  38. package/brain/stt/whisper_stt.py +82 -0
  39. package/brain/subconscious/__init__.py +33 -0
  40. package/brain/subconscious/actions.py +136 -0
  41. package/brain/subconscious/evaluation.py +166 -0
  42. package/brain/subconscious/goal_system.py +90 -0
  43. package/brain/subconscious/goals.py +41 -0
  44. package/brain/subconscious/impulse_generator.py +200 -0
  45. package/brain/subconscious/impulses.py +48 -0
  46. package/brain/subconscious/learning.py +24 -0
  47. package/brain/subconscious/learning_system.py +79 -0
  48. package/brain/subconscious/loop.py +398 -0
  49. package/brain/subconscious/manifest.md +32 -0
  50. package/brain/subconscious/relationship.py +47 -0
  51. package/brain/subconscious/relationship_memory.py +83 -0
  52. package/brain/subconscious/response_analyzer.py +74 -0
  53. package/brain/subconscious/templates.py +70 -0
  54. package/brain/subconscious/thought.py +37 -0
  55. package/brain/subconscious/working_memory.py +97 -0
  56. package/cli/index.js +371 -0
  57. package/config/directives.example.json +28 -0
  58. package/config/instructions.example.md +16 -0
  59. package/config/self.example.json +74 -0
  60. package/config/settings.example.json +95 -0
  61. package/core/__init__.py +1 -0
  62. package/core/config.py +54 -0
  63. package/core/directives.py +198 -0
  64. package/core/events.py +50 -0
  65. package/core/follow_up.py +267 -0
  66. package/core/hot_reload.py +174 -0
  67. package/core/initialization.py +253 -0
  68. package/core/manifest.md +28 -0
  69. package/core/media_handler.py +241 -0
  70. package/core/memory_monitor.py +200 -0
  71. package/core/message_handler.py +1440 -0
  72. package/core/proactive_generator.py +277 -0
  73. package/core/self.py +188 -0
  74. package/core/settings.py +169 -0
  75. package/core/skills_registry.py +357 -0
  76. package/core/state.py +27 -0
  77. package/core/subconscious_bridge.py +93 -0
  78. package/core/thinking.py +175 -0
  79. package/core/user_manager.py +306 -0
  80. package/core/user_tracker.py +144 -0
  81. package/demo/index.html +144 -0
  82. package/docker-compose.yml +28 -0
  83. package/docs/assets/logo.svg +15 -0
  84. package/docs/index.html +355 -0
  85. package/heart/__init__.py +93 -0
  86. package/heart/afterglow.py +215 -0
  87. package/heart/attachment.py +186 -0
  88. package/heart/circadian.py +251 -0
  89. package/heart/complex_emotions.py +114 -0
  90. package/heart/conflicts.py +589 -0
  91. package/heart/core.py +387 -0
  92. package/heart/emotional_decay.py +59 -0
  93. package/heart/emotional_memory.py +261 -0
  94. package/heart/emotional_state.py +146 -0
  95. package/heart/emotional_variability.py +156 -0
  96. package/heart/hormonal.py +424 -0
  97. package/heart/inconsistency.py +1222 -0
  98. package/heart/integrity.py +469 -0
  99. package/heart/interoception.py +997 -0
  100. package/heart/love.py +120 -0
  101. package/heart/manifest.md +25 -0
  102. package/heart/mood_shifts.py +169 -0
  103. package/heart/phantom_somatic.py +259 -0
  104. package/heart/predictive.py +374 -0
  105. package/heart/scars.py +474 -0
  106. package/heart/somatic.py +482 -0
  107. package/heart/soul.py +633 -0
  108. package/heart/telemetry.py +942 -0
  109. package/heart/triggers.py +119 -0
  110. package/heart/unconscious.py +443 -0
  111. package/input/__init__.py +1 -0
  112. package/input/manifest.md +24 -0
  113. package/input/telegram/__init__.py +1 -0
  114. package/input/telegram/commands.py +762 -0
  115. package/input/telegram/listener.py +532 -0
  116. package/main.py +90 -0
  117. package/manifest.md +28 -0
  118. package/mypics/.gitkeep +1 -0
  119. package/myvids/.gitkeep +1 -0
  120. package/output/__init__.py +1 -0
  121. package/output/images/__init__.py +1 -0
  122. package/output/images/fal_gen.py +43 -0
  123. package/output/manifest.md +26 -0
  124. package/output/text/__init__.py +1 -0
  125. package/output/text/sender.py +22 -0
  126. package/output/voice/__init__.py +64 -0
  127. package/output/voice/google_tts.py +252 -0
  128. package/output/voice/gtts_tts.py +214 -0
  129. package/output/voice/vibe_tts.py +190 -0
  130. package/package.json +58 -0
  131. package/pyproject.toml +23 -0
  132. package/requirements.txt +21 -0
  133. package/skills/__init__.py +1 -0
  134. package/skills/anticipation_engine/__init__.py +8 -0
  135. package/skills/anticipation_engine/engine.py +618 -0
  136. package/skills/anticipation_engine/manifest.md +192 -0
  137. package/skills/calendar/__init__.py +1 -0
  138. package/skills/content_unlocks/__init__.py +8 -0
  139. package/skills/content_unlocks/manifest.md +231 -0
  140. package/skills/content_unlocks/unlocks.py +945 -0
  141. package/skills/exclusive_moments/__init__.py +8 -0
  142. package/skills/exclusive_moments/manifest.md +145 -0
  143. package/skills/exclusive_moments/moments.py +506 -0
  144. package/skills/intimacy_layers/__init__.py +8 -0
  145. package/skills/intimacy_layers/layers.py +703 -0
  146. package/skills/intimacy_layers/manifest.md +203 -0
  147. package/skills/manifest.md +67 -0
  148. package/skills/memory_callbacks/__init__.py +9 -0
  149. package/skills/memory_callbacks/callbacks.py +748 -0
  150. package/skills/memory_callbacks/manifest.md +170 -0
  151. package/skills/message_scheduler/__init__.py +19 -0
  152. package/skills/message_scheduler/manifest.md +107 -0
  153. package/skills/message_scheduler/scheduler.py +510 -0
  154. package/skills/photo_manager/__init__.py +1 -0
  155. package/skills/photo_manager/scanner.py +296 -0
  156. package/skills/relationship_milestones/__init__.py +8 -0
  157. package/skills/relationship_milestones/manifest.md +206 -0
  158. package/skills/relationship_milestones/tracker.py +494 -0
  159. package/skills/self_authorship/__init__.py +23 -0
  160. package/skills/self_authorship/author.py +331 -0
  161. package/skills/self_authorship/manifest.md +24 -0
  162. package/skills/video_manager/__init__.py +5 -0
  163. package/skills/video_manager/manifest.md +37 -0
  164. package/skills/video_manager/scanner.py +229 -0
  165. package/webui/__init__.py +3 -0
  166. package/webui/app.py +936 -0
  167. package/webui/bridge.py +366 -0
  168. package/webui/static/index.html +2070 -0
@@ -0,0 +1,366 @@
1
+ """
2
+ WebUI Bridge - Connects Alive-AI's nervous system to the dashboard
3
+ """
4
+
5
+ import asyncio
6
+ from datetime import datetime
7
+ from .app import (
8
+ update_state, add_conversation, alive_ai_state, update_soul_state, set_soul_orchestrator,
9
+ update_interoceptive_state, update_idle_state, update_bids_state,
10
+ update_memory_state, update_inconsistency_state
11
+ )
12
+
13
+
14
+ def init_bridge(nervous):
15
+ """Connect nervous system events to webui updates"""
16
+
17
+ async def on_emotion(data):
18
+ """Update emotion state in dashboard"""
19
+ update_state({
20
+ "mood": data.get("mood", "neutral"),
21
+ "arousal": data.get("arousal", 0),
22
+ "desire": data.get("desire", 0),
23
+ "love": data.get("love", 0),
24
+ "joy": data.get("joy", 0),
25
+ "sadness": data.get("sadness", 0),
26
+ "trust": data.get("trust", 0.5),
27
+ "fear": data.get("fear", 0),
28
+ "anger": data.get("anger", 0),
29
+ "boredom": data.get("boredom", 0),
30
+ "guilt": data.get("guilt", 0),
31
+ "pride": data.get("pride", 0),
32
+ "jealousy": data.get("jealousy", 0),
33
+ "embarrassment": data.get("embarrassment", 0),
34
+ "anticipation": data.get("anticipation", 0),
35
+ "hope": data.get("hope", 0.5),
36
+ "dread": data.get("dread", 0),
37
+ "is_high_desire": data.get("is_high_desire", False),
38
+ "is_in_love": data.get("is_in_love", False),
39
+ })
40
+
41
+ async def on_message_sent(data):
42
+ """Track outgoing messages"""
43
+ text = data.get("text", "")
44
+ add_conversation("alive_ai", text)
45
+ alive_ai_state["stats"]["messages"] = alive_ai_state["stats"].get("messages", 0) + 1
46
+ update_state({})
47
+
48
+ async def on_message_received(data):
49
+ """Track incoming messages"""
50
+ text = data.get("text", "")
51
+ user_id = data.get("user_id", "unknown")
52
+ add_conversation("user", text)
53
+ # Track active user
54
+ alive_ai_state["active_user"] = user_id
55
+
56
+ async def on_memory_save(data):
57
+ """Track memory saves"""
58
+ alive_ai_state["stats"]["memories"] = alive_ai_state["stats"].get("memories", 0) + 1
59
+ update_state({})
60
+
61
+ async def on_subconscious(data):
62
+ """Track subconscious impulse thoughts"""
63
+ thought = data.get("thought", "")
64
+ impulse_type = data.get("impulse_type", "impulse")
65
+ if thought:
66
+ alive_ai_state["current_thought"] = thought
67
+ alive_ai_state["stats"]["evaluations"] = alive_ai_state["stats"].get("evaluations", 0) + 1
68
+ # Store recent thoughts for the dashboard
69
+ if "recent_thoughts" not in alive_ai_state:
70
+ alive_ai_state["recent_thoughts"] = []
71
+ alive_ai_state["recent_thoughts"].append({
72
+ "thought": thought,
73
+ "type": impulse_type,
74
+ "emotion": {},
75
+ "time": __import__("datetime").datetime.now().strftime("%H:%M:%S")
76
+ })
77
+ # Keep last 10 thoughts
78
+ alive_ai_state["recent_thoughts"] = alive_ai_state["recent_thoughts"][-10:]
79
+ update_state({})
80
+
81
+ async def on_subconscious_thought(data):
82
+ """Track background thoughts from subconscious"""
83
+ thought = data.get("thought", "")
84
+ thought_type = data.get("type", "reflection")
85
+ emotion = data.get("emotion", {})
86
+ if thought:
87
+ alive_ai_state["current_thought"] = thought
88
+ alive_ai_state["stats"]["evaluations"] = alive_ai_state["stats"].get("evaluations", 0) + 1
89
+ # Store recent thoughts for the dashboard
90
+ if "recent_thoughts" not in alive_ai_state:
91
+ alive_ai_state["recent_thoughts"] = []
92
+ alive_ai_state["recent_thoughts"].append({
93
+ "thought": thought,
94
+ "type": thought_type,
95
+ "emotion": emotion,
96
+ "time": __import__("datetime").datetime.now().strftime("%H:%M:%S")
97
+ })
98
+ # Keep last 10 thoughts
99
+ alive_ai_state["recent_thoughts"] = alive_ai_state["recent_thoughts"][-10:]
100
+ update_state({})
101
+
102
+ async def on_soul_tick_event(data):
103
+ """Update soul state on each tick from heart/core.py"""
104
+ try:
105
+ update_soul_state(data)
106
+ except Exception as e:
107
+ print(f"[WebUI] Error on soul tick event: {e}")
108
+
109
+ # ============================================================
110
+ # Aliveness Event Handlers
111
+ # ============================================================
112
+
113
+ async def on_interoceptive_update(data):
114
+ """Update interoceptive states from the interoception system"""
115
+ try:
116
+ update_interoceptive_state(data)
117
+ except Exception as e:
118
+ print(f"[WebUI] Error updating interoceptive state: {e}")
119
+
120
+ async def on_idle_thought(data):
121
+ """Track idle thoughts from default mode processor"""
122
+ try:
123
+ # Add to recent bids/thoughts
124
+ update_idle_state({
125
+ "recent_thoughts": [data] if isinstance(data, dict) else [],
126
+ "last_processing": datetime.now().isoformat()
127
+ })
128
+ except Exception as e:
129
+ print(f"[WebUI] Error updating idle state: {e}")
130
+
131
+ async def on_default_mode_processed(data):
132
+ """Update default mode status"""
133
+ try:
134
+ update_idle_state({
135
+ "processing_count": data.get("processing_count", 0),
136
+ "pending_initiations": data.get("pending_count", 0),
137
+ "last_processing": datetime.now().isoformat()
138
+ })
139
+ except Exception as e:
140
+ print(f"[WebUI] Error updating default mode state: {e}")
141
+
142
+ async def on_bid_detected(data):
143
+ """Track emotional bid detections"""
144
+ try:
145
+ current_time = datetime.now().strftime("%H:%M:%S")
146
+ update_bids_state({
147
+ "last_bid_type": data.get("bid_type", data.get("type", "unknown")),
148
+ "last_bid_intensity": data.get("intensity", "unknown"),
149
+ "recent_bids": [
150
+ {
151
+ "type": data.get("bid_type", data.get("type", "unknown")),
152
+ "intensity": data.get("intensity", "unknown"),
153
+ "time": current_time
154
+ }
155
+ ]
156
+ })
157
+ except Exception as e:
158
+ print(f"[WebUI] Error updating bids state: {e}")
159
+
160
+ async def on_emotional_memory(data):
161
+ """Track emotional memory events"""
162
+ try:
163
+ update_memory_state({
164
+ "total_memories": data.get("total_memories", 0),
165
+ "average_weight": data.get("average_weight", 0),
166
+ "last_significant_memory": data.get("content", data.get("last_memory"))[:100] if data.get("content") or data.get("last_memory") else None
167
+ })
168
+ except Exception as e:
169
+ print(f"[WebUI] Error updating memory state: {e}")
170
+
171
+ async def on_inconsistency_update(data):
172
+ """Update inconsistency state"""
173
+ try:
174
+ update_inconsistency_state(data)
175
+ except Exception as e:
176
+ print(f"[WebUI] Error updating inconsistency state: {e}")
177
+
178
+ # Register event listeners
179
+ nervous.on("emotion_update", on_emotion)
180
+ nervous.on("send_text", on_message_sent)
181
+ nervous.on("send_voice_file", on_message_sent)
182
+ nervous.on("message_received", on_message_received)
183
+ nervous.on("memory_save", on_memory_save)
184
+ nervous.on("subconscious_impulse", on_subconscious)
185
+ nervous.on("subconscious_thought", on_subconscious_thought)
186
+ nervous.on("soul_tick", on_soul_tick_event)
187
+
188
+ # Register aliveness event listeners
189
+ nervous.on("interoceptive_update", on_interoceptive_update)
190
+ nervous.on("idle_thought", on_idle_thought)
191
+ nervous.on("default_mode_processed", on_default_mode_processed)
192
+ nervous.on("bid_detected", on_bid_detected)
193
+ nervous.on("emotional_memory", on_emotional_memory)
194
+ nervous.on("inconsistency_update", on_inconsistency_update)
195
+
196
+ print("[WebUI] Bridge connected to nervous system")
197
+
198
+
199
+ def init_soul_bridge(soul_orchestrator):
200
+ """Connect Soul Architecture to the dashboard"""
201
+
202
+ # Set the orchestrator reference
203
+ set_soul_orchestrator(soul_orchestrator)
204
+
205
+ # Get initial state
206
+ try:
207
+ initial_state = soul_orchestrator.get_state_summary()
208
+ update_soul_state(initial_state)
209
+ print("[WebUI] Soul Architecture connected to dashboard")
210
+ except Exception as e:
211
+ print(f"[WebUI] Error connecting Soul Architecture: {e}")
212
+
213
+
214
+ def on_soul_tick(soul_orchestrator):
215
+ """Called on each soul tick to update dashboard"""
216
+ try:
217
+ state = soul_orchestrator.get_state_summary()
218
+ update_soul_state(state)
219
+ except Exception as e:
220
+ print(f"[WebUI] Error on soul tick: {e}")
221
+
222
+
223
+ def on_soul_experience(experience):
224
+ """Called when a new emotional experience is generated"""
225
+ from .app import soul_state
226
+ try:
227
+ soul_state["current_experience"] = {
228
+ "valence": experience.overall_valence,
229
+ "arousal": experience.overall_arousal,
230
+ "vulnerability": experience.overall_vulnerability,
231
+ "response_tendency": experience.response_tendency,
232
+ "description": experience.experience_description
233
+ }
234
+ soul_state["somatic"]["sensation_summary"] = experience.somatic_sensation
235
+ update_soul_state(soul_state)
236
+ except Exception as e:
237
+ print(f"[WebUI] Error on soul experience: {e}")
238
+
239
+
240
+ def init_aliveness_bridge():
241
+ """
242
+ Initialize connections to aliveness modules and fetch initial state.
243
+ Call this after the aliveness modules are initialized.
244
+ """
245
+ # Try to connect to interoceptive system
246
+ try:
247
+ from heart.interoception import get_interoceptive_system
248
+ system = get_interoceptive_system()
249
+ states = system.get_state_values()
250
+ report = system.get_feeling_report()
251
+
252
+ update_interoceptive_state({
253
+ "states": {name: {"current_value": val} for name, val in states.items()},
254
+ "bodily_description": report.bodily_description if report else "feeling balanced",
255
+ "needs": report.needs if report else []
256
+ })
257
+ print("[WebUI] Connected to Interoceptive System")
258
+ except Exception as e:
259
+ print(f"[WebUI] Could not connect to Interoceptive System: {e}")
260
+
261
+ # Try to connect to default mode processor
262
+ try:
263
+ from brain.default_mode import get_default_mode_processor
264
+ processor = get_default_mode_processor()
265
+ if processor:
266
+ status = processor.get_status()
267
+ update_idle_state({
268
+ "running": status.get("running", False),
269
+ "pending_initiations": status.get("pending_initiations", 0),
270
+ "last_processing": status.get("last_processing")
271
+ })
272
+ print("[WebUI] Connected to Default Mode Processor")
273
+ except Exception as e:
274
+ print(f"[WebUI] Could not connect to Default Mode Processor: {e}")
275
+
276
+ # Try to connect to emotional memory system
277
+ try:
278
+ from brain.emotional_memory import get_emotional_memory_system
279
+ system = get_emotional_memory_system()
280
+ stats = system.get_stats()
281
+
282
+ update_memory_state({
283
+ "total_memories": stats.get("total_memories", 0),
284
+ "average_weight": stats.get("average_weight", 0),
285
+ "high_emotion_count": stats.get("high_emotion_count", 0)
286
+ })
287
+ print("[WebUI] Connected to Emotional Memory System")
288
+ except Exception as e:
289
+ print(f"[WebUI] Could not connect to Emotional Memory System: {e}")
290
+
291
+ # Try to connect to inconsistency engine
292
+ try:
293
+ from heart.inconsistency import get_inconsistency_engine
294
+ engine = get_inconsistency_engine()
295
+ modifier = engine.get_inconsistency_modifier()
296
+
297
+ update_inconsistency_state({
298
+ "active_conflicts": modifier.get("active_conflicts", []),
299
+ "mood": modifier.get("mood", {"state": "content"}),
300
+ "behavioral_tendency": modifier.get("behavioral_tendency", "neutral")
301
+ })
302
+ print("[WebUI] Connected to Inconsistency Engine")
303
+ except Exception as e:
304
+ print(f"[WebUI] Could not connect to Inconsistency Engine: {e}")
305
+
306
+ print("[WebUI] Aliveness bridge initialized")
307
+
308
+
309
+ def update_all_aliveness_states():
310
+ """
311
+ Refresh all aliveness states from their respective modules.
312
+ Call this periodically to keep the dashboard up to date.
313
+ """
314
+ # Interoceptive
315
+ try:
316
+ from heart.interoception import get_interoceptive_system
317
+ system = get_interoceptive_system()
318
+ states = system.get_state_values()
319
+ report = system.get_feeling_report()
320
+
321
+ update_interoceptive_state({
322
+ "states": {name: {"current_value": val} for name, val in states.items()},
323
+ "bodily_description": report.bodily_description if report else "feeling balanced"
324
+ })
325
+ except Exception:
326
+ pass
327
+
328
+ # Inconsistency
329
+ try:
330
+ from heart.inconsistency import get_inconsistency_engine
331
+ engine = get_inconsistency_engine()
332
+ modifier = engine.get_inconsistency_modifier()
333
+
334
+ update_inconsistency_state({
335
+ "active_conflicts": modifier.get("active_conflicts", []),
336
+ "mood": modifier.get("mood", {"state": "content"}),
337
+ "behavioral_tendency": modifier.get("behavioral_tendency", "neutral")
338
+ })
339
+ except Exception:
340
+ pass
341
+
342
+ # Memory stats
343
+ try:
344
+ from brain.emotional_memory import get_emotional_memory_system
345
+ system = get_emotional_memory_system()
346
+ stats = system.get_stats()
347
+
348
+ update_memory_state({
349
+ "total_memories": stats.get("total_memories", 0),
350
+ "average_weight": stats.get("average_weight", 0),
351
+ "high_emotion_count": stats.get("high_emotion_count", 0)
352
+ })
353
+ except Exception:
354
+ pass
355
+
356
+
357
+ async def start_webui(host: str = "0.0.0.0", port: int = 8080):
358
+ """Start the webui server"""
359
+ import uvicorn
360
+ from .app import app
361
+
362
+ config = uvicorn.Config(app, host=host, port=port, log_level="warning")
363
+ server = uvicorn.Server(config)
364
+
365
+ print(f"[WebUI] Dashboard starting at http://{host}:{port}")
366
+ await server.serve()