agentmesh-ai 0.2.1 → 0.3.1
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/GUIDE.md +155 -286
- package/README.md +127 -144
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +41 -22
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/join.d.ts +1 -5
- package/dist/cli/commands/join.d.ts.map +1 -1
- package/dist/cli/commands/join.js +99 -76
- package/dist/cli/commands/join.js.map +1 -1
- package/dist/cli/commands/serve.d.ts.map +1 -1
- package/dist/cli/commands/serve.js +8 -1
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +31 -10
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +15 -0
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/index.js +3 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cloud/cloud-conversation.d.ts +83 -0
- package/dist/cloud/cloud-conversation.d.ts.map +1 -0
- package/dist/cloud/cloud-conversation.js +357 -0
- package/dist/cloud/cloud-conversation.js.map +1 -0
- package/dist/cloud/index.d.ts +4 -0
- package/dist/cloud/index.d.ts.map +1 -0
- package/dist/cloud/index.js +3 -0
- package/dist/cloud/index.js.map +1 -0
- package/dist/cloud/supabase-client.d.ts +29 -0
- package/dist/cloud/supabase-client.d.ts.map +1 -0
- package/dist/cloud/supabase-client.js +135 -0
- package/dist/cloud/supabase-client.js.map +1 -0
- package/dist/conversation/server.d.ts.map +1 -1
- package/dist/conversation/server.js +6 -0
- package/dist/conversation/server.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/conversation-tools.d.ts +5 -1
- package/dist/mcp/conversation-tools.d.ts.map +1 -1
- package/dist/mcp/conversation-tools.js +202 -149
- package/dist/mcp/conversation-tools.js.map +1 -1
- package/dist/mcp/index.js +94 -36
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/memory-tools.d.ts +20 -2
- package/dist/mcp/memory-tools.d.ts.map +1 -1
- package/dist/mcp/memory-tools.js +88 -44
- package/dist/mcp/memory-tools.js.map +1 -1
- package/dist/memory/index.d.ts +1 -0
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +1 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/merge-view.d.ts.map +1 -1
- package/dist/memory/merge-view.js +5 -4
- package/dist/memory/merge-view.js.map +1 -1
- package/dist/memory/reader.js +2 -2
- package/dist/memory/reader.js.map +1 -1
- package/dist/memory/schema.d.ts +3 -0
- package/dist/memory/schema.d.ts.map +1 -1
- package/dist/memory/schema.js +1 -0
- package/dist/memory/schema.js.map +1 -1
- package/dist/memory/types.d.ts +1 -0
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/write-utils.d.ts +30 -0
- package/dist/memory/write-utils.d.ts.map +1 -0
- package/dist/memory/write-utils.js +98 -0
- package/dist/memory/write-utils.js.map +1 -0
- package/dist/memory/writer.d.ts.map +1 -1
- package/dist/memory/writer.js +21 -84
- package/dist/memory/writer.js.map +1 -1
- package/dist/utils/id.d.ts +2 -0
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +4 -0
- package/dist/utils/id.js.map +1 -1
- package/dist/utils/notify.d.ts +2 -0
- package/dist/utils/notify.d.ts.map +1 -0
- package/dist/utils/notify.js +50 -0
- package/dist/utils/notify.js.map +1 -0
- package/package.json +5 -4
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { AgentIdentity, StoredMessage, DecisionProposedMessage, DecisionResolvedMessage, MeetingStatusMessage, MemorySyncedMessage } from '../conversation/protocol.js';
|
|
2
|
+
export interface CloudConversationClientOptions {
|
|
3
|
+
teamId: string;
|
|
4
|
+
agent: AgentIdentity;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Realtime conversation client backed by Supabase.
|
|
8
|
+
*
|
|
9
|
+
* - Messages are broadcast instantly via Supabase Realtime channels.
|
|
10
|
+
* - Messages are persisted to team_messages table for history.
|
|
11
|
+
* - Presence tracks who is online.
|
|
12
|
+
* - No server needed — fully serverless.
|
|
13
|
+
*/
|
|
14
|
+
export declare class CloudConversationClient {
|
|
15
|
+
private options;
|
|
16
|
+
private channel;
|
|
17
|
+
private connected;
|
|
18
|
+
private messageBuffer;
|
|
19
|
+
private activeTopics;
|
|
20
|
+
private connectedAgents;
|
|
21
|
+
private pendingDecisionsList;
|
|
22
|
+
private resolvedDecisionsList;
|
|
23
|
+
private meetingStatusList;
|
|
24
|
+
private syncedMemoriesMap;
|
|
25
|
+
private messageListeners;
|
|
26
|
+
private incomingHandlers;
|
|
27
|
+
constructor(options: CloudConversationClientOptions);
|
|
28
|
+
get isConnected(): boolean;
|
|
29
|
+
get agents(): AgentIdentity[];
|
|
30
|
+
get topics(): string[];
|
|
31
|
+
get recentMessages(): StoredMessage[];
|
|
32
|
+
get pendingDecisions(): DecisionProposedMessage[];
|
|
33
|
+
get resolvedDecisions(): DecisionResolvedMessage[];
|
|
34
|
+
get meetings(): MeetingStatusMessage[];
|
|
35
|
+
get syncedMemories(): MemorySyncedMessage[];
|
|
36
|
+
/** Connect to the team's Realtime channel and load history from DB. */
|
|
37
|
+
connect(): Promise<void>;
|
|
38
|
+
/** Disconnect from the channel. */
|
|
39
|
+
disconnect(): void;
|
|
40
|
+
/** Send a chat message — broadcast instantly + persist to DB. */
|
|
41
|
+
sendMessage(topic: string, content: string, related_to?: string): void;
|
|
42
|
+
/** Record a discussion conclusion. */
|
|
43
|
+
conclude(topic: string, summary: string, tags: string[]): void;
|
|
44
|
+
/** Propose a decision for team voting. */
|
|
45
|
+
proposeDecision(decisionId: string, topic: string, options: Array<{
|
|
46
|
+
label: string;
|
|
47
|
+
description: string;
|
|
48
|
+
}>, recommendation?: string): void;
|
|
49
|
+
/** Vote on a pending decision. */
|
|
50
|
+
vote(decisionId: string, vote: 'approve' | 'reject', choice?: string, reason?: string): void;
|
|
51
|
+
/** Start a meeting requiring specific agents. */
|
|
52
|
+
startMeeting(meetingId: string, topic: string, requiredAgents: string[]): void;
|
|
53
|
+
/** Conclude an active meeting. */
|
|
54
|
+
concludeMeeting(meetingId: string): void;
|
|
55
|
+
/** Upload memory entries (for cross-agent sync via broadcast). */
|
|
56
|
+
syncMemory(entries: Array<{
|
|
57
|
+
topic: string;
|
|
58
|
+
tags: string[];
|
|
59
|
+
content: string;
|
|
60
|
+
date: string;
|
|
61
|
+
}>): void;
|
|
62
|
+
/** Get messages for a specific topic. */
|
|
63
|
+
getTopicMessages(topic: string): StoredMessage[];
|
|
64
|
+
/**
|
|
65
|
+
* Wait for a new message on a topic.
|
|
66
|
+
*
|
|
67
|
+
* This is the key improvement over WebSocket polling:
|
|
68
|
+
* returns a Promise that resolves as soon as a message arrives,
|
|
69
|
+
* or rejects on timeout. The discuss tool uses this instead of
|
|
70
|
+
* sleep-and-poll loops.
|
|
71
|
+
*/
|
|
72
|
+
waitForMessage(topic: string, timeoutMs: number): Promise<StoredMessage>;
|
|
73
|
+
/**
|
|
74
|
+
* Register a handler for any incoming message from other agents.
|
|
75
|
+
* Used by MCP to trigger desktop notifications.
|
|
76
|
+
*/
|
|
77
|
+
onIncomingMessage(handler: (msg: StoredMessage) => void): void;
|
|
78
|
+
private handleIncomingMessage;
|
|
79
|
+
private addMessage;
|
|
80
|
+
private loadHistory;
|
|
81
|
+
private persistMessage;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=cloud-conversation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-conversation.d.ts","sourceRoot":"","sources":["../../src/cloud/cloud-conversation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { getSupabaseClient } from './supabase-client.js';
|
|
2
|
+
/**
|
|
3
|
+
* Realtime conversation client backed by Supabase.
|
|
4
|
+
*
|
|
5
|
+
* - Messages are broadcast instantly via Supabase Realtime channels.
|
|
6
|
+
* - Messages are persisted to team_messages table for history.
|
|
7
|
+
* - Presence tracks who is online.
|
|
8
|
+
* - No server needed — fully serverless.
|
|
9
|
+
*/
|
|
10
|
+
export class CloudConversationClient {
|
|
11
|
+
options;
|
|
12
|
+
channel = null;
|
|
13
|
+
connected = false;
|
|
14
|
+
messageBuffer = [];
|
|
15
|
+
activeTopics = [];
|
|
16
|
+
connectedAgents = [];
|
|
17
|
+
pendingDecisionsList = [];
|
|
18
|
+
resolvedDecisionsList = [];
|
|
19
|
+
meetingStatusList = [];
|
|
20
|
+
syncedMemoriesMap = new Map();
|
|
21
|
+
messageListeners = [];
|
|
22
|
+
incomingHandlers = [];
|
|
23
|
+
constructor(options) {
|
|
24
|
+
this.options = options;
|
|
25
|
+
}
|
|
26
|
+
get isConnected() {
|
|
27
|
+
return this.connected;
|
|
28
|
+
}
|
|
29
|
+
get agents() {
|
|
30
|
+
return [...this.connectedAgents];
|
|
31
|
+
}
|
|
32
|
+
get topics() {
|
|
33
|
+
return [...this.activeTopics];
|
|
34
|
+
}
|
|
35
|
+
get recentMessages() {
|
|
36
|
+
return [...this.messageBuffer];
|
|
37
|
+
}
|
|
38
|
+
get pendingDecisions() {
|
|
39
|
+
return [...this.pendingDecisionsList];
|
|
40
|
+
}
|
|
41
|
+
get resolvedDecisions() {
|
|
42
|
+
return [...this.resolvedDecisionsList];
|
|
43
|
+
}
|
|
44
|
+
get meetings() {
|
|
45
|
+
return [...this.meetingStatusList];
|
|
46
|
+
}
|
|
47
|
+
get syncedMemories() {
|
|
48
|
+
return [...this.syncedMemoriesMap.values()];
|
|
49
|
+
}
|
|
50
|
+
/** Connect to the team's Realtime channel and load history from DB. */
|
|
51
|
+
async connect() {
|
|
52
|
+
const supabase = getSupabaseClient();
|
|
53
|
+
// Load message history from DB
|
|
54
|
+
await this.loadHistory();
|
|
55
|
+
// Subscribe to Realtime channel
|
|
56
|
+
this.channel = supabase.channel(`team:${this.options.teamId}`, {
|
|
57
|
+
config: { broadcast: { self: false } },
|
|
58
|
+
});
|
|
59
|
+
// Listen for broadcast messages
|
|
60
|
+
this.channel.on('broadcast', { event: 'chat' }, (payload) => {
|
|
61
|
+
this.handleIncomingMessage(payload.payload);
|
|
62
|
+
});
|
|
63
|
+
this.channel.on('broadcast', { event: 'conclusion' }, (payload) => {
|
|
64
|
+
// A conclusion is also a message for display purposes
|
|
65
|
+
this.handleIncomingMessage(payload.payload);
|
|
66
|
+
});
|
|
67
|
+
this.channel.on('broadcast', { event: 'decision_proposed' }, (payload) => {
|
|
68
|
+
const msg = payload.payload;
|
|
69
|
+
msg.type = 'DECISION_PROPOSED';
|
|
70
|
+
this.pendingDecisionsList.push(msg);
|
|
71
|
+
});
|
|
72
|
+
this.channel.on('broadcast', { event: 'decision_resolved' }, (payload) => {
|
|
73
|
+
const msg = payload.payload;
|
|
74
|
+
msg.type = 'DECISION_RESOLVED';
|
|
75
|
+
this.resolvedDecisionsList.push(msg);
|
|
76
|
+
this.pendingDecisionsList = this.pendingDecisionsList.filter(d => d.decisionId !== msg.decisionId);
|
|
77
|
+
});
|
|
78
|
+
this.channel.on('broadcast', { event: 'vote' }, (payload) => {
|
|
79
|
+
// Track votes on pending decisions
|
|
80
|
+
const vote = payload.payload;
|
|
81
|
+
// Votes are tracked but resolution happens via decision_resolved event
|
|
82
|
+
});
|
|
83
|
+
this.channel.on('broadcast', { event: 'meeting_status' }, (payload) => {
|
|
84
|
+
const msg = payload.payload;
|
|
85
|
+
msg.type = 'MEETING_STATUS';
|
|
86
|
+
const idx = this.meetingStatusList.findIndex(m => m.meetingId === msg.meetingId);
|
|
87
|
+
if (idx >= 0) {
|
|
88
|
+
this.meetingStatusList[idx] = msg;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.meetingStatusList.push(msg);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
// Presence: track who is online
|
|
95
|
+
this.channel.on('presence', { event: 'sync' }, () => {
|
|
96
|
+
const state = this.channel.presenceState();
|
|
97
|
+
this.connectedAgents = [];
|
|
98
|
+
for (const key of Object.keys(state)) {
|
|
99
|
+
const presences = state[key];
|
|
100
|
+
for (const p of presences) {
|
|
101
|
+
if (p.agent) {
|
|
102
|
+
this.connectedAgents.push(p.agent);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
// Subscribe and track self
|
|
108
|
+
await new Promise((resolve, reject) => {
|
|
109
|
+
const timeout = setTimeout(() => reject(new Error('Connection timeout')), 10000);
|
|
110
|
+
this.channel.subscribe(async (status) => {
|
|
111
|
+
if (status === 'SUBSCRIBED') {
|
|
112
|
+
clearTimeout(timeout);
|
|
113
|
+
// Announce presence
|
|
114
|
+
await this.channel.track({ agent: this.options.agent });
|
|
115
|
+
this.connected = true;
|
|
116
|
+
resolve();
|
|
117
|
+
}
|
|
118
|
+
else if (status === 'CHANNEL_ERROR') {
|
|
119
|
+
clearTimeout(timeout);
|
|
120
|
+
// Clean up the failed channel
|
|
121
|
+
if (this.channel) {
|
|
122
|
+
const supabase = getSupabaseClient();
|
|
123
|
+
supabase.removeChannel(this.channel);
|
|
124
|
+
this.channel = null;
|
|
125
|
+
}
|
|
126
|
+
reject(new Error('Channel error'));
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/** Disconnect from the channel. */
|
|
132
|
+
disconnect() {
|
|
133
|
+
if (this.channel) {
|
|
134
|
+
this.channel.untrack();
|
|
135
|
+
const supabase = getSupabaseClient();
|
|
136
|
+
supabase.removeChannel(this.channel);
|
|
137
|
+
this.channel = null;
|
|
138
|
+
this.connected = false;
|
|
139
|
+
}
|
|
140
|
+
// Clear pending waitForMessage listeners to prevent hanging promises
|
|
141
|
+
this.messageListeners = [];
|
|
142
|
+
}
|
|
143
|
+
/** Send a chat message — broadcast instantly + persist to DB. */
|
|
144
|
+
sendMessage(topic, content, related_to) {
|
|
145
|
+
const msg = {
|
|
146
|
+
from: this.options.agent,
|
|
147
|
+
topic,
|
|
148
|
+
content,
|
|
149
|
+
timestamp: new Date().toISOString(),
|
|
150
|
+
...(related_to ? { related_to } : {}),
|
|
151
|
+
};
|
|
152
|
+
// Add to local buffer immediately
|
|
153
|
+
this.addMessage(msg);
|
|
154
|
+
// Broadcast to other agents (instant push)
|
|
155
|
+
this.channel?.send({ type: 'broadcast', event: 'chat', payload: msg });
|
|
156
|
+
// Persist to DB (fire-and-forget)
|
|
157
|
+
this.persistMessage(topic, content, 'message', related_to);
|
|
158
|
+
}
|
|
159
|
+
/** Record a discussion conclusion. */
|
|
160
|
+
conclude(topic, summary, tags) {
|
|
161
|
+
const msg = {
|
|
162
|
+
from: this.options.agent,
|
|
163
|
+
topic,
|
|
164
|
+
content: `[CONCLUSION] ${summary}`,
|
|
165
|
+
timestamp: new Date().toISOString(),
|
|
166
|
+
};
|
|
167
|
+
this.addMessage(msg);
|
|
168
|
+
this.channel?.send({ type: 'broadcast', event: 'conclusion', payload: msg });
|
|
169
|
+
this.persistMessage(topic, `[CONCLUSION] ${summary}`, 'conclusion', undefined, { tags });
|
|
170
|
+
}
|
|
171
|
+
/** Propose a decision for team voting. */
|
|
172
|
+
proposeDecision(decisionId, topic, options, recommendation) {
|
|
173
|
+
const proposal = {
|
|
174
|
+
type: 'DECISION_PROPOSED',
|
|
175
|
+
decisionId,
|
|
176
|
+
topic,
|
|
177
|
+
options,
|
|
178
|
+
recommendation,
|
|
179
|
+
proposedBy: this.options.agent,
|
|
180
|
+
timestamp: new Date().toISOString(),
|
|
181
|
+
};
|
|
182
|
+
this.pendingDecisionsList.push(proposal);
|
|
183
|
+
this.channel?.send({ type: 'broadcast', event: 'decision_proposed', payload: proposal });
|
|
184
|
+
this.persistMessage(topic, `[DECISION] ${topic}`, 'decision_proposal', undefined, {
|
|
185
|
+
decisionId, options, recommendation,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/** Vote on a pending decision. */
|
|
189
|
+
vote(decisionId, vote, choice, reason) {
|
|
190
|
+
const votePayload = {
|
|
191
|
+
decisionId,
|
|
192
|
+
agentId: this.options.agent.id,
|
|
193
|
+
vote,
|
|
194
|
+
choice,
|
|
195
|
+
reason,
|
|
196
|
+
};
|
|
197
|
+
this.channel?.send({ type: 'broadcast', event: 'vote', payload: votePayload });
|
|
198
|
+
this.persistMessage(decisionId, `[VOTE] ${vote}${choice ? `: ${choice}` : ''}`, 'vote', undefined, {
|
|
199
|
+
decisionId, vote, choice, reason,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
/** Start a meeting requiring specific agents. */
|
|
203
|
+
startMeeting(meetingId, topic, requiredAgents) {
|
|
204
|
+
const present = this.connectedAgents.map(a => a.id);
|
|
205
|
+
const missing = requiredAgents.filter(id => !present.includes(id) && id !== this.options.agent.id);
|
|
206
|
+
const allPresent = [...new Set([...present.filter(id => requiredAgents.includes(id)), this.options.agent.id])];
|
|
207
|
+
const status = {
|
|
208
|
+
type: 'MEETING_STATUS',
|
|
209
|
+
meetingId,
|
|
210
|
+
topic,
|
|
211
|
+
status: missing.length === 0 ? 'active' : 'waiting',
|
|
212
|
+
requiredAgents,
|
|
213
|
+
presentAgents: allPresent,
|
|
214
|
+
missingAgents: missing,
|
|
215
|
+
startedBy: this.options.agent.id,
|
|
216
|
+
};
|
|
217
|
+
this.meetingStatusList.push(status);
|
|
218
|
+
this.channel?.send({ type: 'broadcast', event: 'meeting_status', payload: status });
|
|
219
|
+
}
|
|
220
|
+
/** Conclude an active meeting. */
|
|
221
|
+
concludeMeeting(meetingId) {
|
|
222
|
+
const idx = this.meetingStatusList.findIndex(m => m.meetingId === meetingId);
|
|
223
|
+
if (idx >= 0) {
|
|
224
|
+
this.meetingStatusList[idx].status = 'concluded';
|
|
225
|
+
this.channel?.send({
|
|
226
|
+
type: 'broadcast',
|
|
227
|
+
event: 'meeting_status',
|
|
228
|
+
payload: this.meetingStatusList[idx],
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/** Upload memory entries (for cross-agent sync via broadcast). */
|
|
233
|
+
syncMemory(entries) {
|
|
234
|
+
const msg = {
|
|
235
|
+
type: 'MEMORY_SYNCED',
|
|
236
|
+
agent: this.options.agent,
|
|
237
|
+
entries,
|
|
238
|
+
};
|
|
239
|
+
this.syncedMemoriesMap.set(this.options.agent.id, msg);
|
|
240
|
+
// Don't broadcast memory sync — cloud memory already handles this via DB
|
|
241
|
+
}
|
|
242
|
+
/** Get messages for a specific topic. */
|
|
243
|
+
getTopicMessages(topic) {
|
|
244
|
+
return this.messageBuffer.filter(m => m.topic === topic);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Wait for a new message on a topic.
|
|
248
|
+
*
|
|
249
|
+
* This is the key improvement over WebSocket polling:
|
|
250
|
+
* returns a Promise that resolves as soon as a message arrives,
|
|
251
|
+
* or rejects on timeout. The discuss tool uses this instead of
|
|
252
|
+
* sleep-and-poll loops.
|
|
253
|
+
*/
|
|
254
|
+
waitForMessage(topic, timeoutMs) {
|
|
255
|
+
return new Promise((resolve, reject) => {
|
|
256
|
+
const timer = setTimeout(() => {
|
|
257
|
+
// Remove listener on timeout
|
|
258
|
+
this.messageListeners = this.messageListeners.filter(l => l !== listener);
|
|
259
|
+
reject(new Error('timeout'));
|
|
260
|
+
}, timeoutMs);
|
|
261
|
+
const listener = (msg) => {
|
|
262
|
+
if (msg.topic === topic && msg.from.id !== this.options.agent.id) {
|
|
263
|
+
clearTimeout(timer);
|
|
264
|
+
this.messageListeners = this.messageListeners.filter(l => l !== listener);
|
|
265
|
+
resolve(msg);
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
this.messageListeners.push(listener);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Register a handler for any incoming message from other agents.
|
|
273
|
+
* Used by MCP to trigger desktop notifications.
|
|
274
|
+
*/
|
|
275
|
+
onIncomingMessage(handler) {
|
|
276
|
+
this.incomingHandlers.push(handler);
|
|
277
|
+
}
|
|
278
|
+
// ── Internal ──────────────────────────────────────────────────────────────
|
|
279
|
+
handleIncomingMessage(msg) {
|
|
280
|
+
this.addMessage(msg);
|
|
281
|
+
// Notify waitForMessage listeners
|
|
282
|
+
for (const listener of this.messageListeners) {
|
|
283
|
+
listener(msg);
|
|
284
|
+
}
|
|
285
|
+
// Notify incoming message handlers (for desktop notifications etc.)
|
|
286
|
+
for (const handler of this.incomingHandlers) {
|
|
287
|
+
handler(msg);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
addMessage(msg) {
|
|
291
|
+
this.messageBuffer.push(msg);
|
|
292
|
+
if (this.messageBuffer.length > 1000) {
|
|
293
|
+
this.messageBuffer = this.messageBuffer.slice(-1000);
|
|
294
|
+
}
|
|
295
|
+
if (!this.activeTopics.includes(msg.topic)) {
|
|
296
|
+
this.activeTopics.push(msg.topic);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async loadHistory() {
|
|
300
|
+
const supabase = getSupabaseClient();
|
|
301
|
+
try {
|
|
302
|
+
const result = await Promise.race([
|
|
303
|
+
supabase
|
|
304
|
+
.from('team_messages')
|
|
305
|
+
.select('*')
|
|
306
|
+
.eq('team_id', this.options.teamId)
|
|
307
|
+
.order('created_at', { ascending: true })
|
|
308
|
+
.limit(200),
|
|
309
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Cloud history load timed out')), 10000)),
|
|
310
|
+
]);
|
|
311
|
+
if (result.data) {
|
|
312
|
+
for (const row of result.data) {
|
|
313
|
+
const msg = {
|
|
314
|
+
from: {
|
|
315
|
+
id: row.agent_id,
|
|
316
|
+
displayName: row.agent_display_name,
|
|
317
|
+
role: row.agent_role,
|
|
318
|
+
tool: row.agent_tool,
|
|
319
|
+
},
|
|
320
|
+
topic: row.topic,
|
|
321
|
+
content: row.content,
|
|
322
|
+
timestamp: row.created_at,
|
|
323
|
+
...(row.related_to ? { related_to: row.related_to } : {}),
|
|
324
|
+
};
|
|
325
|
+
this.addMessage(msg);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
// Timeout or network error — start with empty history
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
async persistMessage(topic, content, messageType, related_to, metadata) {
|
|
334
|
+
const supabase = getSupabaseClient();
|
|
335
|
+
try {
|
|
336
|
+
const { error } = await supabase.from('team_messages').insert({
|
|
337
|
+
team_id: this.options.teamId,
|
|
338
|
+
topic,
|
|
339
|
+
agent_id: this.options.agent.id,
|
|
340
|
+
agent_display_name: this.options.agent.displayName,
|
|
341
|
+
agent_role: this.options.agent.role,
|
|
342
|
+
agent_tool: this.options.agent.tool,
|
|
343
|
+
content,
|
|
344
|
+
message_type: messageType,
|
|
345
|
+
metadata: metadata ?? {},
|
|
346
|
+
related_to,
|
|
347
|
+
});
|
|
348
|
+
if (error) {
|
|
349
|
+
process.stderr.write(`[agentmesh] message persist error: ${error.message}\n`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
catch (err) {
|
|
353
|
+
process.stderr.write(`[agentmesh] message persist error: ${err?.message ?? err}\n`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
//# sourceMappingURL=cloud-conversation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-conversation.js","sourceRoot":"","sources":["../../src/cloud/cloud-conversation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { getSupabaseClient, cloudReadAllMemories, cloudReadAgentMemory, cloudWriteMemory, joinTeamChannel, broadcastToTeam, leaveTeamChannel, } from './supabase-client.js';
|
|
2
|
+
export { CloudConversationClient } from './cloud-conversation.js';
|
|
3
|
+
export type { CloudConversationClientOptions } from './cloud-conversation.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cloud/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,YAAY,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { getSupabaseClient, cloudReadAllMemories, cloudReadAgentMemory, cloudWriteMemory, joinTeamChannel, broadcastToTeam, leaveTeamChannel, } from './supabase-client.js';
|
|
2
|
+
export { CloudConversationClient } from './cloud-conversation.js';
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cloud/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supabase cloud client for AgentMesh.
|
|
3
|
+
*
|
|
4
|
+
* Replaces local WebSocket with Supabase for:
|
|
5
|
+
* - Shared memory persistence (team_memories table)
|
|
6
|
+
* - Real-time agent communication (Supabase Realtime channels)
|
|
7
|
+
*/
|
|
8
|
+
import { type SupabaseClient, type RealtimeChannel } from '@supabase/supabase-js';
|
|
9
|
+
import type { AgentMemoryFile, WriteMemoryOptions, WriteResult } from '../memory/types.js';
|
|
10
|
+
/** Get or create the singleton Supabase client. */
|
|
11
|
+
export declare function getSupabaseClient(): SupabaseClient;
|
|
12
|
+
/** Read all agent memories for a team from Supabase. */
|
|
13
|
+
export declare function cloudReadAllMemories(teamId: string): Promise<AgentMemoryFile[]>;
|
|
14
|
+
/** Read a single agent's memory from Supabase. */
|
|
15
|
+
export declare function cloudReadAgentMemory(teamId: string, agentId: string): Promise<AgentMemoryFile | null>;
|
|
16
|
+
/** Write a memory entry to Supabase (upsert: insert or update by team_id + agent_id). */
|
|
17
|
+
export declare function cloudWriteMemory(teamId: string, agentId: string, agentRole: string, agentTool: string, options: WriteMemoryOptions): Promise<WriteResult>;
|
|
18
|
+
export interface CloudChannelOptions {
|
|
19
|
+
teamId: string;
|
|
20
|
+
agentId: string;
|
|
21
|
+
onMessage?: (payload: any) => void;
|
|
22
|
+
}
|
|
23
|
+
/** Subscribe to the team's realtime channel for live messages. */
|
|
24
|
+
export declare function joinTeamChannel(options: CloudChannelOptions): RealtimeChannel;
|
|
25
|
+
/** Send a broadcast message to the team channel. */
|
|
26
|
+
export declare function broadcastToTeam(channel: RealtimeChannel, event: string, payload: Record<string, any>): void;
|
|
27
|
+
/** Leave the team channel. */
|
|
28
|
+
export declare function leaveTeamChannel(): void;
|
|
29
|
+
//# sourceMappingURL=supabase-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supabase-client.d.ts","sourceRoot":"","sources":["../../src/cloud/supabase-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAgB,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAChG,OAAO,KAAK,EAAE,eAAe,EAAe,kBAAkB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAUxG,mDAAmD;AACnD,wBAAgB,iBAAiB,IAAI,cAAc,CAKlD;AAID,wDAAwD;AACxD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAmBrF;AAED,kDAAkD;AAClD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAkBjC;AAED,yFAAyF;AACzF,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,WAAW,CAAC,CA8CtB;AAID,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;CACpC;AAID,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,eAAe,CAmB7E;AAED,oDAAoD;AACpD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAO7B;AAED,8BAA8B;AAC9B,wBAAgB,gBAAgB,SAM/B"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supabase cloud client for AgentMesh.
|
|
3
|
+
*
|
|
4
|
+
* Replaces local WebSocket with Supabase for:
|
|
5
|
+
* - Shared memory persistence (team_memories table)
|
|
6
|
+
* - Real-time agent communication (Supabase Realtime channels)
|
|
7
|
+
*/
|
|
8
|
+
import { createClient } from '@supabase/supabase-js';
|
|
9
|
+
import { checkProtection, validateContent, buildMemoryEntry, upsertEntry } from '../memory/write-utils.js';
|
|
10
|
+
// Hardcoded Supabase config — single shared instance for all AgentMesh users.
|
|
11
|
+
// Each team is isolated by team_id. This is intentional: zero-config for users.
|
|
12
|
+
const SUPABASE_URL = 'https://hbdrhdeqyioxkzmoxnjp.supabase.co';
|
|
13
|
+
const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImhiZHJoZGVxeWlveGt6bW94bmpwIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzUxMzY4MTYsImV4cCI6MjA5MDcxMjgxNn0.BDKzJt4XQ1yS9eIoO0dp2Mx7flxU2eEwxfD8kAIlw_w';
|
|
14
|
+
let supabase = null;
|
|
15
|
+
/** Get or create the singleton Supabase client. */
|
|
16
|
+
export function getSupabaseClient() {
|
|
17
|
+
if (!supabase) {
|
|
18
|
+
supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
|
|
19
|
+
}
|
|
20
|
+
return supabase;
|
|
21
|
+
}
|
|
22
|
+
// ─── Memory CRUD ─────────────────────────────────────────────────────────────
|
|
23
|
+
/** Read all agent memories for a team from Supabase. */
|
|
24
|
+
export async function cloudReadAllMemories(teamId) {
|
|
25
|
+
const client = getSupabaseClient();
|
|
26
|
+
const { data, error } = await client
|
|
27
|
+
.from('team_memories')
|
|
28
|
+
.select('*')
|
|
29
|
+
.eq('team_id', teamId);
|
|
30
|
+
if (error) {
|
|
31
|
+
process.stderr.write(`[agentmesh] cloud read error: ${error.message}\n`);
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
return (data ?? []).map(row => ({
|
|
35
|
+
agent: row.agent_id,
|
|
36
|
+
role: row.agent_role ?? 'developer',
|
|
37
|
+
tool: row.agent_tool ?? 'unknown',
|
|
38
|
+
last_active: row.updated_at ?? new Date().toISOString(),
|
|
39
|
+
entries: (row.entries ?? []),
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
/** Read a single agent's memory from Supabase. */
|
|
43
|
+
export async function cloudReadAgentMemory(teamId, agentId) {
|
|
44
|
+
const client = getSupabaseClient();
|
|
45
|
+
const { data, error } = await client
|
|
46
|
+
.from('team_memories')
|
|
47
|
+
.select('*')
|
|
48
|
+
.eq('team_id', teamId)
|
|
49
|
+
.eq('agent_id', agentId)
|
|
50
|
+
.maybeSingle();
|
|
51
|
+
if (error || !data)
|
|
52
|
+
return null;
|
|
53
|
+
return {
|
|
54
|
+
agent: data.agent_id,
|
|
55
|
+
role: data.agent_role ?? 'developer',
|
|
56
|
+
tool: data.agent_tool ?? 'unknown',
|
|
57
|
+
last_active: data.updated_at ?? new Date().toISOString(),
|
|
58
|
+
entries: (data.entries ?? []),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** Write a memory entry to Supabase (upsert: insert or update by team_id + agent_id). */
|
|
62
|
+
export async function cloudWriteMemory(teamId, agentId, agentRole, agentTool, options) {
|
|
63
|
+
const client = getSupabaseClient();
|
|
64
|
+
// Check protection rules
|
|
65
|
+
const allMemories = await cloudReadAllMemories(teamId);
|
|
66
|
+
const { blocked, proposalWarning } = checkProtection(allMemories, agentId, options.topic);
|
|
67
|
+
if (blocked)
|
|
68
|
+
return blocked;
|
|
69
|
+
// Scan for secrets
|
|
70
|
+
const { blocked: secretBlocked, warnings } = validateContent(options.content);
|
|
71
|
+
if (secretBlocked)
|
|
72
|
+
return secretBlocked;
|
|
73
|
+
// Build and upsert entry
|
|
74
|
+
const existing = allMemories.find(m => m.agent === agentId);
|
|
75
|
+
const entries = existing ? [...existing.entries] : [];
|
|
76
|
+
const now = new Date().toISOString();
|
|
77
|
+
const newEntry = buildMemoryEntry(options, now);
|
|
78
|
+
upsertEntry(entries, newEntry, options);
|
|
79
|
+
// Write to Supabase
|
|
80
|
+
const { error } = await client
|
|
81
|
+
.from('team_memories')
|
|
82
|
+
.upsert({
|
|
83
|
+
team_id: teamId,
|
|
84
|
+
agent_id: agentId,
|
|
85
|
+
agent_role: agentRole,
|
|
86
|
+
agent_tool: agentTool,
|
|
87
|
+
entries,
|
|
88
|
+
updated_at: now,
|
|
89
|
+
}, { onConflict: 'team_id,agent_id' });
|
|
90
|
+
if (error) {
|
|
91
|
+
return { success: false, reason: `Cloud write failed: ${error.message}` };
|
|
92
|
+
}
|
|
93
|
+
const allWarnings = [...warnings];
|
|
94
|
+
if (proposalWarning)
|
|
95
|
+
allWarnings.push(proposalWarning);
|
|
96
|
+
return {
|
|
97
|
+
success: true,
|
|
98
|
+
...(allWarnings.length > 0 ? { warnings: allWarnings } : {}),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
let activeChannel = null;
|
|
102
|
+
/** Subscribe to the team's realtime channel for live messages. */
|
|
103
|
+
export function joinTeamChannel(options) {
|
|
104
|
+
const client = getSupabaseClient();
|
|
105
|
+
// Clean up existing channel
|
|
106
|
+
if (activeChannel) {
|
|
107
|
+
client.removeChannel(activeChannel);
|
|
108
|
+
}
|
|
109
|
+
const channel = client.channel(`team:${options.teamId}`, {
|
|
110
|
+
config: { broadcast: { self: false } },
|
|
111
|
+
});
|
|
112
|
+
channel.on('broadcast', { event: 'message' }, (payload) => {
|
|
113
|
+
options.onMessage?.(payload.payload);
|
|
114
|
+
});
|
|
115
|
+
channel.subscribe();
|
|
116
|
+
activeChannel = channel;
|
|
117
|
+
return channel;
|
|
118
|
+
}
|
|
119
|
+
/** Send a broadcast message to the team channel. */
|
|
120
|
+
export function broadcastToTeam(channel, event, payload) {
|
|
121
|
+
channel.send({
|
|
122
|
+
type: 'broadcast',
|
|
123
|
+
event,
|
|
124
|
+
payload,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/** Leave the team channel. */
|
|
128
|
+
export function leaveTeamChannel() {
|
|
129
|
+
if (activeChannel) {
|
|
130
|
+
const client = getSupabaseClient();
|
|
131
|
+
client.removeChannel(activeChannel);
|
|
132
|
+
activeChannel = null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=supabase-client.js.map
|