@johpaz/hive-sdk 0.0.12 → 0.0.15

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 (199) hide show
  1. package/.github/CODEOWNERS +9 -0
  2. package/.github/workflows/publish.yml +89 -0
  3. package/.github/workflows/version-bump.yml +102 -0
  4. package/CHANGELOG.md +38 -0
  5. package/README.md +158 -0
  6. package/bun.lock +543 -0
  7. package/bunfig.toml +7 -0
  8. package/docs/API-AGENTS.md +316 -0
  9. package/docs/API-CONTEXT-COMPILER.md +252 -0
  10. package/docs/API-DAG-SCHEDULER.md +273 -0
  11. package/docs/API-TOOLS-SKILLS-CHANNELS.md +293 -0
  12. package/docs/API-WORKERS-EVENTS.md +152 -0
  13. package/docs/INDEX.md +141 -0
  14. package/docs/README.md +68 -0
  15. package/package.json +54 -105
  16. package/packages/cli/package.json +17 -0
  17. package/packages/cli/src/commands/init.ts +56 -0
  18. package/packages/cli/src/commands/run.ts +45 -0
  19. package/packages/cli/src/commands/test.ts +42 -0
  20. package/packages/cli/src/commands/trace.ts +55 -0
  21. package/packages/cli/src/index.ts +43 -0
  22. package/packages/core/package.json +58 -0
  23. package/packages/core/src/ace/Curator.ts +158 -0
  24. package/packages/core/src/ace/Reflector.ts +200 -0
  25. package/packages/core/src/ace/Tracer.ts +100 -0
  26. package/packages/core/src/ace/index.ts +4 -0
  27. package/packages/core/src/agent/AgentRunner.ts +699 -0
  28. package/packages/core/src/agent/Compaction.ts +221 -0
  29. package/packages/core/src/agent/ContextCompiler.ts +567 -0
  30. package/packages/core/src/agent/ContextGuard.ts +91 -0
  31. package/packages/core/src/agent/ConversationStore.ts +244 -0
  32. package/packages/core/src/agent/Hooks.ts +166 -0
  33. package/packages/core/src/agent/NativeTools.ts +31 -0
  34. package/packages/core/src/agent/PromptBuilder.ts +169 -0
  35. package/packages/core/src/agent/Service.ts +267 -0
  36. package/packages/core/src/agent/StuckLoop.ts +133 -0
  37. package/packages/core/src/agent/index.ts +12 -0
  38. package/packages/core/src/agent/providers/LLMClient.ts +149 -0
  39. package/packages/core/src/agent/providers/anthropic.ts +212 -0
  40. package/packages/core/src/agent/providers/gemini.ts +215 -0
  41. package/packages/core/src/agent/providers/index.ts +199 -0
  42. package/packages/core/src/agent/providers/interface.ts +195 -0
  43. package/packages/core/src/agent/providers/ollama.ts +175 -0
  44. package/packages/core/src/agent/providers/openai-compat.ts +231 -0
  45. package/packages/core/src/agent/providers.ts +1 -0
  46. package/packages/core/src/agent/selectors/PlaybookSelector.ts +147 -0
  47. package/packages/core/src/agent/selectors/SkillSelector.ts +478 -0
  48. package/packages/core/src/agent/selectors/ToolSelector.ts +577 -0
  49. package/packages/core/src/agent/selectors/index.ts +6 -0
  50. package/packages/core/src/api/createAgent.test.ts +48 -0
  51. package/packages/core/src/api/createAgent.ts +122 -0
  52. package/packages/core/src/api/index.ts +2 -0
  53. package/packages/core/src/canvas/CanvasManager.ts +390 -0
  54. package/packages/core/src/canvas/a2ui-tools.ts +255 -0
  55. package/packages/core/src/canvas/canvas-tools.ts +448 -0
  56. package/packages/core/src/canvas/emitter.ts +149 -0
  57. package/packages/core/src/canvas/index.ts +6 -0
  58. package/packages/core/src/config/index.ts +2 -0
  59. package/packages/core/src/config/loader.ts +554 -0
  60. package/packages/core/src/ethics/EthicsGuard.test.ts +54 -0
  61. package/packages/core/src/ethics/EthicsGuard.ts +66 -0
  62. package/packages/core/src/ethics/index.ts +2 -0
  63. package/packages/core/src/gateway/channel-notify.test.ts +14 -0
  64. package/packages/core/src/gateway/channel-notify.ts +12 -0
  65. package/packages/core/src/gateway/index.ts +1 -0
  66. package/packages/core/src/index.ts +37 -0
  67. package/packages/core/src/mcp/MCPClient.ts +439 -0
  68. package/packages/core/src/mcp/MCPToolAdapter.ts +176 -0
  69. package/packages/core/src/mcp/config.ts +13 -0
  70. package/packages/core/src/mcp/hot-reload.ts +147 -0
  71. package/packages/core/src/mcp/index.ts +11 -0
  72. package/packages/core/src/mcp/logger.ts +42 -0
  73. package/packages/core/src/mcp/singleton.ts +21 -0
  74. package/packages/core/src/mcp/transports/index.ts +67 -0
  75. package/packages/core/src/mcp/transports/sse.ts +241 -0
  76. package/packages/core/src/mcp/transports/websocket.ts +159 -0
  77. package/packages/core/src/memory/Scratchpad.test.ts +47 -0
  78. package/packages/core/src/memory/Scratchpad.ts +37 -0
  79. package/packages/core/src/memory/Storage.ts +6 -0
  80. package/packages/core/src/memory/index.ts +2 -0
  81. package/packages/core/src/multimodal/VisionService.ts +293 -0
  82. package/packages/core/src/multimodal/index.ts +2 -0
  83. package/packages/core/src/multimodal/types.ts +28 -0
  84. package/packages/core/src/security/Pairing.ts +250 -0
  85. package/packages/core/src/security/RateLimit.ts +270 -0
  86. package/packages/core/src/security/index.ts +4 -0
  87. package/packages/core/src/skills/SkillLoader.ts +388 -0
  88. package/packages/core/src/skills/bundled-data.generated.ts +3332 -0
  89. package/packages/core/src/skills/defineSkill.ts +18 -0
  90. package/packages/core/src/skills/index.ts +4 -0
  91. package/packages/core/src/state/index.ts +2 -0
  92. package/packages/core/src/state/store.ts +312 -0
  93. package/packages/core/src/storage/SQLiteStorage.ts +407 -0
  94. package/packages/core/src/storage/crypto.ts +101 -0
  95. package/packages/core/src/storage/index.ts +10 -0
  96. package/packages/core/src/storage/onboarding.ts +1603 -0
  97. package/packages/core/src/storage/schema.ts +689 -0
  98. package/packages/core/src/storage/seed.ts +740 -0
  99. package/packages/core/src/storage/usage.ts +374 -0
  100. package/packages/core/src/swarm/AgentBus.ts +460 -0
  101. package/packages/core/src/swarm/AgentExecutor.ts +53 -0
  102. package/packages/core/src/swarm/Coordinator.ts +251 -0
  103. package/packages/core/src/swarm/EventBridge.ts +122 -0
  104. package/packages/core/src/swarm/EventBus.ts +169 -0
  105. package/packages/core/src/swarm/TaskGraph.ts +192 -0
  106. package/packages/core/src/swarm/TaskNode.ts +97 -0
  107. package/packages/core/src/swarm/TaskResult.ts +22 -0
  108. package/packages/core/src/swarm/WorkerPool.ts +236 -0
  109. package/packages/core/src/swarm/errors.ts +37 -0
  110. package/packages/core/src/swarm/index.ts +30 -0
  111. package/packages/core/src/swarm/presets/HiveLearnPreset.ts +99 -0
  112. package/packages/core/src/swarm/presets/ResearchPreset.ts +97 -0
  113. package/packages/core/src/swarm/presets/index.ts +4 -0
  114. package/packages/core/src/swarm/strategies/ParallelStrategy.ts +21 -0
  115. package/packages/core/src/swarm/strategies/PriorityStrategy.ts +46 -0
  116. package/packages/core/src/swarm/strategies/index.ts +3 -0
  117. package/packages/core/src/swarm/types.ts +164 -0
  118. package/packages/core/src/tools/ToolExecutor.ts +58 -0
  119. package/packages/core/src/tools/ToolRegistry.test.ts +98 -0
  120. package/packages/core/src/tools/ToolRegistry.ts +61 -0
  121. package/packages/core/src/tools/agents/get-available-models.ts +118 -0
  122. package/packages/core/src/tools/agents/index.ts +715 -0
  123. package/packages/core/src/tools/bridge-events.ts +26 -0
  124. package/packages/core/src/tools/canvas/index.ts +375 -0
  125. package/packages/core/src/tools/cli/index.ts +142 -0
  126. package/packages/core/src/tools/codebridge/index.ts +342 -0
  127. package/packages/core/src/tools/core/index.ts +476 -0
  128. package/packages/core/src/tools/cron/index.ts +626 -0
  129. package/packages/core/src/tools/filesystem/fs-delete.ts +78 -0
  130. package/packages/core/src/tools/filesystem/fs-edit.ts +106 -0
  131. package/packages/core/src/tools/filesystem/fs-exists.ts +63 -0
  132. package/packages/core/src/tools/filesystem/fs-glob.ts +108 -0
  133. package/packages/core/src/tools/filesystem/fs-list.ts +129 -0
  134. package/packages/core/src/tools/filesystem/fs-read.ts +72 -0
  135. package/packages/core/src/tools/filesystem/fs-write.ts +67 -0
  136. package/packages/core/src/tools/filesystem/index.ts +34 -0
  137. package/packages/core/src/tools/filesystem/workspace-guard.ts +62 -0
  138. package/packages/core/src/tools/index.ts +231 -0
  139. package/packages/core/src/tools/meeting/index.ts +363 -0
  140. package/packages/core/src/tools/office/index.ts +47 -0
  141. package/packages/core/src/tools/office/office-escribir-docx.ts +192 -0
  142. package/packages/core/src/tools/office/office-escribir-pdf.ts +172 -0
  143. package/packages/core/src/tools/office/office-escribir-pptx.ts +174 -0
  144. package/packages/core/src/tools/office/office-escribir-xlsx.ts +116 -0
  145. package/packages/core/src/tools/office/office-leer-docx.ts +93 -0
  146. package/packages/core/src/tools/office/office-leer-pdf.ts +114 -0
  147. package/packages/core/src/tools/office/office-leer-pptx.ts +136 -0
  148. package/packages/core/src/tools/office/office-leer-xlsx.ts +124 -0
  149. package/packages/core/src/tools/projects/index.ts +37 -0
  150. package/packages/core/src/tools/projects/project-create.ts +94 -0
  151. package/packages/core/src/tools/projects/project-done.ts +66 -0
  152. package/packages/core/src/tools/projects/project-fail.ts +66 -0
  153. package/packages/core/src/tools/projects/project-list.ts +96 -0
  154. package/packages/core/src/tools/projects/project-update.ts +72 -0
  155. package/packages/core/src/tools/projects/task-create.ts +68 -0
  156. package/packages/core/src/tools/projects/task-evaluate.ts +93 -0
  157. package/packages/core/src/tools/projects/task-update.ts +93 -0
  158. package/packages/core/src/tools/types.ts +39 -0
  159. package/packages/core/src/tools/voice/index.ts +104 -0
  160. package/packages/core/src/tools/web/browser-click.ts +78 -0
  161. package/packages/core/src/tools/web/browser-extract.ts +139 -0
  162. package/packages/core/src/tools/web/browser-navigate.ts +106 -0
  163. package/packages/core/src/tools/web/browser-screenshot.ts +87 -0
  164. package/packages/core/src/tools/web/browser-script.ts +88 -0
  165. package/packages/core/src/tools/web/browser-service.ts +554 -0
  166. package/packages/core/src/tools/web/browser-type.ts +101 -0
  167. package/packages/core/src/tools/web/browser-wait.ts +136 -0
  168. package/packages/core/src/tools/web/index.ts +41 -0
  169. package/packages/core/src/tools/web/web-fetch.ts +78 -0
  170. package/packages/core/src/tools/web/web-search.ts +123 -0
  171. package/packages/core/src/utils/benchmark.ts +80 -0
  172. package/packages/core/src/utils/crypto.ts +73 -0
  173. package/packages/core/src/utils/date.ts +42 -0
  174. package/packages/core/src/utils/index.ts +10 -0
  175. package/packages/core/src/utils/logger.ts +389 -0
  176. package/packages/core/src/utils/retry.ts +70 -0
  177. package/packages/core/src/utils/toon.ts +253 -0
  178. package/packages/core/src/voice/index.ts +656 -0
  179. package/test/setup-db.ts +216 -0
  180. package/tsconfig.json +39 -0
  181. package/src/agents.ts +0 -1
  182. package/src/canvas.ts +0 -1
  183. package/src/channels.ts +0 -1
  184. package/src/config.ts +0 -1
  185. package/src/events.ts +0 -1
  186. package/src/gateway.ts +0 -1
  187. package/src/index.ts +0 -304
  188. package/src/mcp.ts +0 -1
  189. package/src/multimodal.ts +0 -1
  190. package/src/scheduler.ts +0 -1
  191. package/src/security.ts +0 -1
  192. package/src/skills.ts +0 -1
  193. package/src/state.ts +0 -1
  194. package/src/storage.ts +0 -1
  195. package/src/tools.ts +0 -1
  196. package/src/tts.ts +0 -1
  197. package/src/types.ts +0 -82
  198. package/src/utils.ts +0 -1
  199. package/src/voice.ts +0 -1
@@ -0,0 +1,689 @@
1
+ export const SCHEMA = `
2
+ PRAGMA journal_mode = WAL;
3
+ PRAGMA foreign_keys = ON;
4
+
5
+ -- ENCRYPTION KEY (stored separately, used for encrypting sensitive data)
6
+ -- The encryption key is derived from HIVE_MASTER_KEY env var or generated on first run
7
+
8
+ -- CONFIGURATION (all linked to user)
9
+
10
+ CREATE TABLE IF NOT EXISTS users (
11
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
12
+ name TEXT,
13
+ language TEXT,
14
+ timezone TEXT,
15
+ occupation TEXT,
16
+ notes TEXT,
17
+ master_key_hash TEXT,
18
+ email TEXT UNIQUE,
19
+ password_hash TEXT,
20
+ preferred_cron_channel TEXT NOT NULL DEFAULT 'auto',
21
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
22
+ );
23
+
24
+ -- Providers: linked to user (API key encrypted)
25
+ -- Solo la empresa (OpenAI, Groq, ElevenLabs, etc.)
26
+ -- La API key es del provider, no del modelo
27
+ -- category: 'llm', 'stt', 'tts' (default: llm)
28
+ CREATE TABLE IF NOT EXISTS providers (
29
+ id TEXT PRIMARY KEY,
30
+ name TEXT NOT NULL UNIQUE,
31
+ api_key_encrypted TEXT,
32
+ api_key_iv TEXT,
33
+ headers_encrypted TEXT,
34
+ headers_iv TEXT,
35
+ base_url TEXT,
36
+ category TEXT NOT NULL DEFAULT 'llm',
37
+ num_ctx INTEGER,
38
+ num_gpu INTEGER DEFAULT -1,
39
+ enabled INTEGER NOT NULL DEFAULT 1,
40
+ active INTEGER NOT NULL DEFAULT 0,
41
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
42
+ );
43
+
44
+ -- Models: linked to provider
45
+ -- model_type: 'llm', 'stt', 'tts', 'vision', 'embedding'
46
+ -- stt models: whisper-1, whisper-large-v3
47
+ -- tts models: tts-1, gpt-4o-mini-tts, eleven_multilingual_v2
48
+ CREATE TABLE IF NOT EXISTS models (
49
+ id TEXT PRIMARY KEY,
50
+ provider_id TEXT REFERENCES providers(id) ON DELETE CASCADE,
51
+ name TEXT NOT NULL,
52
+ model_type TEXT NOT NULL DEFAULT 'llm',
53
+ context_window INTEGER NOT NULL DEFAULT 20000,
54
+ capabilities TEXT,
55
+ enabled INTEGER NOT NULL DEFAULT 1,
56
+ active INTEGER NOT NULL DEFAULT 0
57
+ );
58
+
59
+ -- Agents: linked to user + provider/model
60
+ -- role: 'coordinator' | 'worker'
61
+ -- system_prompt: explicit prompt (description is a human-readable summary)
62
+ -- tools_json: JSON array of tool IDs this agent can use (NULL = all)
63
+ -- skills_json: JSON array of skill IDs this agent can use (NULL = all)
64
+ -- parent_id: agent that created this one (NULL for coordinator)
65
+ -- max_iterations: loop limit per invocation
66
+ CREATE TABLE IF NOT EXISTS agents (
67
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
68
+ user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
69
+ name TEXT NOT NULL,
70
+ description TEXT,
71
+ system_prompt TEXT,
72
+ tone TEXT,
73
+ role TEXT NOT NULL DEFAULT 'coordinator' CHECK(role IN ('coordinator', 'worker')),
74
+ status TEXT NOT NULL DEFAULT 'idle',
75
+ enabled INTEGER NOT NULL DEFAULT 1,
76
+ provider_id TEXT REFERENCES providers(id),
77
+ model_id TEXT REFERENCES models(id),
78
+ tools_json TEXT,
79
+ skills_json TEXT,
80
+ parent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,
81
+ max_iterations INTEGER NOT NULL DEFAULT 10,
82
+ headers_encrypted TEXT,
83
+ headers_iv TEXT,
84
+ workspace TEXT,
85
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
86
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
87
+ );
88
+
89
+ -- Channels: linked to user (or global if user_id is NULL)
90
+ -- voice_enabled: enables speech-to-text for incoming audio
91
+ -- tts_enabled: enables text-to-speech for outgoing responses
92
+ -- stt_provider: which STT provider to use (groq-whisper, openai-whisper)
93
+ -- tts_provider: which TTS provider to use (elevenlabs, openai-tts)
94
+ -- tts_voice_id: specific voice ID for TTS (e.g., ElevenLabs voice ID)
95
+ -- step_delivery_mode: how to send intermediate steps to user:
96
+ -- "new_message" = send new message for each step (default)
97
+ -- "edit" = edit same message (Telegram/Discord only)
98
+ -- "thread" = use threading (Slack only)
99
+ -- vision_enabled: enables image/document processing for incoming media
100
+ -- ocr_provider: which provider to use for OCR fallback (openai, gemini, anthropic)
101
+ -- vision_provider: provider for vision-capable models
102
+ -- vision_model_id: specific model for vision processing
103
+ CREATE TABLE IF NOT EXISTS channels (
104
+ id TEXT PRIMARY KEY,
105
+ user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
106
+ type TEXT NOT NULL,
107
+ config_encrypted TEXT,
108
+ config_iv TEXT,
109
+ enabled INTEGER NOT NULL DEFAULT 1,
110
+ active INTEGER NOT NULL DEFAULT 0,
111
+ status TEXT NOT NULL DEFAULT 'disconnected',
112
+ last_active INTEGER,
113
+ voice_enabled INTEGER NOT NULL DEFAULT 0,
114
+ tts_enabled INTEGER NOT NULL DEFAULT 0,
115
+ stt_provider TEXT,
116
+ tts_provider TEXT,
117
+ tts_voice_id TEXT,
118
+ step_delivery_mode TEXT DEFAULT 'new_messages',
119
+ vision_enabled INTEGER NOT NULL DEFAULT 0,
120
+ ocr_provider TEXT,
121
+ vision_provider TEXT,
122
+ vision_model_id TEXT
123
+ );
124
+
125
+ -- MCP Servers: linked to user (or global if user_id is NULL)
126
+ CREATE TABLE IF NOT EXISTS mcp_servers (
127
+ id TEXT PRIMARY KEY,
128
+ name TEXT NOT NULL,
129
+ transport TEXT NOT NULL,
130
+ command TEXT,
131
+ args TEXT,
132
+ env_encrypted TEXT,
133
+ env_iv TEXT,
134
+ headers_encrypted TEXT,
135
+ headers_iv TEXT,
136
+ url TEXT,
137
+ enabled INTEGER NOT NULL DEFAULT 1,
138
+ active INTEGER NOT NULL DEFAULT 0,
139
+ builtin INTEGER NOT NULL DEFAULT 0,
140
+ status TEXT NOT NULL DEFAULT 'disconnected',
141
+ tools_count INTEGER DEFAULT 0
142
+ );
143
+
144
+ -- MCP Servers: external tool providers (stdio, SSE, etc.)
145
+ -- MCP tools are loaded at runtime from connected servers, not stored in DB
146
+ CREATE TABLE IF NOT EXISTS mcp_servers (
147
+ id TEXT PRIMARY KEY,
148
+ name TEXT NOT NULL,
149
+ transport TEXT NOT NULL,
150
+ command TEXT,
151
+ args TEXT,
152
+ env_encrypted TEXT,
153
+ env_iv TEXT,
154
+ headers_encrypted TEXT,
155
+ headers_iv TEXT,
156
+ url TEXT,
157
+ enabled INTEGER NOT NULL DEFAULT 1,
158
+ active INTEGER NOT NULL DEFAULT 0,
159
+ builtin INTEGER NOT NULL DEFAULT 0,
160
+ status TEXT NOT NULL DEFAULT 'disconnected',
161
+ tools_count INTEGER DEFAULT 0
162
+ );
163
+
164
+ -- Note: MCP tools are NOT stored in DB. They are loaded from MCP servers at runtime
165
+ -- and made available directly via context-compiler (Direct Connection architecture)
166
+
167
+ -- Skills: can be global (system) or user-specific
168
+ -- v0.0.28: expanded schema with description, author, icon, permissions, dependencies, preferred_agents
169
+ CREATE TABLE IF NOT EXISTS skills (
170
+ id TEXT PRIMARY KEY,
171
+ name TEXT NOT NULL,
172
+ description TEXT,
173
+ version TEXT DEFAULT '0.0.1',
174
+ author TEXT DEFAULT 'Anonymous',
175
+ icon TEXT DEFAULT '🧩',
176
+ category TEXT NOT NULL,
177
+ permissions TEXT,
178
+ dependencies TEXT,
179
+ tools TEXT NOT NULL,
180
+ triggers TEXT NOT NULL,
181
+ preferred_agents TEXT,
182
+ body TEXT NOT NULL,
183
+ version_num INTEGER DEFAULT 1,
184
+ active INTEGER DEFAULT 1,
185
+ created_at TEXT DEFAULT (datetime('now')),
186
+ updated_at TEXT DEFAULT (datetime('now'))
187
+ );
188
+
189
+ -- Índices para filtros directos
190
+ CREATE INDEX IF NOT EXISTS idx_skills_category ON skills(category);
191
+ CREATE INDEX IF NOT EXISTS idx_skills_active ON skills(active);
192
+
193
+ -- Tools: global (bundled), not user-specific
194
+ -- category: 'bundled', 'workspace', 'project', 'builtin', 'voice'
195
+ CREATE TABLE IF NOT EXISTS tools (
196
+ id TEXT PRIMARY KEY,
197
+ name TEXT NOT NULL UNIQUE,
198
+ description TEXT,
199
+ category TEXT,
200
+ enabled INTEGER NOT NULL DEFAULT 1,
201
+ active INTEGER NOT NULL DEFAULT 1,
202
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
203
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
204
+ );
205
+
206
+ -- Ethics: global templates (user selects one)
207
+ CREATE TABLE IF NOT EXISTS ethics (
208
+ id TEXT PRIMARY KEY,
209
+ name TEXT NOT NULL,
210
+ description TEXT,
211
+ content TEXT NOT NULL,
212
+ is_default INTEGER NOT NULL DEFAULT 0,
213
+ enabled INTEGER NOT NULL DEFAULT 1,
214
+ active INTEGER NOT NULL DEFAULT 0
215
+ );
216
+
217
+ -- Code Bridge: external CLI tools configuration (global)
218
+ CREATE TABLE IF NOT EXISTS code_bridge (
219
+ id TEXT PRIMARY KEY,
220
+ user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
221
+ name TEXT NOT NULL UNIQUE,
222
+ cli_command TEXT NOT NULL,
223
+ enabled INTEGER NOT NULL DEFAULT 0,
224
+ active INTEGER NOT NULL DEFAULT 0,
225
+ port INTEGER DEFAULT 18791,
226
+ config TEXT
227
+ );
228
+
229
+ -- Code Bridge Config: key-value store for configuration (voice_wake_word, etc.)
230
+ CREATE TABLE IF NOT EXISTS code_bridge_config (
231
+ id TEXT PRIMARY KEY,
232
+ user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
233
+ key TEXT NOT NULL,
234
+ value TEXT,
235
+ UNIQUE(user_id, key)
236
+ );
237
+
238
+ -- USER IDENTITIES (channel + user mapping)
239
+
240
+ CREATE TABLE IF NOT EXISTS user_identities (
241
+ user_id TEXT NOT NULL REFERENCES users(id),
242
+ channel TEXT NOT NULL,
243
+ channel_user_id TEXT NOT NULL,
244
+ linked_at INTEGER NOT NULL DEFAULT (unixepoch()),
245
+ PRIMARY KEY (user_id, channel)
246
+ );
247
+
248
+ -- USER CHANNELS (user-specific channel configurations)
249
+ -- Stores per-user channel account configurations (Telegram bot, Discord bot, etc.)
250
+ -- config: JSON object with channel-specific settings (bot token, webhook URL, etc.)
251
+ -- active: 1 = enabled and running, 0 = disabled
252
+ CREATE TABLE IF NOT EXISTS user_channels (
253
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
254
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
255
+ channel TEXT NOT NULL,
256
+ account_id TEXT NOT NULL,
257
+ config TEXT,
258
+ active INTEGER NOT NULL DEFAULT 1,
259
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
260
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
261
+ UNIQUE(user_id, channel, account_id)
262
+ );
263
+
264
+ CREATE INDEX IF NOT EXISTS idx_user_channels_user ON user_channels(user_id);
265
+ CREATE INDEX IF NOT EXISTS idx_user_channels_channel ON user_channels(channel);
266
+
267
+ -- ONBOARDING PROGRESS
268
+
269
+ CREATE TABLE IF NOT EXISTS onboarding_progress (
270
+ id TEXT PRIMARY KEY,
271
+ user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
272
+ step TEXT NOT NULL,
273
+ data TEXT,
274
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
275
+ );
276
+
277
+ -- USAGE TRACKING (tokens, costs)
278
+ CREATE TABLE IF NOT EXISTS usage_records (
279
+ id TEXT PRIMARY KEY,
280
+ provider TEXT NOT NULL,
281
+ model TEXT NOT NULL,
282
+ input_tokens INTEGER NOT NULL DEFAULT 0,
283
+ output_tokens INTEGER NOT NULL DEFAULT 0,
284
+ cost_usd REAL NOT NULL DEFAULT 0,
285
+ latency_ms INTEGER,
286
+
287
+ -- TOON Savings
288
+ toon_saved_tokens INTEGER NOT NULL DEFAULT 0,
289
+ toon_saved_cost REAL NOT NULL DEFAULT 0,
290
+
291
+ -- TOON Metrics (complete compression analysis)
292
+ toon_json_bytes INTEGER NOT NULL DEFAULT 0,
293
+ toon_toon_bytes INTEGER NOT NULL DEFAULT 0,
294
+ toon_saved_bytes INTEGER NOT NULL DEFAULT 0,
295
+ toon_saved_percent REAL NOT NULL DEFAULT 0,
296
+ toon_json_tokens INTEGER NOT NULL DEFAULT 0,
297
+ toon_toon_tokens INTEGER NOT NULL DEFAULT 0,
298
+ toon_saved_tokens_pct REAL NOT NULL DEFAULT 0,
299
+
300
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
301
+ );
302
+
303
+ -- ═══════════════════════════════════════════════════════════════════
304
+ -- CRON JOBS — Tareas programadas (Croner v10.0.1)
305
+ -- ═══════════════════════════════════════════════════════════════════
306
+ -- task_type: 'recurring' (uses cron_expression) or 'one_shot' (uses fire_at)
307
+ -- task: REQUIRED instruction the agent reads when the job triggers (natural language)
308
+ -- cron_expression: stored in user's local time, not UTC
309
+ -- fire_at: ISO 8601 in user's local time (e.g., "2026-04-01T09:00:00")
310
+ -- start_at / stop_at: ISO 8601 datetime window (Croner: startAt / stopAt)
311
+ -- dom_and_dow: 0 = OR (default), 1 = AND logic for day-of-month + day-of-week (Croner: domAndDow)
312
+ -- timezone: IANA timezone (e.g., "America/Bogota") inherited from users.timezone
313
+ -- protect: overrun protection (1 = enabled, 0 = disabled)
314
+ -- payload: JSON string, at minimum { prompt: string } or { message: string }
315
+ -- CHECK: recurring requires cron_expression, one_shot requires fire_at
316
+ CREATE TABLE IF NOT EXISTS cron_jobs (
317
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(8)))),
318
+ name TEXT NOT NULL,
319
+ task TEXT NOT NULL,
320
+ task_type TEXT NOT NULL CHECK(task_type IN ('recurring', 'one_shot')),
321
+ cron_expression TEXT,
322
+ fire_at TEXT,
323
+ timezone TEXT NOT NULL DEFAULT 'UTC',
324
+ start_at TEXT,
325
+ stop_at TEXT,
326
+ dom_and_dow INTEGER NOT NULL DEFAULT 0,
327
+ max_runs INTEGER,
328
+ protect INTEGER NOT NULL DEFAULT 1,
329
+ interval_sec INTEGER,
330
+ agent_id TEXT,
331
+ channel TEXT DEFAULT 'system',
332
+ payload TEXT DEFAULT '{}',
333
+ tool_name TEXT,
334
+ status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'paused', 'completed', 'failed', 'cancelled')),
335
+ run_count INTEGER NOT NULL DEFAULT 0,
336
+ error_count INTEGER NOT NULL DEFAULT 0,
337
+ last_error TEXT,
338
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
339
+ updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
340
+ last_run_at TEXT,
341
+ next_run_at TEXT,
342
+ completed_at TEXT,
343
+ CHECK(
344
+ (task_type = 'recurring' AND cron_expression IS NOT NULL) OR
345
+ (task_type = 'one_shot' AND fire_at IS NOT NULL)
346
+ )
347
+ );
348
+
349
+ -- Task execution history
350
+ CREATE TABLE IF NOT EXISTS task_runs (
351
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(8)))),
352
+ task_id TEXT NOT NULL REFERENCES cron_jobs(id) ON DELETE CASCADE,
353
+ status TEXT NOT NULL CHECK(status IN ('running', 'success', 'failed', 'timeout')),
354
+ started_at TEXT NOT NULL,
355
+ finished_at TEXT,
356
+ duration_ms INTEGER,
357
+ error_message TEXT,
358
+ payload_snapshot TEXT,
359
+ agent_response TEXT
360
+ );
361
+
362
+ -- INDICES for cron_jobs
363
+ CREATE INDEX IF NOT EXISTS idx_cron_jobs_status ON cron_jobs(status);
364
+ CREATE INDEX IF NOT EXISTS idx_cron_jobs_type ON cron_jobs(task_type);
365
+ CREATE INDEX IF NOT EXISTS idx_cron_jobs_next_run ON cron_jobs(next_run_at);
366
+ CREATE INDEX IF NOT EXISTS idx_cron_jobs_agent ON cron_jobs(agent_id);
367
+
368
+ -- INDICES for task_runs
369
+ CREATE INDEX IF NOT EXISTS idx_task_runs_task ON task_runs(task_id);
370
+ CREATE INDEX IF NOT EXISTS idx_task_runs_started ON task_runs(started_at);
371
+ CREATE INDEX IF NOT EXISTS idx_task_runs_status ON task_runs(status);
372
+
373
+ -- TRIGGER: Update updated_at on cron_jobs UPDATE
374
+ CREATE TRIGGER IF NOT EXISTS update_cron_jobs_updated_at
375
+ AFTER UPDATE ON cron_jobs
376
+ BEGIN
377
+ UPDATE cron_jobs SET updated_at = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') WHERE id = NEW.id;
378
+ END;
379
+
380
+ -- INDICES
381
+
382
+ CREATE INDEX IF NOT EXISTS idx_models_provider ON models(provider_id);
383
+ CREATE INDEX IF NOT EXISTS idx_models_type ON models(model_type);
384
+ CREATE INDEX IF NOT EXISTS idx_agents_user ON agents(user_id);
385
+ CREATE INDEX IF NOT EXISTS idx_channels_user ON channels(user_id);
386
+ CREATE INDEX IF NOT EXISTS idx_channels_type ON channels(type);
387
+ CREATE INDEX IF NOT EXISTS idx_ethics ON ethics(id);
388
+ CREATE INDEX IF NOT EXISTS idx_code_bridge ON code_bridge(id);
389
+ CREATE INDEX IF NOT EXISTS idx_identities_user ON user_identities(user_id);
390
+ CREATE INDEX IF NOT EXISTS idx_usage_provider_model ON usage_records(provider, model);
391
+ CREATE INDEX IF NOT EXISTS idx_usage_created_at ON usage_records(created_at);
392
+ CREATE INDEX IF NOT EXISTS idx_code_bridge_config_user ON code_bridge_config(user_id);
393
+
394
+ `;
395
+
396
+ export const PROJECTS_SCHEMA = `
397
+ -- PROJECTS: tareas multi-paso con seguimiento de progreso
398
+ CREATE TABLE IF NOT EXISTS projects (
399
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
400
+ user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
401
+ agent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,
402
+ name TEXT NOT NULL,
403
+ description TEXT,
404
+ type TEXT NOT NULL DEFAULT 'general',
405
+ task TEXT,
406
+ progress INTEGER NOT NULL DEFAULT 0 CHECK(progress >= 0 AND progress <= 100),
407
+ status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending','active','paused','done','failed')),
408
+ context TEXT,
409
+ parent_id TEXT REFERENCES projects(id) ON DELETE SET NULL,
410
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
411
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
412
+ started_at INTEGER,
413
+ completed_at INTEGER
414
+ );
415
+
416
+ -- TASKS: subtareas atómicas asociadas a un proyecto, con agente asignado
417
+ -- depends_on: JSON array of task IDs that must complete before this one
418
+ -- priority: higher = more urgent
419
+ -- error: reason for failure if status='failed'
420
+ CREATE TABLE IF NOT EXISTS tasks (
421
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
422
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
423
+ agent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,
424
+ parent_task_id INTEGER REFERENCES tasks(id) ON DELETE CASCADE,
425
+ name TEXT NOT NULL,
426
+ description TEXT,
427
+ status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending','in_progress','completed','failed','blocked')),
428
+ progress INTEGER NOT NULL DEFAULT 0 CHECK(progress >= 0 AND progress <= 100),
429
+ priority INTEGER NOT NULL DEFAULT 0,
430
+ depends_on TEXT,
431
+ result TEXT,
432
+ error TEXT,
433
+ metadata TEXT,
434
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
435
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
436
+ completed_at INTEGER
437
+ );
438
+
439
+ CREATE INDEX IF NOT EXISTS idx_projects_user ON projects(user_id);
440
+ CREATE INDEX IF NOT EXISTS idx_projects_agent ON projects(agent_id);
441
+ CREATE INDEX IF NOT EXISTS idx_projects_parent ON projects(parent_id);
442
+ CREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status);
443
+ CREATE INDEX IF NOT EXISTS idx_tasks_project ON tasks(project_id);
444
+ CREATE INDEX IF NOT EXISTS idx_tasks_agent ON tasks(agent_id);
445
+ CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
446
+ CREATE INDEX IF NOT EXISTS idx_tasks_priority ON tasks(priority);
447
+ `;
448
+
449
+ // ─── Context Engine + ACE tables ─────────────────────────────────────────────
450
+
451
+ export const CONTEXT_ENGINE_SCHEMA = `
452
+ -- CONVERSATIONS: full message history per thread (replaces lg_checkpoints)
453
+ -- role: 'user' | 'assistant' | 'tool' | 'system'
454
+ -- tool_calls_json: JSON array of tool calls if the message triggered any
455
+ -- token_count: estimated tokens for context budget tracking
456
+ CREATE TABLE IF NOT EXISTS conversations (
457
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
458
+ thread_id TEXT NOT NULL,
459
+ channel TEXT NOT NULL DEFAULT 'webchat',
460
+ role TEXT NOT NULL CHECK(role IN ('user','assistant','tool','system')),
461
+ content TEXT NOT NULL,
462
+ content_multimodal TEXT,
463
+ tool_calls_json TEXT,
464
+ tool_call_id TEXT,
465
+ token_count INTEGER NOT NULL DEFAULT 0,
466
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
467
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
468
+ );
469
+
470
+ -- SUMMARIES: compressed digests of long conversations
471
+ -- The Context Compiler uses the summary instead of full history
472
+ CREATE TABLE IF NOT EXISTS summaries (
473
+ thread_id TEXT PRIMARY KEY,
474
+ summary TEXT NOT NULL,
475
+ messages_covered INTEGER NOT NULL DEFAULT 0,
476
+ last_message_id INTEGER,
477
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
478
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
479
+ );
480
+
481
+ -- SCRATCHPAD: persistent key-value notes per conversation
482
+ -- Survives context compression. Written by agents via save_note tool.
483
+ CREATE TABLE IF NOT EXISTS scratchpad (
484
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
485
+ thread_id TEXT NOT NULL,
486
+ key TEXT NOT NULL,
487
+ value TEXT NOT NULL,
488
+ source TEXT,
489
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
490
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
491
+ UNIQUE(thread_id, key)
492
+ );
493
+
494
+ -- TRACES: execution log for every agent invocation (ACE Generator output)
495
+ -- success: 1 = ok, 0 = failure
496
+ -- tokens_used: total tokens consumed in this invocation
497
+ CREATE TABLE IF NOT EXISTS traces (
498
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
499
+ thread_id TEXT NOT NULL,
500
+ agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
501
+ agent_name TEXT NOT NULL,
502
+ tool_used TEXT,
503
+ input_summary TEXT NOT NULL,
504
+ output_summary TEXT NOT NULL,
505
+ success INTEGER NOT NULL DEFAULT 1,
506
+ error_message TEXT,
507
+ duration_ms INTEGER,
508
+ tokens_used INTEGER,
509
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
510
+ );
511
+
512
+ -- REFLECTIONS: insights extracted by the ACE Reflector from traces
513
+ -- insight_type: 'success_pattern' | 'failure_pattern' | 'optimization' | 'ethics_violation'
514
+ -- confidence: 0.0 to 1.0
515
+ CREATE TABLE IF NOT EXISTS reflections (
516
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
517
+ trace_ids TEXT NOT NULL,
518
+ insight_type TEXT NOT NULL CHECK(insight_type IN ('success_pattern','failure_pattern','optimization','ethics_violation')),
519
+ description TEXT NOT NULL,
520
+ affected_tools TEXT,
521
+ affected_agents TEXT,
522
+ confidence REAL NOT NULL DEFAULT 0.5,
523
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
524
+ );
525
+
526
+ -- PLAYBOOK: evolved rules injected by Context Compiler (ACE Curator output)
527
+ -- category: 'tool_selection' | 'response_quality' | 'error_avoidance' | 'optimization' | 'agent_creation'
528
+ -- applicable_to: JSON array of contexts where this rule applies
529
+ -- helpful_count / harmful_count: feedback from execution outcomes
530
+ -- active: 0 = pruned by Curator
531
+ CREATE TABLE IF NOT EXISTS playbook (
532
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
533
+ rule TEXT NOT NULL,
534
+ category TEXT NOT NULL CHECK(category IN ('tool_selection','response_quality','error_avoidance','optimization','agent_creation')),
535
+ applicable_to TEXT,
536
+ helpful_count INTEGER NOT NULL DEFAULT 0,
537
+ harmful_count INTEGER NOT NULL DEFAULT 0,
538
+ source_reflection_id INTEGER REFERENCES reflections(id) ON DELETE SET NULL,
539
+ active INTEGER NOT NULL DEFAULT 1,
540
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
541
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
542
+ );
543
+
544
+ -- TOOL_CACHE: cached results for deterministic/expensive tool calls
545
+ -- cache_key: hash of tool_id + serialized params
546
+ -- ttl_seconds: 0 = no expiry
547
+ CREATE TABLE IF NOT EXISTS tool_cache (
548
+ cache_key TEXT PRIMARY KEY,
549
+ tool_id TEXT NOT NULL,
550
+ result TEXT NOT NULL,
551
+ ttl_seconds INTEGER NOT NULL DEFAULT 3600,
552
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
553
+ );
554
+
555
+ -- FTS5 indexes for fast semantic search in Context Compiler
556
+ -- Created by initializeDatabase() via CONTEXT_ENGINE_SCHEMA
557
+ -- Populated by syncToolsToFTS() and syncSkillsToFTS() from gateway/initializer.ts
558
+ -- Triggers are NOT used - data is cleared and re-inserted on each sync to avoid schema drift
559
+
560
+ CREATE VIRTUAL TABLE IF NOT EXISTS playbook_fts USING fts5(
561
+ rule,
562
+ category,
563
+ applicable_to
564
+ );
565
+
566
+ -- FTS5: tool catalog search (populated by syncToolCatalogToFTS from gateway/initializer.ts)
567
+ CREATE VIRTUAL TABLE IF NOT EXISTS tools_fts USING fts5(
568
+ tool_name,
569
+ name,
570
+ description,
571
+ category
572
+ );
573
+
574
+ -- FTS5: skills catalog search (populated by syncSkillsToFTS from gateway/initializer.ts)
575
+ -- v0.0.28: includes description column for better semantic matching
576
+ CREATE VIRTUAL TABLE IF NOT EXISTS skills_fts USING fts5(
577
+ id, name, description, category, tools, triggers, body
578
+ );
579
+
580
+ -- MCP Tools: tool definitions discovered from connected MCP servers
581
+ -- Persisted for FTS5 search and offline availability
582
+ -- Synced from MCPClientManager at runtime via hot-reload
583
+ -- Deleted when server disconnects (active management by hot-reload)
584
+ CREATE TABLE IF NOT EXISTS mcp_tools (
585
+ id TEXT PRIMARY KEY,
586
+ server_id TEXT NOT NULL,
587
+ server_name TEXT NOT NULL,
588
+ tool_name TEXT NOT NULL,
589
+ description TEXT,
590
+ category TEXT DEFAULT 'mcp',
591
+ active INTEGER NOT NULL DEFAULT 1,
592
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
593
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
594
+ );
595
+
596
+ CREATE INDEX IF NOT EXISTS idx_mcp_tools_server ON mcp_tools(server_id);
597
+ CREATE INDEX IF NOT EXISTS idx_mcp_tools_active ON mcp_tools(active);
598
+
599
+ -- FTS5: MCP tools catalog search (populated by syncMCPToolsToFTS from mcp/tool-sync.ts)
600
+ -- Separate from tools_fts to avoid polluting native tool search with MCP tools
601
+ CREATE VIRTUAL TABLE IF NOT EXISTS mcp_tools_fts USING fts5(
602
+ id, server_name, tool_name, description, category
603
+ );
604
+
605
+ -- REFRESH TOKENS: JWT refresh token storage (hash-based for security)
606
+ -- Stores hashed refresh tokens with expiry and user linkage
607
+ CREATE TABLE IF NOT EXISTS refresh_tokens (
608
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
609
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
610
+ token_hash TEXT NOT NULL UNIQUE,
611
+ expires_at INTEGER NOT NULL,
612
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
613
+ revoked INTEGER NOT NULL DEFAULT 0
614
+ );
615
+
616
+ CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user ON refresh_tokens(user_id);
617
+ CREATE INDEX IF NOT EXISTS idx_refresh_tokens_hash ON refresh_tokens(token_hash);
618
+ CREATE INDEX IF NOT EXISTS idx_refresh_tokens_expires ON refresh_tokens(expires_at);
619
+
620
+ -- Agent Bus: Message queue for worker-to-worker communication
621
+ CREATE TABLE IF NOT EXISTS agent_bus_messages (
622
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
623
+ event_type TEXT NOT NULL,
624
+ from_worker_id TEXT REFERENCES agents(id) ON DELETE SET NULL,
625
+ to_worker_id TEXT REFERENCES agents(id) ON DELETE SET NULL,
626
+ topic TEXT,
627
+ content TEXT NOT NULL,
628
+ metadata TEXT,
629
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
630
+ read INTEGER NOT NULL DEFAULT 0
631
+ );
632
+
633
+ CREATE INDEX IF NOT EXISTS idx_agent_bus_from_worker ON agent_bus_messages(from_worker_id);
634
+ CREATE INDEX IF NOT EXISTS idx_agent_bus_to_worker ON agent_bus_messages(to_worker_id);
635
+ CREATE INDEX IF NOT EXISTS idx_agent_bus_event_type ON agent_bus_messages(event_type);
636
+ CREATE INDEX IF NOT EXISTS idx_agent_bus_read ON agent_bus_messages(read);
637
+
638
+ -- INDICES
639
+ CREATE INDEX IF NOT EXISTS idx_conversations_thread ON conversations(thread_id);
640
+ CREATE INDEX IF NOT EXISTS idx_conversations_role ON conversations(role);
641
+ CREATE INDEX IF NOT EXISTS idx_scratchpad_thread ON scratchpad(thread_id);
642
+ CREATE INDEX IF NOT EXISTS idx_traces_thread ON traces(thread_id);
643
+ CREATE INDEX IF NOT EXISTS idx_traces_agent ON traces(agent_id);
644
+ CREATE INDEX IF NOT EXISTS idx_traces_success ON traces(success);
645
+ CREATE INDEX IF NOT EXISTS idx_reflections_type ON reflections(insight_type);
646
+ CREATE INDEX IF NOT EXISTS idx_playbook_active ON playbook(active);
647
+ CREATE INDEX IF NOT EXISTS idx_playbook_category ON playbook(category);
648
+ CREATE INDEX IF NOT EXISTS idx_tool_cache_tool ON tool_cache(tool_id);
649
+
650
+ -- Schema migrations: idempotent version tracking (runs every startup)
651
+ CREATE TABLE IF NOT EXISTS schema_migrations (
652
+ version TEXT PRIMARY KEY,
653
+ applied_at INTEGER NOT NULL DEFAULT (unixepoch())
654
+ );
655
+
656
+
657
+ `;
658
+
659
+ export const MEETING_SCHEMA = `
660
+ -- Meeting Sessions: encabezado de cada transcripción de reunión
661
+ CREATE TABLE IF NOT EXISTS meeting_sessions (
662
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
663
+ user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
664
+ title TEXT NOT NULL DEFAULT 'Reunión sin título',
665
+ status TEXT NOT NULL DEFAULT 'active'
666
+ CHECK(status IN ('active', 'stopped', 'report_ready')),
667
+ stt_model TEXT NOT NULL DEFAULT 'whisper-large-v3-turbo',
668
+ started_at INTEGER NOT NULL DEFAULT (unixepoch()),
669
+ stopped_at INTEGER,
670
+ report_path TEXT,
671
+ metadata TEXT
672
+ );
673
+
674
+ -- Meeting Segments: cada bloque de audio transcrito
675
+ CREATE TABLE IF NOT EXISTS meeting_segments (
676
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
677
+ session_id TEXT NOT NULL REFERENCES meeting_sessions(id) ON DELETE CASCADE,
678
+ seq INTEGER NOT NULL,
679
+ speaker TEXT,
680
+ text TEXT NOT NULL,
681
+ duration_ms INTEGER,
682
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
683
+ );
684
+
685
+ CREATE INDEX IF NOT EXISTS idx_meeting_sessions_user ON meeting_sessions(user_id);
686
+ CREATE INDEX IF NOT EXISTS idx_meeting_sessions_status ON meeting_sessions(status);
687
+ CREATE INDEX IF NOT EXISTS idx_meeting_segments_session ON meeting_segments(session_id);
688
+ CREATE INDEX IF NOT EXISTS idx_meeting_segments_seq ON meeting_segments(session_id, seq);
689
+ `;