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,190 @@
1
+ """
2
+ Output: Vibe TTS
3
+ Connect to VibeVoice server for natural text-to-speech
4
+
5
+ Max 5000 chars per request - splits longer texts into parts
6
+ """
7
+
8
+ import aiohttp
9
+ import asyncio
10
+ import re
11
+ import tempfile
12
+ import subprocess
13
+ from pathlib import Path
14
+
15
+ VOICE_OUTPUT_PATH = "/tmp/alive_ai_voice.ogg"
16
+ MAX_CHARS = 5000 # VibeTTS limit
17
+
18
+
19
+ class VibeTTS:
20
+ """Text-to-speech via VibeVoice server"""
21
+
22
+ DEFAULT_VOICE = "en-Emma_woman"
23
+
24
+ CFG_MOOD = {
25
+ "chill": 1.5, "neutral": 1.5, "happy": 1.6,
26
+ "flirty": 1.6, "excited": 1.7, "high_desire": 1.9, "intense": 2.0
27
+ }
28
+
29
+ def __init__(self, url: str = "http://localhost:8080"):
30
+ self.url = url.rstrip("/")
31
+
32
+ def prepare_text(self, text: str) -> str:
33
+ """Clean text for TTS - removes formatting and EMOJIS"""
34
+ # Remove markdown formatting
35
+ text = re.sub(r'\*+[^*]+\*+', '', text) # Remove *bold*/**bold** content
36
+ text = text.replace("__", "").replace("_", "").replace("~", "")
37
+ text = re.sub(r'\.{3,}', '...', text)
38
+ text = re.sub(r'!{2,}', '!', text)
39
+ text = re.sub(r'\?{2,}', '?', text)
40
+
41
+ # Remove ALL emojis - they break TTS
42
+ text = re.sub(r'[\U00010000-\U0010ffff]', '', text)
43
+ # Remove common emoji ranges
44
+ text = re.sub(r'[\U0001F600-\U0001F64F]', '', text) # emoticons
45
+ text = re.sub(r'[\U0001F300-\U0001F5FF]', '', text) # symbols & pictographs
46
+ text = re.sub(r'[\U0001F680-\U0001F6FF]', '', text) # transport & map
47
+ text = re.sub(r'[\U0001F700-\U0001F77F]', '', text) # alchemical
48
+ text = re.sub(r'[\U0001F780-\U0001F7FF]', '', text) # Geometric Shapes
49
+ text = re.sub(r'[\U0001F800-\U0001F8FF]', '', text) # Supplemental Arrows-C
50
+ text = re.sub(r'[\U0001F900-\U0001F9FF]', '', text) # Supplemental Symbols and Pictographs
51
+ text = re.sub(r'[\U0001FA00-\U0001FA6F]', '', text) # Chess Symbols
52
+ text = re.sub(r'[\U0001FA70-\U0001FAFF]', '', text) # Symbols and Pictographs Extended-A
53
+ text = re.sub(r'[\U00002702-\U000027B0]', '', text) # Dingbats
54
+ text = re.sub(r'[\U000024C2-\U0001F251]', '', text) # Enclosed characters
55
+ text = re.sub(r'[\U0001F1E0-\U0001F1FF]', '', text) # Flags
56
+
57
+ # Clean up extra spaces
58
+ text = re.sub(r'\s+', ' ', text)
59
+ return text.strip()
60
+
61
+ def split_text(self, text: str) -> list:
62
+ """Split long text at paragraph boundaries"""
63
+ if len(text) <= MAX_CHARS:
64
+ return [text]
65
+
66
+ parts = []
67
+ paragraphs = text.split('\n\n')
68
+ current = ""
69
+
70
+ for para in paragraphs:
71
+ if len(current) + len(para) + 2 <= MAX_CHARS:
72
+ current = current + "\n\n" + para if current else para
73
+ else:
74
+ if current:
75
+ parts.append(current)
76
+ # If single paragraph is too long, split by sentences
77
+ if len(para) > MAX_CHARS:
78
+ sentences = para.replace('. ', '.\n').split('\n')
79
+ chunk = ""
80
+ for s in sentences:
81
+ if len(chunk) + len(s) + 1 <= MAX_CHARS:
82
+ chunk = chunk + " " + s if chunk else s
83
+ else:
84
+ if chunk:
85
+ parts.append(chunk)
86
+ chunk = s
87
+ if chunk:
88
+ parts.append(chunk)
89
+ else:
90
+ current = para
91
+
92
+ if current:
93
+ parts.append(current)
94
+
95
+ return parts
96
+
97
+ def get_cfg_for_mood(self, mood: str) -> float:
98
+ return self.CFG_MOOD.get(mood, 1.5)
99
+
100
+ async def generate(self, text: str, voice: str = None,
101
+ cfg: float = None, mood: str = "neutral") -> str:
102
+ """Generate audio - handles long texts by splitting"""
103
+ if voice is None:
104
+ voice = self.DEFAULT_VOICE
105
+ if cfg is None:
106
+ cfg = self.get_cfg_for_mood(mood)
107
+
108
+ text = self.prepare_text(text)
109
+ print(f"[VibeTTS] Generating voice for {len(text)} chars...")
110
+
111
+ # Split if needed
112
+ parts = self.split_text(text)
113
+ if len(parts) > 1:
114
+ print(f"[VibeTTS] Split into {len(parts)} parts")
115
+
116
+ audio_parts = []
117
+ for i, part in enumerate(parts):
118
+ print(f"[VibeTTS] Processing part {i+1}/{len(parts)} ({len(part)} chars)")
119
+ audio = await self._generate_single(part, voice, cfg)
120
+ if audio:
121
+ audio_parts.append(audio)
122
+ else:
123
+ print(f"[VibeTTS] Part {i+1} failed")
124
+
125
+ if not audio_parts:
126
+ return ""
127
+
128
+ # Combine all parts
129
+ if len(audio_parts) == 1:
130
+ Path(VOICE_OUTPUT_PATH).write_bytes(audio_parts[0])
131
+ else:
132
+ # Use ffmpeg to properly concatenate OGG files
133
+ temp_files = []
134
+ try:
135
+ for i, part in enumerate(audio_parts):
136
+ tf = tempfile.NamedTemporaryFile(suffix=".ogg", delete=False)
137
+ tf.write(part)
138
+ tf.close()
139
+ temp_files.append(tf.name)
140
+ # Create concat list file
141
+ list_file = tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False)
142
+ for tf_name in temp_files:
143
+ list_file.write(f"file '{tf_name}'\n")
144
+ list_file.close()
145
+ subprocess.run(
146
+ ["ffmpeg", "-y", "-f", "concat", "-safe", "0",
147
+ "-i", list_file.name, "-c", "copy", VOICE_OUTPUT_PATH],
148
+ capture_output=True, timeout=30
149
+ )
150
+ Path(list_file.name).unlink(missing_ok=True)
151
+ except Exception as e:
152
+ print(f"[VibeTTS] ffmpeg concat failed, using first part: {e}")
153
+ Path(VOICE_OUTPUT_PATH).write_bytes(audio_parts[0])
154
+ finally:
155
+ for tf_name in temp_files:
156
+ Path(tf_name).unlink(missing_ok=True)
157
+ print(f"[VibeTTS] Generated audio file")
158
+ return VOICE_OUTPUT_PATH
159
+
160
+ async def _generate_single(self, text: str, voice: str, cfg: float) -> bytes:
161
+ """Generate single audio part"""
162
+ try:
163
+ async with aiohttp.ClientSession() as session:
164
+ params = {"text": text, "voice": voice, "cfg": str(cfg)}
165
+ async with session.get(
166
+ f"{self.url}/tts",
167
+ params=params,
168
+ timeout=aiohttp.ClientTimeout(total=600)
169
+ ) as resp:
170
+ if resp.status == 200:
171
+ return await resp.read()
172
+ else:
173
+ error = await resp.text()
174
+ print(f"[VibeTTS] Error {resp.status}: {error[:200]}")
175
+ return b""
176
+ except asyncio.TimeoutError:
177
+ print("[VibeTTS] Timeout")
178
+ return b""
179
+ except Exception as e:
180
+ print(f"[VibeTTS] Error: {e}")
181
+ return b""
182
+
183
+ async def is_available(self) -> bool:
184
+ """Check if server is available"""
185
+ try:
186
+ async with aiohttp.ClientSession() as session:
187
+ async with session.get(f"{self.url}/health", timeout=2) as resp:
188
+ return resp.status == 200
189
+ except:
190
+ return False
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "alive-ai",
3
+ "version": "0.1.0",
4
+ "description": "Local-first emotional AI runtime with memory, impulses, and a live dashboard.",
5
+ "license": "MIT",
6
+ "homepage": "https://vindepemarte.github.io/alive-ai/",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/vindepemarte/alive-ai.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/vindepemarte/alive-ai/issues"
13
+ },
14
+ "bin": {
15
+ "alive-ai": "cli/index.js"
16
+ },
17
+ "files": [
18
+ "alive_ai",
19
+ "brain",
20
+ "cli",
21
+ "config/*.example.json",
22
+ "config/*.example.md",
23
+ "core",
24
+ "demo",
25
+ "docs",
26
+ "heart",
27
+ "input",
28
+ "main.py",
29
+ "manifest.md",
30
+ "mypics/.gitkeep",
31
+ "myvids/.gitkeep",
32
+ "output",
33
+ "requirements.txt",
34
+ "skills",
35
+ "webui",
36
+ "Dockerfile",
37
+ "docker-compose.yml",
38
+ "LICENSE",
39
+ "README.md",
40
+ "pyproject.toml"
41
+ ],
42
+ "keywords": [
43
+ "ai",
44
+ "agent",
45
+ "companion",
46
+ "emotional-ai",
47
+ "local-first",
48
+ "memory",
49
+ "telegram",
50
+ "dashboard"
51
+ ],
52
+ "engines": {
53
+ "node": ">=18"
54
+ },
55
+ "scripts": {
56
+ "smoke": "node cli/index.js --help && python3 -m compileall -q alive_ai brain core heart input output skills webui"
57
+ }
58
+ }
package/pyproject.toml ADDED
@@ -0,0 +1,23 @@
1
+ [project]
2
+ name = "alive-ai-runtime"
3
+ version = "0.1.0"
4
+ description = "Local-first emotional AI runtime with memory, impulses, and a live dashboard."
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ license = { text = "MIT" }
8
+ authors = [{ name = "Vindepemarte" }]
9
+
10
+ [tool.setuptools]
11
+ py-modules = ["main"]
12
+
13
+ [tool.setuptools.packages.find]
14
+ include = [
15
+ "alive_ai*",
16
+ "brain*",
17
+ "core*",
18
+ "heart*",
19
+ "input*",
20
+ "output*",
21
+ "skills*",
22
+ "webui*"
23
+ ]
@@ -0,0 +1,21 @@
1
+ aiohttp>=3.9.0
2
+ python-telegram-bot>=20.0
3
+ SpeechRecognition>=3.10.0
4
+
5
+ # Embedding model
6
+ sentence-transformers>=2.2.0
7
+ torch>=2.0.0
8
+
9
+ # Redis with vector search
10
+ redis>=5.0.0
11
+ watchdog
12
+ fastapi>=0.100.0
13
+ uvicorn>=0.23.0
14
+ sse-starlette>=1.6.0
15
+
16
+ # TTS
17
+ gtts>=2.3.0
18
+ pydub>=0.25.0
19
+
20
+ # Memory monitoring
21
+ psutil>=5.9.0
@@ -0,0 +1 @@
1
+ """Skills"""
@@ -0,0 +1,8 @@
1
+ """
2
+ Anticipation Engine Skill
3
+ Builds anticipation for future content/drops, making users eager to return
4
+ """
5
+
6
+ from .engine import AnticipationEngine
7
+
8
+ __all__ = ["AnticipationEngine"]