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.
- package/LICENSE +21 -0
- package/README.md +147 -0
- package/bin/ohwow.js +2 -0
- package/dist/db/migrations/001-data-plane-tables.sql +250 -0
- package/dist/db/migrations/002-agents-table.sql +40 -0
- package/dist/db/migrations/003-orchestrator-a2a.sql +111 -0
- package/dist/db/migrations/004-whatsapp.sql +37 -0
- package/dist/db/migrations/005-telegram.sql +27 -0
- package/dist/db/migrations/006-deferred-actions.sql +3 -0
- package/dist/db/migrations/007-deliverables.sql +23 -0
- package/dist/db/migrations/008-plans.sql +36 -0
- package/dist/db/migrations/009-nudges.sql +16 -0
- package/dist/db/migrations/010-local-crm.sql +35 -0
- package/dist/db/migrations/011-notification-preferences.sql +5 -0
- package/dist/db/migrations/012-orchestrator-memory.sql +14 -0
- package/dist/db/migrations/013-voice-profile-settings.sql +9 -0
- package/dist/db/migrations/014-webhooks-and-triggers.sql +53 -0
- package/dist/db/migrations/015-file-attachments.sql +19 -0
- package/dist/db/migrations/016-dashboard-tables.sql +47 -0
- package/dist/db/migrations/017-workflow-triggers.sql +24 -0
- package/dist/db/migrations/018-workspace-onboarding.sql +20 -0
- package/dist/db/migrations/019-custom-webhooks.sql +9 -0
- package/dist/db/migrations/020-automation-action-chains.sql +9 -0
- package/dist/db/migrations/021-unify-automations.sql +12 -0
- package/dist/db/migrations/022-knowledge-base.sql +66 -0
- package/dist/db/migrations/023-local-file-access.sql +19 -0
- package/dist/db/migrations/024-model-stats.sql +25 -0
- package/dist/index.d.ts +91 -0
- package/dist/index.js +1169 -0
- package/dist/web/assets/index-C5TP_l1N.css +1 -0
- package/dist/web/assets/index-Dylm-A3c.js +75 -0
- package/dist/web/favicon.svg +4 -0
- package/dist/web/index.html +14 -0
- 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,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,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
|
+
);
|