ohwow 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 (34) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +147 -0
  3. package/bin/ohwow.js +2 -0
  4. package/dist/db/migrations/001-data-plane-tables.sql +250 -0
  5. package/dist/db/migrations/002-agents-table.sql +40 -0
  6. package/dist/db/migrations/003-orchestrator-a2a.sql +111 -0
  7. package/dist/db/migrations/004-whatsapp.sql +37 -0
  8. package/dist/db/migrations/005-telegram.sql +27 -0
  9. package/dist/db/migrations/006-deferred-actions.sql +3 -0
  10. package/dist/db/migrations/007-deliverables.sql +23 -0
  11. package/dist/db/migrations/008-plans.sql +36 -0
  12. package/dist/db/migrations/009-nudges.sql +16 -0
  13. package/dist/db/migrations/010-local-crm.sql +35 -0
  14. package/dist/db/migrations/011-notification-preferences.sql +5 -0
  15. package/dist/db/migrations/012-orchestrator-memory.sql +14 -0
  16. package/dist/db/migrations/013-voice-profile-settings.sql +9 -0
  17. package/dist/db/migrations/014-webhooks-and-triggers.sql +53 -0
  18. package/dist/db/migrations/015-file-attachments.sql +19 -0
  19. package/dist/db/migrations/016-dashboard-tables.sql +47 -0
  20. package/dist/db/migrations/017-workflow-triggers.sql +24 -0
  21. package/dist/db/migrations/018-workspace-onboarding.sql +20 -0
  22. package/dist/db/migrations/019-custom-webhooks.sql +9 -0
  23. package/dist/db/migrations/020-automation-action-chains.sql +9 -0
  24. package/dist/db/migrations/021-unify-automations.sql +12 -0
  25. package/dist/db/migrations/022-knowledge-base.sql +66 -0
  26. package/dist/db/migrations/023-local-file-access.sql +19 -0
  27. package/dist/db/migrations/024-model-stats.sql +25 -0
  28. package/dist/index.d.ts +91 -0
  29. package/dist/index.js +1169 -0
  30. package/dist/web/assets/index-C5TP_l1N.css +1 -0
  31. package/dist/web/assets/index-Dylm-A3c.js +75 -0
  32. package/dist/web/favicon.svg +4 -0
  33. package/dist/web/index.html +14 -0
  34. package/package.json +70 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Business Source License 1.1
2
+
3
+ Parameters
4
+
5
+ Licensor: ohwow
6
+ Licensed Work: ohwow runtime (all versions)
7
+ Additional Use Grant: You may use the Licensed Work for any purpose, including
8
+ production use, EXCEPT for building or offering a product
9
+ or service that competes with ohwow.fun or its features.
10
+ Change Date: March 2, 2030
11
+ Change License: Apache License, Version 2.0
12
+
13
+ For the full BSL 1.1 license text, see https://mariadb.com/bsl11/
14
+
15
+ Notice
16
+
17
+ The Licensed Work is (c) 2024-2026 ohwow.
18
+
19
+ The full text of the Business Source License 1.1 is incorporated by reference
20
+ from the URL above. This file states only the parameters specific to this
21
+ project. In the event of any conflict, the full license text governs.
package/README.md ADDED
@@ -0,0 +1,147 @@
1
+ # ohwow
2
+
3
+ A local AI agent runtime. Free to use with [Ollama](https://ollama.com) for local models. Enterprise features (cloud dashboard sync, WhatsApp, Telegram, scheduling, proactive engine) unlock with an [ohwow.fun](https://ohwow.fun) subscription.
4
+
5
+ ## Getting Started
6
+
7
+ ### Install
8
+
9
+ ```bash
10
+ npm install ohwow -g
11
+ ```
12
+
13
+ ### Requirements
14
+
15
+ - Node.js 20+
16
+ - [Ollama](https://ollama.com) (for free tier / local models)
17
+ - Optional: Anthropic API key (for Claude models)
18
+ - Optional: Playwright browsers (`npx playwright install chromium`) for browser automation
19
+ - Optional: C++ compiler may be needed on some platforms for `better-sqlite3`
20
+
21
+ ### Launch
22
+
23
+ ```bash
24
+ ohwow
25
+ ```
26
+
27
+ On first launch, a setup wizard appears in your terminal. For the free tier, just point it at your Ollama instance. For enterprise features, enter your license key (from the ohwow.fun dashboard, under Settings > License) and your Anthropic API key. These are saved locally so you only do this once.
28
+
29
+ After setup, the runtime opens into a TUI (terminal UI) with tabs for your dashboard, agents, tasks, approvals, activity, schedules, plans, and a chat interface. Use arrow keys or tab to navigate. Everything you see in the web dashboard is also here, running locally.
30
+
31
+ ### What Happens at Startup
32
+
33
+ Once configured, the runtime:
34
+
35
+ 1. Initializes a local database
36
+ 2. Connects to ohwow.fun and syncs your agent configurations
37
+ 3. Starts the orchestrator, scheduler, and proactive engine
38
+ 4. Connects messaging channels (WhatsApp, Telegram) if you've set them up
39
+ 5. Launches a local web UI
40
+ 6. Begins polling for tasks dispatched from the dashboard
41
+
42
+ From here, agents execute tasks on your hardware using your own API key. The dashboard sends the work, your machine does the thinking.
43
+
44
+ ## Using the Orchestrator
45
+
46
+ The orchestrator is a conversational assistant built into the runtime with 40+ tools. Open the Chat tab in the TUI, or use the web UI from your browser.
47
+
48
+ You can talk to it naturally. Some examples of what it can do:
49
+
50
+ | What you say | What happens |
51
+ |---|---|
52
+ | "Run the content writer on this week's blog post" | Dispatches a task to that agent immediately |
53
+ | "What failed today?" | Lists recent failed tasks with details |
54
+ | "Schedule outreach every weekday at 9am" | Creates a cron schedule for the agent |
55
+ | "Send a WhatsApp to the team: launching Friday" | Sends the message through your connected WhatsApp |
56
+ | "Plan out researching 5 new leads this week" | Creates a multi-step plan with agent assignments, waits for your approval |
57
+ | "Show me the business pulse" | Returns task stats, contact pipeline, costs, and streaks |
58
+ | "Create a project for the website redesign" | Creates a project with a Kanban board |
59
+ | "Move that task to review" | Moves a task between board columns |
60
+
61
+ The orchestrator covers: agents, tasks, projects, CRM (contacts, pipeline, events), scheduling, messaging (WhatsApp + Telegram), A2A connections, goal planning, deep research, analytics, and workflows. It can also switch your TUI tabs if you ask ("go to approvals").
62
+
63
+ ## Features
64
+
65
+ ### Agent Memory
66
+
67
+ After each task, key facts, skills, and feedback are extracted and stored locally. These memories are compiled into the agent's context on future tasks. Agents improve the more they work. You can view any agent's memory from the Agents tab.
68
+
69
+ ### Browser Automation
70
+
71
+ Agents can browse the web using Playwright. Navigation, clicking, form filling, screenshots, and content extraction. The browser launches on first use and runs headless by default. Set `OHWOW_BROWSER_HEADLESS=false` to watch it work.
72
+
73
+ ### WhatsApp and Telegram
74
+
75
+ Connect WhatsApp through a QR code scan in Settings (no Meta business API needed). Connect Telegram with a bot token. Once connected, incoming messages route to the orchestrator automatically. Your agents can reply, take action, or flag things for your attention. You control which chats are allowed.
76
+
77
+ ### Agent-to-Agent (A2A)
78
+
79
+ Connect to external agents using the A2A protocol. Each agent publishes a card describing its capabilities. You set trust levels to control what external agents can do. Managed from the A2A tab or through the orchestrator.
80
+
81
+ ### Scheduling
82
+
83
+ Set agents or workflows to run on cron schedules. Create schedules through conversation ("schedule the analyst every Monday at 8am") or from the Schedules tab. Toggle them on and off as needed.
84
+
85
+ ### Goal Planning
86
+
87
+ For complex goals, the orchestrator can break them into multi-step plans with agent assignments and dependencies. Plans start as drafts. You review the steps, approve or reject, and track execution from the Plans tab.
88
+
89
+ ### Approval Workflows
90
+
91
+ Some tasks pause for your sign-off before executing. The Approvals tab shows pending items. Approve to proceed, or reject with feedback. Rejected tasks can retry with your notes included.
92
+
93
+ ### Projects and CRM
94
+
95
+ Organize tasks into projects with Kanban boards (backlog, todo, in progress, review, done). The built-in CRM tracks contacts (leads, customers, partners), logs events (calls, emails, meetings), and gives you pipeline analytics. All stored locally.
96
+
97
+ ### Local Models with Ollama
98
+
99
+ If you run [Ollama](https://ollama.com) locally, the runtime can route lightweight tasks to your local model instead of Claude. Complex work still goes to Claude. If Ollama goes down, everything falls back automatically.
100
+
101
+ ### Web Search
102
+
103
+ Agents with web search enabled can search the web during task execution, powered by Anthropic's built-in search tool.
104
+
105
+ ### Offline Mode
106
+
107
+ If ohwow.fun becomes unreachable, the runtime continues with cached agent configs. Tasks still execute, results still store locally. When connectivity returns, everything syncs back up.
108
+
109
+ ## What Stays Local
110
+
111
+ The runtime syncs agent configurations from ohwow.fun and reports back only operational metadata: task titles, status, token counts, and costs. Everything else stays on your machine:
112
+
113
+ - Prompts and system instructions
114
+ - Agent outputs and full conversations
115
+ - Long-term agent memory
116
+ - CRM contacts and activity history
117
+ - WhatsApp and Telegram message history
118
+ - Browser session data and screenshots
119
+
120
+ This is the core of the Enterprise plan. Your business data never leaves your infrastructure.
121
+
122
+ ## Web UI
123
+
124
+ The runtime also serves a web UI accessible from any browser on your network. Same capabilities as the TUI. Useful if you prefer a graphical interface or want to share access with your team locally.
125
+
126
+ ## Headless Mode
127
+
128
+ For servers, containers, or always-on deployments where you don't need a terminal interface:
129
+
130
+ ```bash
131
+ ohwow --headless
132
+ ```
133
+
134
+ In headless mode, configure through environment variables. The web UI still runs normally. See the [configuration docs](https://ohwow.fun/docs/runtime/configuration) for available options.
135
+
136
+ ## Supported Models
137
+
138
+ | Model | Provider |
139
+ |-------|----------|
140
+ | Claude Opus 4.6 | Anthropic |
141
+ | Claude Sonnet 4.5 | Anthropic |
142
+ | Claude Haiku 4 | Anthropic |
143
+ | Any Ollama model | Local |
144
+
145
+ ## License
146
+
147
+ BSL 1.1 (Business Source License). Free to use, including production. You can't use it to build a competing product. Converts to Apache 2.0 on March 2, 2030. See [LICENSE](./LICENSE) for details.
package/bin/ohwow.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import('../dist/index.js');
@@ -0,0 +1,250 @@
1
+ -- Enterprise Runtime: Data Plane Tables
2
+ -- These are the tables whose data stays local on the customer's machine.
3
+ -- Schema mirrors the Supabase tables but runs on SQLite.
4
+
5
+ -- ============================================================================
6
+ -- TASKS
7
+ -- ============================================================================
8
+
9
+ CREATE TABLE IF NOT EXISTS agent_workforce_tasks (
10
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
11
+ workspace_id TEXT NOT NULL,
12
+ agent_id TEXT NOT NULL,
13
+ title TEXT NOT NULL,
14
+ description TEXT,
15
+ input TEXT, -- JSON
16
+ output TEXT, -- JSON
17
+ status TEXT NOT NULL DEFAULT 'pending'
18
+ CHECK (status IN ('pending', 'in_progress', 'completed', 'failed', 'needs_approval', 'approved', 'rejected')),
19
+ priority TEXT NOT NULL DEFAULT 'normal'
20
+ CHECK (priority IN ('low', 'normal', 'high', 'urgent')),
21
+ model_used TEXT,
22
+ tokens_used INTEGER NOT NULL DEFAULT 0,
23
+ cost_cents INTEGER NOT NULL DEFAULT 0,
24
+ scheduled_for TEXT,
25
+ started_at TEXT,
26
+ completed_at TEXT,
27
+ duration_seconds INTEGER,
28
+ requires_approval INTEGER NOT NULL DEFAULT 0,
29
+ approved_by TEXT,
30
+ approved_at TEXT,
31
+ rejection_reason TEXT,
32
+ error_message TEXT,
33
+ retry_count INTEGER NOT NULL DEFAULT 0,
34
+ max_retries INTEGER NOT NULL DEFAULT 3,
35
+ contact_ids TEXT NOT NULL DEFAULT '[]', -- JSON array
36
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
37
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
38
+ );
39
+
40
+ CREATE INDEX IF NOT EXISTS idx_tasks_workspace ON agent_workforce_tasks(workspace_id);
41
+ CREATE INDEX IF NOT EXISTS idx_tasks_agent ON agent_workforce_tasks(agent_id);
42
+ CREATE INDEX IF NOT EXISTS idx_tasks_status ON agent_workforce_tasks(status);
43
+ CREATE INDEX IF NOT EXISTS idx_tasks_created ON agent_workforce_tasks(created_at);
44
+
45
+ -- ============================================================================
46
+ -- TASK MESSAGES
47
+ -- ============================================================================
48
+
49
+ CREATE TABLE IF NOT EXISTS agent_workforce_task_messages (
50
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
51
+ task_id TEXT NOT NULL REFERENCES agent_workforce_tasks(id) ON DELETE CASCADE,
52
+ role TEXT NOT NULL CHECK (role IN ('user', 'assistant', 'system', 'tool')),
53
+ content TEXT NOT NULL,
54
+ metadata TEXT NOT NULL DEFAULT '{}', -- JSON
55
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
56
+ );
57
+
58
+ CREATE INDEX IF NOT EXISTS idx_task_messages_task ON agent_workforce_task_messages(task_id);
59
+
60
+ -- ============================================================================
61
+ -- AGENT MEMORY
62
+ -- ============================================================================
63
+
64
+ CREATE TABLE IF NOT EXISTS agent_workforce_agent_memory (
65
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
66
+ agent_id TEXT NOT NULL,
67
+ workspace_id TEXT NOT NULL,
68
+ memory_type TEXT NOT NULL CHECK (memory_type IN ('fact', 'skill', 'feedback_positive', 'feedback_negative', 'cross_agent')),
69
+ content TEXT NOT NULL,
70
+ source_task_id TEXT,
71
+ source_type TEXT NOT NULL CHECK (source_type IN ('extraction', 'approval', 'rejection', 'manual', 'cross_agent')),
72
+ relevance_score REAL NOT NULL DEFAULT 0.5,
73
+ times_used INTEGER NOT NULL DEFAULT 0,
74
+ last_used_at TEXT,
75
+ token_count INTEGER NOT NULL DEFAULT 0,
76
+ is_active INTEGER NOT NULL DEFAULT 1,
77
+ superseded_by TEXT,
78
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
79
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
80
+ );
81
+
82
+ CREATE INDEX IF NOT EXISTS idx_memory_agent ON agent_workforce_agent_memory(agent_id);
83
+ CREATE INDEX IF NOT EXISTS idx_memory_workspace ON agent_workforce_agent_memory(workspace_id);
84
+ CREATE INDEX IF NOT EXISTS idx_memory_active ON agent_workforce_agent_memory(is_active);
85
+
86
+ -- ============================================================================
87
+ -- MEMORY EXTRACTION LOG
88
+ -- ============================================================================
89
+
90
+ CREATE TABLE IF NOT EXISTS agent_workforce_memory_extraction_log (
91
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
92
+ workspace_id TEXT NOT NULL,
93
+ agent_id TEXT NOT NULL,
94
+ task_id TEXT,
95
+ trigger_type TEXT NOT NULL CHECK (trigger_type IN ('task_completed', 'task_approved', 'task_rejected')),
96
+ memories_extracted INTEGER NOT NULL DEFAULT 0,
97
+ extraction_tokens_used INTEGER NOT NULL DEFAULT 0,
98
+ extraction_cost_cents INTEGER NOT NULL DEFAULT 0,
99
+ raw_extraction TEXT, -- JSON
100
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
101
+ );
102
+
103
+ -- ============================================================================
104
+ -- BROWSER SESSIONS
105
+ -- ============================================================================
106
+
107
+ CREATE TABLE IF NOT EXISTS agent_workforce_browser_sessions (
108
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
109
+ workspace_id TEXT NOT NULL,
110
+ agent_id TEXT NOT NULL,
111
+ task_id TEXT NOT NULL,
112
+ provider_session_id TEXT NOT NULL DEFAULT '',
113
+ cdp_url TEXT,
114
+ live_view_url TEXT,
115
+ status TEXT NOT NULL DEFAULT 'creating'
116
+ CHECK (status IN ('creating', 'active', 'idle', 'error', 'closed')),
117
+ current_url TEXT,
118
+ page_title TEXT,
119
+ error_message TEXT,
120
+ started_at TEXT NOT NULL DEFAULT (datetime('now')),
121
+ last_activity_at TEXT NOT NULL DEFAULT (datetime('now')),
122
+ closed_at TEXT,
123
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
124
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
125
+ );
126
+
127
+ CREATE INDEX IF NOT EXISTS idx_browser_sessions_task ON agent_workforce_browser_sessions(task_id);
128
+ CREATE INDEX IF NOT EXISTS idx_browser_sessions_status ON agent_workforce_browser_sessions(status);
129
+
130
+ -- ============================================================================
131
+ -- TELEGRAM CHAT MESSAGES
132
+ -- ============================================================================
133
+
134
+ CREATE TABLE IF NOT EXISTS telegram_chat_messages (
135
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
136
+ workspace_id TEXT NOT NULL,
137
+ chat_id TEXT NOT NULL,
138
+ telegram_message_id INTEGER,
139
+ sender TEXT NOT NULL CHECK (sender IN ('user', 'bot')),
140
+ content TEXT NOT NULL,
141
+ agent_id TEXT,
142
+ task_id TEXT,
143
+ metadata TEXT DEFAULT '{}', -- JSON
144
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
145
+ );
146
+
147
+ CREATE INDEX IF NOT EXISTS idx_telegram_messages_workspace ON telegram_chat_messages(workspace_id);
148
+ CREATE INDEX IF NOT EXISTS idx_telegram_messages_chat ON telegram_chat_messages(chat_id);
149
+
150
+ -- ============================================================================
151
+ -- ORCHESTRATOR CHAT SESSIONS
152
+ -- ============================================================================
153
+
154
+ CREATE TABLE IF NOT EXISTS orchestrator_chat_sessions (
155
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
156
+ workspace_id TEXT NOT NULL,
157
+ title TEXT,
158
+ messages TEXT NOT NULL DEFAULT '[]', -- JSON array
159
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
160
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
161
+ );
162
+
163
+ CREATE INDEX IF NOT EXISTS idx_orchestrator_sessions_workspace ON orchestrator_chat_sessions(workspace_id);
164
+
165
+ -- ============================================================================
166
+ -- CONTACT EVENTS (data plane portion)
167
+ -- ============================================================================
168
+
169
+ CREATE TABLE IF NOT EXISTS agent_workforce_contact_events (
170
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
171
+ workspace_id TEXT NOT NULL,
172
+ contact_id TEXT NOT NULL,
173
+ event_type TEXT NOT NULL,
174
+ title TEXT NOT NULL,
175
+ description TEXT,
176
+ agent_id TEXT,
177
+ task_id TEXT,
178
+ metadata TEXT DEFAULT '{}', -- JSON
179
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
180
+ );
181
+
182
+ CREATE INDEX IF NOT EXISTS idx_contact_events_contact ON agent_workforce_contact_events(contact_id);
183
+ CREATE INDEX IF NOT EXISTS idx_contact_events_workspace ON agent_workforce_contact_events(workspace_id);
184
+
185
+ -- ============================================================================
186
+ -- BRIEFINGS
187
+ -- ============================================================================
188
+
189
+ CREATE TABLE IF NOT EXISTS agent_workforce_briefings (
190
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
191
+ workspace_id TEXT NOT NULL,
192
+ briefing_type TEXT NOT NULL DEFAULT 'daily',
193
+ briefing_date TEXT NOT NULL,
194
+ content TEXT NOT NULL, -- JSON
195
+ is_read INTEGER NOT NULL DEFAULT 0,
196
+ read_at TEXT,
197
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
198
+ );
199
+
200
+ CREATE INDEX IF NOT EXISTS idx_briefings_workspace ON agent_workforce_briefings(workspace_id);
201
+ CREATE INDEX IF NOT EXISTS idx_briefings_date ON agent_workforce_briefings(briefing_date);
202
+
203
+ -- ============================================================================
204
+ -- LOCAL AGENT CONFIG CACHE
205
+ -- Synced from control plane, stored locally for offline operation
206
+ -- ============================================================================
207
+
208
+ CREATE TABLE IF NOT EXISTS local_agent_configs (
209
+ id TEXT PRIMARY KEY,
210
+ workspace_id TEXT NOT NULL,
211
+ name TEXT NOT NULL,
212
+ role TEXT NOT NULL,
213
+ description TEXT,
214
+ system_prompt TEXT NOT NULL,
215
+ config TEXT NOT NULL DEFAULT '{}', -- JSON (AgentConfig)
216
+ status TEXT NOT NULL DEFAULT 'idle',
217
+ stats TEXT NOT NULL DEFAULT '{}', -- JSON (AgentStats)
218
+ department_id TEXT,
219
+ synced_at TEXT NOT NULL DEFAULT (datetime('now'))
220
+ );
221
+
222
+ -- ============================================================================
223
+ -- LOCAL SCHEDULE CACHE
224
+ -- ============================================================================
225
+
226
+ CREATE TABLE IF NOT EXISTS local_schedule_configs (
227
+ id TEXT PRIMARY KEY,
228
+ workspace_id TEXT NOT NULL,
229
+ agent_id TEXT,
230
+ workflow_id TEXT,
231
+ label TEXT,
232
+ cron TEXT NOT NULL,
233
+ task_prompt TEXT,
234
+ enabled INTEGER NOT NULL DEFAULT 1,
235
+ synced_at TEXT NOT NULL DEFAULT (datetime('now'))
236
+ );
237
+
238
+ -- ============================================================================
239
+ -- LOCAL WORKFLOW CACHE
240
+ -- ============================================================================
241
+
242
+ CREATE TABLE IF NOT EXISTS local_workflow_configs (
243
+ id TEXT PRIMARY KEY,
244
+ workspace_id TEXT NOT NULL,
245
+ name TEXT NOT NULL,
246
+ description TEXT,
247
+ steps TEXT NOT NULL DEFAULT '[]', -- JSON
248
+ status TEXT NOT NULL DEFAULT 'active',
249
+ synced_at TEXT NOT NULL DEFAULT (datetime('now'))
250
+ );
@@ -0,0 +1,40 @@
1
+ -- Enterprise Runtime: Agents table (mirrors cloud schema for service compatibility)
2
+ -- This allows shared services to query agent_workforce_agents locally.
3
+
4
+ CREATE TABLE IF NOT EXISTS agent_workforce_agents (
5
+ id TEXT PRIMARY KEY,
6
+ workspace_id TEXT NOT NULL,
7
+ department_id TEXT,
8
+ name TEXT NOT NULL,
9
+ role TEXT NOT NULL,
10
+ description TEXT,
11
+ avatar_url TEXT,
12
+ system_prompt TEXT NOT NULL DEFAULT '',
13
+ config TEXT NOT NULL DEFAULT '{}', -- JSON
14
+ status TEXT NOT NULL DEFAULT 'idle',
15
+ stats TEXT NOT NULL DEFAULT '{}', -- JSON
16
+ is_preset INTEGER NOT NULL DEFAULT 0,
17
+ a2a_published INTEGER NOT NULL DEFAULT 0,
18
+ a2a_skills TEXT NOT NULL DEFAULT '[]', -- JSON
19
+ memory_document TEXT,
20
+ memory_token_count INTEGER DEFAULT 0,
21
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
22
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
23
+ );
24
+
25
+ CREATE INDEX IF NOT EXISTS idx_agents_workspace ON agent_workforce_agents(workspace_id);
26
+
27
+ -- Activity log table (for rpc compatibility)
28
+ CREATE TABLE IF NOT EXISTS agent_workforce_activity (
29
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
30
+ workspace_id TEXT NOT NULL,
31
+ activity_type TEXT NOT NULL,
32
+ title TEXT NOT NULL,
33
+ description TEXT,
34
+ agent_id TEXT,
35
+ task_id TEXT,
36
+ metadata TEXT DEFAULT '{}', -- JSON
37
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
38
+ );
39
+
40
+ CREATE INDEX IF NOT EXISTS idx_activity_workspace ON agent_workforce_activity(workspace_id);
@@ -0,0 +1,111 @@
1
+ -- Migration 003: Orchestrator A2A support
2
+ -- Adds tables for A2A connections, task logs, projects, and schedules
3
+
4
+ -- A2A connections to external agents
5
+ CREATE TABLE IF NOT EXISTS a2a_connections (
6
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
7
+ workspace_id TEXT NOT NULL,
8
+ name TEXT NOT NULL,
9
+ description TEXT,
10
+ agent_card_url TEXT NOT NULL,
11
+ endpoint_url TEXT NOT NULL,
12
+ auth_type TEXT NOT NULL DEFAULT 'none',
13
+ auth_config TEXT NOT NULL DEFAULT '{}',
14
+ trust_level TEXT NOT NULL DEFAULT 'read_only',
15
+ store_results INTEGER NOT NULL DEFAULT 1,
16
+ result_retention_hours INTEGER NOT NULL DEFAULT 168,
17
+ allowed_data_types TEXT NOT NULL DEFAULT '[]',
18
+ rate_limit_per_minute INTEGER NOT NULL DEFAULT 60,
19
+ rate_limit_per_hour INTEGER NOT NULL DEFAULT 1000,
20
+ status TEXT NOT NULL DEFAULT 'pending',
21
+ last_health_check_at TEXT,
22
+ last_health_status TEXT,
23
+ consecutive_failures INTEGER NOT NULL DEFAULT 0,
24
+ agent_card_cache TEXT,
25
+ agent_card_fetched_at TEXT,
26
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
27
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
28
+ );
29
+
30
+ -- A2A task audit logs
31
+ CREATE TABLE IF NOT EXISTS a2a_task_logs (
32
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
33
+ workspace_id TEXT NOT NULL,
34
+ direction TEXT NOT NULL,
35
+ a2a_task_id TEXT NOT NULL,
36
+ method TEXT NOT NULL,
37
+ api_key_id TEXT,
38
+ connection_id TEXT,
39
+ agent_id TEXT,
40
+ status TEXT NOT NULL DEFAULT 'pending',
41
+ request_summary TEXT,
42
+ result_summary TEXT,
43
+ tokens_used INTEGER NOT NULL DEFAULT 0,
44
+ cost_cents REAL NOT NULL DEFAULT 0,
45
+ duration_ms INTEGER,
46
+ error_code TEXT,
47
+ error_message TEXT,
48
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
49
+ completed_at TEXT
50
+ );
51
+
52
+ -- Local project management
53
+ CREATE TABLE IF NOT EXISTS agent_workforce_projects (
54
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
55
+ workspace_id TEXT NOT NULL,
56
+ name TEXT NOT NULL,
57
+ description TEXT,
58
+ status TEXT NOT NULL DEFAULT 'active',
59
+ color TEXT DEFAULT '#6366f1',
60
+ due_date TEXT,
61
+ position INTEGER NOT NULL DEFAULT 0,
62
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
63
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
64
+ );
65
+
66
+ -- Local cron schedules
67
+ CREATE TABLE IF NOT EXISTS agent_workforce_schedules (
68
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
69
+ workspace_id TEXT NOT NULL,
70
+ agent_id TEXT,
71
+ workflow_id TEXT,
72
+ label TEXT,
73
+ cron TEXT NOT NULL,
74
+ enabled INTEGER NOT NULL DEFAULT 1,
75
+ next_run_at TEXT,
76
+ last_run_at TEXT,
77
+ task_prompt TEXT,
78
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
79
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
80
+ );
81
+
82
+ -- Local workflows table
83
+ CREATE TABLE IF NOT EXISTS agent_workforce_workflows (
84
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
85
+ workspace_id TEXT NOT NULL,
86
+ name TEXT NOT NULL,
87
+ description TEXT,
88
+ status TEXT NOT NULL DEFAULT 'active',
89
+ steps TEXT NOT NULL DEFAULT '[]',
90
+ run_count INTEGER NOT NULL DEFAULT 0,
91
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
92
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
93
+ );
94
+
95
+ -- Add project_id and board_column to tasks
96
+ -- These use the @statement marker so the migration runner executes them individually
97
+ -- and swallows "duplicate column" errors for idempotency.
98
+ -- @statement
99
+ ALTER TABLE agent_workforce_tasks ADD COLUMN project_id TEXT;
100
+ -- @statement
101
+ ALTER TABLE agent_workforce_tasks ADD COLUMN board_column TEXT DEFAULT 'backlog';
102
+ -- @statement
103
+ ALTER TABLE agent_workforce_tasks ADD COLUMN due_date TEXT;
104
+ -- @statement
105
+ ALTER TABLE agent_workforce_tasks ADD COLUMN labels TEXT DEFAULT '[]';
106
+ -- @statement
107
+ ALTER TABLE agent_workforce_tasks ADD COLUMN parent_task_id TEXT;
108
+ -- @statement
109
+ ALTER TABLE agent_workforce_tasks ADD COLUMN position INTEGER DEFAULT 0;
110
+ -- @statement
111
+ ALTER TABLE agent_workforce_tasks ADD COLUMN archived_at TEXT;
@@ -0,0 +1,37 @@
1
+ -- Migration 004: WhatsApp integration via Baileys
2
+ -- Adds tables for WhatsApp connections, allowlisted chats, and message history
3
+
4
+ -- WhatsApp connections (one per runtime)
5
+ CREATE TABLE IF NOT EXISTS whatsapp_connections (
6
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
7
+ workspace_id TEXT NOT NULL,
8
+ phone_number TEXT,
9
+ status TEXT NOT NULL DEFAULT 'disconnected',
10
+ auth_state TEXT,
11
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
12
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
13
+ );
14
+
15
+ -- Allowlisted chats
16
+ CREATE TABLE IF NOT EXISTS whatsapp_allowed_chats (
17
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
18
+ connection_id TEXT NOT NULL REFERENCES whatsapp_connections(id) ON DELETE CASCADE,
19
+ chat_id TEXT NOT NULL,
20
+ chat_name TEXT,
21
+ chat_type TEXT DEFAULT 'individual',
22
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
23
+ UNIQUE(connection_id, chat_id)
24
+ );
25
+
26
+ -- Chat message history (for orchestrator context)
27
+ CREATE TABLE IF NOT EXISTS whatsapp_chat_messages (
28
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
29
+ connection_id TEXT NOT NULL REFERENCES whatsapp_connections(id) ON DELETE CASCADE,
30
+ chat_id TEXT NOT NULL,
31
+ sender TEXT,
32
+ role TEXT NOT NULL DEFAULT 'user',
33
+ content TEXT NOT NULL,
34
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
35
+ );
36
+
37
+ CREATE INDEX IF NOT EXISTS idx_wa_messages_chat ON whatsapp_chat_messages(connection_id, chat_id, created_at DESC);
@@ -0,0 +1,27 @@
1
+ -- Migration 005: Telegram integration via Bot API long-polling
2
+ -- Adds tables for Telegram connections and message history
3
+
4
+ -- Telegram bot connections
5
+ CREATE TABLE IF NOT EXISTS telegram_connections (
6
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
7
+ workspace_id TEXT NOT NULL,
8
+ bot_token TEXT NOT NULL,
9
+ bot_username TEXT,
10
+ bot_id TEXT,
11
+ status TEXT NOT NULL DEFAULT 'disconnected',
12
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
13
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
14
+ UNIQUE(workspace_id)
15
+ );
16
+
17
+ -- Chat message history (for orchestrator context)
18
+ CREATE TABLE IF NOT EXISTS telegram_chat_messages (
19
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
20
+ chat_id TEXT NOT NULL,
21
+ sender TEXT,
22
+ role TEXT NOT NULL DEFAULT 'user',
23
+ content TEXT NOT NULL,
24
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
25
+ );
26
+
27
+ CREATE INDEX IF NOT EXISTS idx_tg_messages_chat ON telegram_chat_messages(chat_id, created_at DESC);
@@ -0,0 +1,3 @@
1
+ -- Add deferred_action column to tasks (mirrors Supabase JSONB column as TEXT)
2
+ -- @statement
3
+ ALTER TABLE agent_workforce_tasks ADD COLUMN deferred_action TEXT DEFAULT NULL;
@@ -0,0 +1,23 @@
1
+ -- @statement
2
+ ALTER TABLE agent_workforce_tasks ADD COLUMN response_type TEXT DEFAULT NULL;
3
+
4
+ -- @statement
5
+ CREATE TABLE IF NOT EXISTS agent_workforce_deliverables (
6
+ id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
7
+ workspace_id TEXT NOT NULL,
8
+ task_id TEXT NOT NULL REFERENCES agent_workforce_tasks(id),
9
+ agent_id TEXT,
10
+ deliverable_type TEXT NOT NULL,
11
+ provider TEXT,
12
+ title TEXT NOT NULL,
13
+ content TEXT NOT NULL,
14
+ status TEXT NOT NULL DEFAULT 'pending_review',
15
+ delivery_result TEXT,
16
+ delivered_at TEXT,
17
+ reviewed_by TEXT,
18
+ reviewed_at TEXT,
19
+ rejection_reason TEXT,
20
+ retry_of_deliverable_id TEXT,
21
+ created_at TEXT DEFAULT (datetime('now')),
22
+ updated_at TEXT DEFAULT (datetime('now'))
23
+ );