supaclaw 1.0.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/SCHEMA.md ADDED
@@ -0,0 +1,215 @@
1
+ # OpenClaw Memory - Database Schema
2
+
3
+ ## Core Tables
4
+
5
+ ### 1. `sessions`
6
+ Every conversation gets a session. This is the primary organizational unit.
7
+
8
+ ```sql
9
+ CREATE TABLE sessions (
10
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
11
+ agent_id TEXT NOT NULL, -- Which agent (main, subagent, etc.)
12
+ user_id TEXT, -- Who they're talking to
13
+ channel TEXT, -- telegram, discord, webchat, etc.
14
+ started_at TIMESTAMPTZ DEFAULT NOW(),
15
+ ended_at TIMESTAMPTZ,
16
+ summary TEXT, -- AI-generated session summary
17
+ metadata JSONB DEFAULT '{}' -- Flexible additional data
18
+ );
19
+ ```
20
+
21
+ ### 2. `messages`
22
+ Every message in every session. The raw conversation log.
23
+
24
+ ```sql
25
+ CREATE TABLE messages (
26
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
27
+ session_id UUID REFERENCES sessions(id) ON DELETE CASCADE,
28
+ role TEXT NOT NULL, -- 'user', 'assistant', 'system', 'tool'
29
+ content TEXT NOT NULL,
30
+ created_at TIMESTAMPTZ DEFAULT NOW(),
31
+ token_count INT, -- Track usage
32
+ metadata JSONB DEFAULT '{}' -- Tool calls, attachments, etc.
33
+ );
34
+ ```
35
+
36
+ ### 3. `memories`
37
+ Distilled, long-term memories. The "important stuff" extracted from sessions.
38
+
39
+ ```sql
40
+ CREATE TABLE memories (
41
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
42
+ agent_id TEXT NOT NULL,
43
+ user_id TEXT, -- Whose memory (null = global)
44
+ category TEXT, -- 'preference', 'fact', 'decision', 'task', etc.
45
+ content TEXT NOT NULL,
46
+ importance FLOAT DEFAULT 0.5, -- 0-1 score for retrieval prioritization
47
+ source_session_id UUID REFERENCES sessions(id),
48
+ created_at TIMESTAMPTZ DEFAULT NOW(),
49
+ updated_at TIMESTAMPTZ DEFAULT NOW(),
50
+ expires_at TIMESTAMPTZ, -- Optional TTL for temporary memories
51
+ embedding VECTOR(1536), -- For semantic search (OpenAI ada-002 dimensions)
52
+ metadata JSONB DEFAULT '{}'
53
+ );
54
+
55
+ -- Index for vector similarity search
56
+ CREATE INDEX memories_embedding_idx ON memories
57
+ USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
58
+ ```
59
+
60
+ ### 4. `entities`
61
+ People, places, things the agent knows about.
62
+
63
+ ```sql
64
+ CREATE TABLE entities (
65
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
66
+ agent_id TEXT NOT NULL,
67
+ entity_type TEXT NOT NULL, -- 'person', 'place', 'project', 'tool', etc.
68
+ name TEXT NOT NULL,
69
+ aliases TEXT[], -- Alternative names
70
+ description TEXT,
71
+ properties JSONB DEFAULT '{}', -- Flexible key-value properties
72
+ first_seen_at TIMESTAMPTZ DEFAULT NOW(),
73
+ last_seen_at TIMESTAMPTZ DEFAULT NOW(),
74
+ mention_count INT DEFAULT 1,
75
+ embedding VECTOR(1536),
76
+
77
+ UNIQUE(agent_id, entity_type, name)
78
+ );
79
+ ```
80
+
81
+ ### 5. `tasks`
82
+ Persistent task tracking (replaces TODO.md).
83
+
84
+ ```sql
85
+ CREATE TABLE tasks (
86
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
87
+ agent_id TEXT NOT NULL,
88
+ user_id TEXT,
89
+ title TEXT NOT NULL,
90
+ description TEXT,
91
+ status TEXT DEFAULT 'pending', -- 'pending', 'in_progress', 'blocked', 'done'
92
+ priority INT DEFAULT 0,
93
+ due_at TIMESTAMPTZ,
94
+ completed_at TIMESTAMPTZ,
95
+ source_session_id UUID REFERENCES sessions(id),
96
+ parent_task_id UUID REFERENCES tasks(id),
97
+ metadata JSONB DEFAULT '{}',
98
+ created_at TIMESTAMPTZ DEFAULT NOW(),
99
+ updated_at TIMESTAMPTZ DEFAULT NOW()
100
+ );
101
+ ```
102
+
103
+ ### 6. `learnings`
104
+ Self-improvement records (replaces LEARNINGS.md).
105
+
106
+ ```sql
107
+ CREATE TABLE learnings (
108
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
109
+ agent_id TEXT NOT NULL,
110
+ category TEXT NOT NULL, -- 'error', 'correction', 'improvement', 'capability_gap'
111
+ trigger TEXT NOT NULL, -- What caused this learning
112
+ lesson TEXT NOT NULL, -- What was learned
113
+ action TEXT, -- What to do differently
114
+ severity TEXT DEFAULT 'info', -- 'info', 'warning', 'critical'
115
+ source_session_id UUID REFERENCES sessions(id),
116
+ applied_count INT DEFAULT 0, -- How many times this learning was used
117
+ created_at TIMESTAMPTZ DEFAULT NOW(),
118
+ metadata JSONB DEFAULT '{}'
119
+ );
120
+ ```
121
+
122
+ ## Key Features
123
+
124
+ ### 1. Session Summarization
125
+ When a session ends (or grows too long), automatically summarize it:
126
+ - Extract key decisions
127
+ - Note new entities/relationships
128
+ - Create memories from important facts
129
+ - Store summary in session record
130
+
131
+ ### 2. Semantic Memory Search
132
+ Instead of loading entire MEMORY.md:
133
+ ```sql
134
+ -- Find relevant memories for current context
135
+ SELECT content, importance, created_at
136
+ FROM memories
137
+ WHERE agent_id = $1
138
+ ORDER BY embedding <=> $2 -- Vector similarity
139
+ LIMIT 10;
140
+ ```
141
+
142
+ ### 3. Context Window Management
143
+ Before each response, pull relevant context:
144
+ - Recent messages from current session
145
+ - Relevant memories (semantic search)
146
+ - Active tasks
147
+ - Entity info for mentioned people/things
148
+
149
+ ### 4. Multi-Agent Memory Sharing
150
+ Agents can share memories:
151
+ ```sql
152
+ -- Get memories shared across all agents
153
+ SELECT * FROM memories
154
+ WHERE agent_id = 'shared'
155
+ AND user_id = $1;
156
+ ```
157
+
158
+ ## Migration Strategy
159
+
160
+ ### From Markdown to Supabase
161
+ 1. Parse existing MEMORY.md → memories table
162
+ 2. Parse daily logs → sessions + messages
163
+ 3. Parse TODO.md → tasks table
164
+ 4. Parse LEARNINGS.md → learnings table
165
+ 5. Keep markdown as backup/fallback
166
+
167
+ ## API Design (npm package)
168
+
169
+ ```typescript
170
+ import { OpenClawMemory } from 'openclaw-memory';
171
+
172
+ const memory = new OpenClawMemory({
173
+ supabaseUrl: process.env.SUPABASE_URL,
174
+ supabaseKey: process.env.SUPABASE_KEY,
175
+ agentId: 'main'
176
+ });
177
+
178
+ // Start a session
179
+ const session = await memory.startSession({
180
+ userId: 'han',
181
+ channel: 'telegram'
182
+ });
183
+
184
+ // Log messages
185
+ await memory.addMessage(session.id, {
186
+ role: 'user',
187
+ content: 'Hello!'
188
+ });
189
+
190
+ // Create a memory
191
+ await memory.remember({
192
+ content: 'Han prefers concise responses',
193
+ category: 'preference',
194
+ importance: 0.8
195
+ });
196
+
197
+ // Search memories
198
+ const relevant = await memory.recall('user preferences', { limit: 5 });
199
+
200
+ // End session with summary
201
+ await memory.endSession(session.id, {
202
+ summary: 'Discussed project requirements...'
203
+ });
204
+ ```
205
+
206
+ ## Benefits Summary
207
+
208
+ | Problem | Solution |
209
+ |---------|----------|
210
+ | Context window limits | Only load relevant memories via semantic search |
211
+ | Forgetting across sessions | Persistent database with session history |
212
+ | Unstructured data | SQL queries, typed schemas, relationships |
213
+ | No search | pgvector semantic search + full-text search |
214
+ | Single agent | Multi-agent memory sharing |
215
+ | Manual memory curation | Auto-extract from conversations |
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Clawdbot Integration for OpenClaw Memory
3
+ *
4
+ * This module provides integration hooks for Clawdbot to:
5
+ * 1. Auto-log all messages to sessions
6
+ * 2. Replace memory_search with semantic recall
7
+ * 3. Replace memory_get with database queries
8
+ * 4. Inject relevant context into system prompts
9
+ * 5. Handle session lifecycle
10
+ */
11
+ import { OpenClawMemory, Memory, Learning, Task } from './index';
12
+ export interface ClawdbotConfig {
13
+ supabaseUrl: string;
14
+ supabaseKey: string;
15
+ agentId: string;
16
+ userId?: string;
17
+ embeddingProvider?: 'openai' | 'voyage' | 'none';
18
+ openaiApiKey?: string;
19
+ autoLog?: boolean;
20
+ autoInject?: boolean;
21
+ sessionTimeout?: number;
22
+ }
23
+ export interface MessageContext {
24
+ sessionId?: string;
25
+ userId?: string;
26
+ channel?: string;
27
+ messageId?: string;
28
+ timestamp?: string;
29
+ model?: string;
30
+ }
31
+ export declare class ClawdbotMemoryIntegration {
32
+ private memory;
33
+ private config;
34
+ private activeSessions;
35
+ private sessionTimeoutMs;
36
+ constructor(config: ClawdbotConfig);
37
+ /**
38
+ * Initialize the memory system
39
+ */
40
+ initialize(): Promise<void>;
41
+ /**
42
+ * Get or create a session for a chat/user
43
+ */
44
+ getOrCreateSession(chatId: string, context?: MessageContext): Promise<string>;
45
+ /**
46
+ * Log a user message
47
+ */
48
+ logUserMessage(chatId: string, content: string, context?: MessageContext): Promise<void>;
49
+ /**
50
+ * Log an assistant message
51
+ */
52
+ logAssistantMessage(chatId: string, content: string, context?: MessageContext): Promise<void>;
53
+ /**
54
+ * Log a system message
55
+ */
56
+ logSystemMessage(chatId: string, content: string, context?: MessageContext): Promise<void>;
57
+ /**
58
+ * Replace memory_search - semantic search for memories
59
+ */
60
+ memorySearch(query: string, opts?: {
61
+ userId?: string;
62
+ category?: string;
63
+ limit?: number;
64
+ minImportance?: number;
65
+ }): Promise<Array<{
66
+ content: string;
67
+ category?: string;
68
+ importance: number;
69
+ created_at: string;
70
+ }>>;
71
+ /**
72
+ * Replace memory_get - get memories by category
73
+ */
74
+ memoryGet(opts?: {
75
+ category?: string;
76
+ userId?: string;
77
+ limit?: number;
78
+ }): Promise<Array<{
79
+ content: string;
80
+ category?: string;
81
+ importance: number;
82
+ }>>;
83
+ /**
84
+ * Build context for system prompt injection
85
+ */
86
+ buildContext(query: string, opts?: {
87
+ includeMemories?: boolean;
88
+ includeLearnings?: boolean;
89
+ includeRecentMessages?: boolean;
90
+ chatId?: string;
91
+ maxMemories?: number;
92
+ maxLearnings?: number;
93
+ maxMessages?: number;
94
+ }): Promise<string>;
95
+ /**
96
+ * Store a memory
97
+ */
98
+ remember(content: string, opts?: {
99
+ category?: string;
100
+ importance?: number;
101
+ userId?: string;
102
+ chatId?: string;
103
+ expiresAt?: string;
104
+ }): Promise<Memory>;
105
+ /**
106
+ * Record a learning
107
+ */
108
+ learn(learning: {
109
+ category: 'error' | 'correction' | 'improvement' | 'capability_gap';
110
+ trigger: string;
111
+ lesson: string;
112
+ action?: string;
113
+ severity?: 'info' | 'warning' | 'critical';
114
+ chatId?: string;
115
+ }): Promise<Learning>;
116
+ /**
117
+ * Create a task
118
+ */
119
+ createTask(task: {
120
+ title: string;
121
+ description?: string;
122
+ priority?: number;
123
+ dueAt?: string;
124
+ userId?: string;
125
+ parentTaskId?: string;
126
+ }): Promise<Task>;
127
+ /**
128
+ * Get upcoming tasks for reminders
129
+ */
130
+ getUpcomingTasks(hoursAhead?: number): Promise<Array<Task & {
131
+ timeUntilDue: number;
132
+ }>>;
133
+ /**
134
+ * End a session
135
+ */
136
+ endSession(chatId: string, opts?: {
137
+ summary?: string;
138
+ autoSummarize?: boolean;
139
+ extractMemories?: boolean;
140
+ }): Promise<void>;
141
+ /**
142
+ * End all inactive sessions
143
+ */
144
+ cleanupInactiveSessions(): Promise<void>;
145
+ /**
146
+ * Heartbeat check - call this periodically (e.g., every 30 min)
147
+ */
148
+ heartbeat(): Promise<{
149
+ upcomingTasks: Array<Task & {
150
+ timeUntilDue: number;
151
+ }>;
152
+ inactiveSessions: number;
153
+ }>;
154
+ /**
155
+ * Get the underlying OpenClawMemory instance for advanced operations
156
+ */
157
+ getMemory(): OpenClawMemory;
158
+ }
159
+ /**
160
+ * Factory function to create integration instance
161
+ */
162
+ export declare function createClawdbotIntegration(config: ClawdbotConfig): ClawdbotMemoryIntegration;
163
+ /**
164
+ * Express/Koa-style middleware for auto-logging
165
+ */
166
+ export declare function createLoggingMiddleware(integration: ClawdbotMemoryIntegration): (message: {
167
+ chatId: string;
168
+ role: "user" | "assistant" | "system";
169
+ content: string;
170
+ context?: MessageContext;
171
+ }) => Promise<void>;