agentmesh-ai 0.4.0 → 0.5.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/GUIDE-EN.md +421 -0
- package/GUIDE.md +85 -4
- package/README.md +91 -8
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +29 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/join.d.ts.map +1 -1
- package/dist/cli/commands/join.js +34 -2
- package/dist/cli/commands/join.js.map +1 -1
- package/dist/cli/commands/status.js +1 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cloud/supabase-client.d.ts +14 -1
- package/dist/cloud/supabase-client.d.ts.map +1 -1
- package/dist/cloud/supabase-client.js +56 -0
- package/dist/cloud/supabase-client.js.map +1 -1
- package/dist/events/emitter.d.ts +11 -0
- package/dist/events/emitter.d.ts.map +1 -0
- package/dist/events/emitter.js +81 -0
- package/dist/events/emitter.js.map +1 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +3 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/webhook.d.ts +10 -0
- package/dist/events/webhook.d.ts.map +1 -0
- package/dist/events/webhook.js +153 -0
- package/dist/events/webhook.js.map +1 -0
- package/dist/federation/index.d.ts +4 -0
- package/dist/federation/index.d.ts.map +1 -0
- package/dist/federation/index.js +3 -0
- package/dist/federation/index.js.map +1 -0
- package/dist/federation/link.d.ts +10 -0
- package/dist/federation/link.d.ts.map +1 -0
- package/dist/federation/link.js +86 -0
- package/dist/federation/link.js.map +1 -0
- package/dist/federation/reader.d.ts +12 -0
- package/dist/federation/reader.d.ts.map +1 -0
- package/dist/federation/reader.js +60 -0
- package/dist/federation/reader.js.map +1 -0
- package/dist/federation/types.d.ts +26 -0
- package/dist/federation/types.d.ts.map +1 -0
- package/dist/federation/types.js +2 -0
- package/dist/federation/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/conversation-tools.d.ts.map +1 -1
- package/dist/mcp/conversation-tools.js +6 -5
- package/dist/mcp/conversation-tools.js.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/memory-tools.d.ts.map +1 -1
- package/dist/mcp/memory-tools.js +322 -16
- package/dist/mcp/memory-tools.js.map +1 -1
- package/dist/memory/consolidator.d.ts +14 -6
- package/dist/memory/consolidator.d.ts.map +1 -1
- package/dist/memory/consolidator.js +47 -0
- package/dist/memory/consolidator.js.map +1 -1
- package/dist/memory/merge-view.d.ts.map +1 -1
- package/dist/memory/merge-view.js +3 -0
- package/dist/memory/merge-view.js.map +1 -1
- package/dist/memory/scorer.d.ts +28 -0
- package/dist/memory/scorer.d.ts.map +1 -0
- package/dist/memory/scorer.js +149 -0
- package/dist/memory/scorer.js.map +1 -0
- package/dist/memory/timeline.d.ts +6 -0
- package/dist/memory/timeline.d.ts.map +1 -0
- package/dist/memory/timeline.js +85 -0
- package/dist/memory/timeline.js.map +1 -0
- package/dist/memory/types.d.ts +37 -2
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/write-utils.d.ts +6 -1
- package/dist/memory/write-utils.d.ts.map +1 -1
- package/dist/memory/write-utils.js +25 -0
- package/dist/memory/write-utils.js.map +1 -1
- package/dist/protocol/index.d.ts +25 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +22 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/sdk.d.ts +54 -1
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +107 -2
- package/dist/sdk.js.map +1 -1
- package/dist/templates/export.d.ts +17 -0
- package/dist/templates/export.d.ts.map +1 -0
- package/dist/templates/export.js +49 -0
- package/dist/templates/export.js.map +1 -0
- package/dist/templates/import.d.ts +19 -0
- package/dist/templates/import.d.ts.map +1 -0
- package/dist/templates/import.js +83 -0
- package/dist/templates/import.js.map +1 -0
- package/dist/templates/index.d.ts +4 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +3 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/types.d.ts +38 -0
- package/dist/templates/types.d.ts.map +1 -0
- package/dist/templates/types.js +2 -0
- package/dist/templates/types.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook dispatcher — POSTs events to registered webhook URLs.
|
|
3
|
+
*
|
|
4
|
+
* Supports HMAC-SHA256 signing for verification.
|
|
5
|
+
* Retries up to 3 times with exponential backoff.
|
|
6
|
+
*/
|
|
7
|
+
import { createHmac } from 'node:crypto';
|
|
8
|
+
import { getSupabaseClient } from '../cloud/supabase-client.js';
|
|
9
|
+
/** Dispatch an event to all matching webhooks for a team. Best-effort. */
|
|
10
|
+
export async function dispatchWebhooks(teamId, event) {
|
|
11
|
+
const webhooks = await getActiveWebhooks(teamId);
|
|
12
|
+
if (webhooks.length === 0)
|
|
13
|
+
return;
|
|
14
|
+
const matching = webhooks.filter(w => w.events.includes(event.type));
|
|
15
|
+
if (matching.length === 0)
|
|
16
|
+
return;
|
|
17
|
+
const payload = JSON.stringify({
|
|
18
|
+
event: event.type,
|
|
19
|
+
team_id: event.team_id,
|
|
20
|
+
agent: event.agent,
|
|
21
|
+
topic: event.topic,
|
|
22
|
+
timestamp: event.timestamp,
|
|
23
|
+
detail: event.detail,
|
|
24
|
+
metadata: event.metadata,
|
|
25
|
+
old_value: event.old_value,
|
|
26
|
+
new_value: event.new_value,
|
|
27
|
+
});
|
|
28
|
+
await Promise.allSettled(matching.map(w => deliverWithRetry(w, payload)));
|
|
29
|
+
}
|
|
30
|
+
/** Get active webhooks for a team. */
|
|
31
|
+
async function getActiveWebhooks(teamId) {
|
|
32
|
+
const supabase = getSupabaseClient();
|
|
33
|
+
const { data } = await supabase
|
|
34
|
+
.from('team_webhooks')
|
|
35
|
+
.select('*')
|
|
36
|
+
.eq('team_id', teamId)
|
|
37
|
+
.eq('active', true);
|
|
38
|
+
return (data ?? []).map(row => ({
|
|
39
|
+
id: row.id,
|
|
40
|
+
team_id: row.team_id,
|
|
41
|
+
url: row.url,
|
|
42
|
+
events: row.events,
|
|
43
|
+
secret: row.secret,
|
|
44
|
+
active: row.active,
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
/** Deliver a webhook with up to 3 retries (exponential backoff). */
|
|
48
|
+
async function deliverWithRetry(webhook, payload) {
|
|
49
|
+
const maxRetries = 3;
|
|
50
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
51
|
+
try {
|
|
52
|
+
const headers = {
|
|
53
|
+
'Content-Type': 'application/json',
|
|
54
|
+
'User-Agent': 'AgentMesh-Webhook/1.0',
|
|
55
|
+
};
|
|
56
|
+
if (webhook.secret) {
|
|
57
|
+
const signature = createHmac('sha256', webhook.secret)
|
|
58
|
+
.update(payload)
|
|
59
|
+
.digest('hex');
|
|
60
|
+
headers['X-AgentMesh-Signature'] = `sha256=${signature}`;
|
|
61
|
+
}
|
|
62
|
+
const response = await fetch(webhook.url, {
|
|
63
|
+
method: 'POST',
|
|
64
|
+
headers,
|
|
65
|
+
body: payload,
|
|
66
|
+
signal: AbortSignal.timeout(10000),
|
|
67
|
+
});
|
|
68
|
+
if (response.ok || response.status < 500)
|
|
69
|
+
return; // Success or client error (don't retry)
|
|
70
|
+
// 5xx → retry
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
// Network error → retry
|
|
74
|
+
process.stderr.write(`[agentmesh] webhook delivery attempt ${attempt + 1} failed for ${webhook.url}: ${err}\n`);
|
|
75
|
+
}
|
|
76
|
+
// Exponential backoff: 1s, 2s, 4s
|
|
77
|
+
if (attempt < maxRetries - 1) {
|
|
78
|
+
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Validate webhook URL — block internal/private addresses. */
|
|
83
|
+
function validateWebhookUrl(url) {
|
|
84
|
+
let parsed;
|
|
85
|
+
try {
|
|
86
|
+
parsed = new URL(url);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
throw new Error(`Invalid webhook URL: ${url}`);
|
|
90
|
+
}
|
|
91
|
+
if (!['http:', 'https:'].includes(parsed.protocol)) {
|
|
92
|
+
throw new Error(`Webhook URL must use http or https (got ${parsed.protocol})`);
|
|
93
|
+
}
|
|
94
|
+
const host = parsed.hostname.toLowerCase();
|
|
95
|
+
if (host === 'localhost' || host === '127.0.0.1' || host === '::1' || host === '0.0.0.0'
|
|
96
|
+
|| host.endsWith('.local') || host.startsWith('10.') || host.startsWith('192.168.')
|
|
97
|
+
|| /^172\.(1[6-9]|2\d|3[0-1])\./.test(host)) {
|
|
98
|
+
throw new Error(`Webhook URL cannot target private/internal addresses: ${host}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** Register a new webhook for a team. */
|
|
102
|
+
export async function registerWebhook(config) {
|
|
103
|
+
validateWebhookUrl(config.url);
|
|
104
|
+
const supabase = getSupabaseClient();
|
|
105
|
+
const { data, error } = await supabase
|
|
106
|
+
.from('team_webhooks')
|
|
107
|
+
.insert({
|
|
108
|
+
team_id: config.team_id,
|
|
109
|
+
url: config.url,
|
|
110
|
+
events: config.events,
|
|
111
|
+
secret: config.secret,
|
|
112
|
+
active: config.active,
|
|
113
|
+
})
|
|
114
|
+
.select()
|
|
115
|
+
.single();
|
|
116
|
+
if (error)
|
|
117
|
+
throw new Error(`Failed to register webhook: ${error.message}`);
|
|
118
|
+
return {
|
|
119
|
+
id: data.id,
|
|
120
|
+
team_id: data.team_id,
|
|
121
|
+
url: data.url,
|
|
122
|
+
events: data.events,
|
|
123
|
+
secret: data.secret,
|
|
124
|
+
active: data.active,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/** List webhooks for a team. */
|
|
128
|
+
export async function listWebhooks(teamId) {
|
|
129
|
+
const supabase = getSupabaseClient();
|
|
130
|
+
const { data } = await supabase
|
|
131
|
+
.from('team_webhooks')
|
|
132
|
+
.select('*')
|
|
133
|
+
.eq('team_id', teamId);
|
|
134
|
+
return (data ?? []).map(row => ({
|
|
135
|
+
id: row.id,
|
|
136
|
+
team_id: row.team_id,
|
|
137
|
+
url: row.url,
|
|
138
|
+
events: row.events,
|
|
139
|
+
secret: row.secret,
|
|
140
|
+
active: row.active,
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
/** Delete a webhook. */
|
|
144
|
+
export async function deleteWebhook(webhookId) {
|
|
145
|
+
const supabase = getSupabaseClient();
|
|
146
|
+
const { error } = await supabase
|
|
147
|
+
.from('team_webhooks')
|
|
148
|
+
.delete()
|
|
149
|
+
.eq('id', webhookId);
|
|
150
|
+
if (error)
|
|
151
|
+
throw new Error(`Failed to delete webhook: ${error.message}`);
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=webhook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/events/webhook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { FederationLink, CreateFederationOptions } from './types.js';
|
|
2
|
+
export { createFederationLink, acceptFederationLink, revokeFederationLink, listFederationLinks } from './link.js';
|
|
3
|
+
export { readFederatedMemories, type FederatedMemoryEntry } from './reader.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/federation/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAClH,OAAO,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/federation/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAClH,OAAO,EAAE,qBAAqB,EAA6B,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FederationLink, CreateFederationOptions } from './types.js';
|
|
2
|
+
/** Create a federation link (starts as 'pending'). */
|
|
3
|
+
export declare function createFederationLink(sourceTeamId: string, options: CreateFederationOptions): Promise<FederationLink>;
|
|
4
|
+
/** Accept a pending federation link (target team confirms). */
|
|
5
|
+
export declare function acceptFederationLink(linkId: string): Promise<FederationLink>;
|
|
6
|
+
/** Revoke a federation link. */
|
|
7
|
+
export declare function revokeFederationLink(linkId: string): Promise<void>;
|
|
8
|
+
/** List federation links for a team (as source or target). */
|
|
9
|
+
export declare function listFederationLinks(teamId: string): Promise<FederationLink[]>;
|
|
10
|
+
//# sourceMappingURL=link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../src/federation/link.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1E,sDAAsD;AACtD,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,cAAc,CAAC,CAiBzB;AAED,+DAA+D;AAC/D,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAYlF;AAED,gCAAgC;AAChC,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxE;AAED,8DAA8D;AAC9D,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAyBnF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Federation link management — create, accept, revoke links between teams.
|
|
3
|
+
*/
|
|
4
|
+
import { getSupabaseClient } from '../cloud/supabase-client.js';
|
|
5
|
+
/** Create a federation link (starts as 'pending'). */
|
|
6
|
+
export async function createFederationLink(sourceTeamId, options) {
|
|
7
|
+
const supabase = getSupabaseClient();
|
|
8
|
+
const { data, error } = await supabase
|
|
9
|
+
.from('team_federation_links')
|
|
10
|
+
.insert({
|
|
11
|
+
source_team_id: sourceTeamId,
|
|
12
|
+
target_team_id: options.target_team_id,
|
|
13
|
+
shared_topics: options.shared_topics ?? [],
|
|
14
|
+
shared_categories: options.shared_categories ?? [],
|
|
15
|
+
direction: options.direction ?? 'bidirectional',
|
|
16
|
+
status: 'pending',
|
|
17
|
+
})
|
|
18
|
+
.select()
|
|
19
|
+
.single();
|
|
20
|
+
if (error)
|
|
21
|
+
throw new Error(`Failed to create federation link: ${error.message}`);
|
|
22
|
+
return mapRow(data);
|
|
23
|
+
}
|
|
24
|
+
/** Accept a pending federation link (target team confirms). */
|
|
25
|
+
export async function acceptFederationLink(linkId) {
|
|
26
|
+
const supabase = getSupabaseClient();
|
|
27
|
+
const { data, error } = await supabase
|
|
28
|
+
.from('team_federation_links')
|
|
29
|
+
.update({ status: 'active', accepted_at: new Date().toISOString() })
|
|
30
|
+
.eq('id', linkId)
|
|
31
|
+
.eq('status', 'pending')
|
|
32
|
+
.select()
|
|
33
|
+
.single();
|
|
34
|
+
if (error)
|
|
35
|
+
throw new Error(`Failed to accept federation link: ${error.message}`);
|
|
36
|
+
return mapRow(data);
|
|
37
|
+
}
|
|
38
|
+
/** Revoke a federation link. */
|
|
39
|
+
export async function revokeFederationLink(linkId) {
|
|
40
|
+
const supabase = getSupabaseClient();
|
|
41
|
+
const { error } = await supabase
|
|
42
|
+
.from('team_federation_links')
|
|
43
|
+
.update({ status: 'revoked' })
|
|
44
|
+
.eq('id', linkId);
|
|
45
|
+
if (error)
|
|
46
|
+
throw new Error(`Failed to revoke federation link: ${error.message}`);
|
|
47
|
+
}
|
|
48
|
+
/** List federation links for a team (as source or target). */
|
|
49
|
+
export async function listFederationLinks(teamId) {
|
|
50
|
+
const supabase = getSupabaseClient();
|
|
51
|
+
// Links where this team is source
|
|
52
|
+
const { data: asSource } = await supabase
|
|
53
|
+
.from('team_federation_links')
|
|
54
|
+
.select('*')
|
|
55
|
+
.eq('source_team_id', teamId)
|
|
56
|
+
.neq('status', 'revoked');
|
|
57
|
+
// Links where this team is target
|
|
58
|
+
const { data: asTarget } = await supabase
|
|
59
|
+
.from('team_federation_links')
|
|
60
|
+
.select('*')
|
|
61
|
+
.eq('target_team_id', teamId)
|
|
62
|
+
.neq('status', 'revoked');
|
|
63
|
+
const all = [...(asSource ?? []), ...(asTarget ?? [])];
|
|
64
|
+
// Deduplicate by id
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
return all.filter(row => {
|
|
67
|
+
if (seen.has(row.id))
|
|
68
|
+
return false;
|
|
69
|
+
seen.add(row.id);
|
|
70
|
+
return true;
|
|
71
|
+
}).map(mapRow);
|
|
72
|
+
}
|
|
73
|
+
function mapRow(row) {
|
|
74
|
+
return {
|
|
75
|
+
id: row.id,
|
|
76
|
+
source_team_id: row.source_team_id,
|
|
77
|
+
target_team_id: row.target_team_id,
|
|
78
|
+
shared_topics: row.shared_topics ?? [],
|
|
79
|
+
shared_categories: row.shared_categories ?? [],
|
|
80
|
+
direction: row.direction,
|
|
81
|
+
status: row.status,
|
|
82
|
+
created_at: row.created_at,
|
|
83
|
+
accepted_at: row.accepted_at,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/federation/link.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGhE,sDAAsD;AACtD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,YAAoB,EACpB,OAAgC;IAEhC,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IACrC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ;SACnC,IAAI,CAAC,uBAAuB,CAAC;SAC7B,MAAM,CAAC;QACN,cAAc,EAAE,YAAY;QAC5B,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE;QAC1C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,EAAE;QAClD,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,eAAe;QAC/C,MAAM,EAAE,SAAS;KAClB,CAAC;SACD,MAAM,EAAE;SACR,MAAM,EAAE,CAAC;IAEZ,IAAI,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACjF,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAc;IACvD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IACrC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ;SACnC,IAAI,CAAC,uBAAuB,CAAC;SAC7B,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;SACnE,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC;SAChB,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;SACvB,MAAM,EAAE;SACR,MAAM,EAAE,CAAC;IAEZ,IAAI,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACjF,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC;AAED,gCAAgC;AAChC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAc;IACvD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IACrC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ;SAC7B,IAAI,CAAC,uBAAuB,CAAC;SAC7B,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;SAC7B,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAEpB,IAAI,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;AACnF,CAAC;AAED,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAc;IACtD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IAErC,kCAAkC;IAClC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ;SACtC,IAAI,CAAC,uBAAuB,CAAC;SAC7B,MAAM,CAAC,GAAG,CAAC;SACX,EAAE,CAAC,gBAAgB,EAAE,MAAM,CAAC;SAC5B,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE5B,kCAAkC;IAClC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ;SACtC,IAAI,CAAC,uBAAuB,CAAC;SAC7B,MAAM,CAAC,GAAG,CAAC;SACX,EAAE,CAAC,gBAAgB,EAAE,MAAM,CAAC;SAC5B,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE5B,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC;IACvD,oBAAoB;IACpB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;QACtB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QACnC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACjB,CAAC;AAED,SAAS,MAAM,CAAC,GAAQ;IACtB,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,cAAc,EAAE,GAAG,CAAC,cAAc;QAClC,cAAc,EAAE,GAAG,CAAC,cAAc;QAClC,aAAa,EAAE,GAAG,CAAC,aAAa,IAAI,EAAE;QACtC,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,IAAI,EAAE;QAC9C,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,WAAW,EAAE,GAAG,CAAC,WAAW;KAC7B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { MergedMemoryEntry } from '../memory/types.js';
|
|
2
|
+
/** A federated memory entry with source team info. */
|
|
3
|
+
export interface FederatedMemoryEntry extends MergedMemoryEntry {
|
|
4
|
+
source_team_id: string;
|
|
5
|
+
federated: true;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Read memories from all federated teams.
|
|
9
|
+
* Respects each link's topic/category filters.
|
|
10
|
+
*/
|
|
11
|
+
export declare function readFederatedMemories(teamId: string): Promise<FederatedMemoryEntry[]>;
|
|
12
|
+
//# sourceMappingURL=reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/federation/reader.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAkB,MAAM,oBAAoB,CAAC;AAE5E,sDAAsD;AACtD,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAqDjC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Federated memory reader — reads memories from linked teams
|
|
3
|
+
* filtered by the federation link's shared topics/categories.
|
|
4
|
+
*/
|
|
5
|
+
import { cloudReadAllMemories } from '../cloud/supabase-client.js';
|
|
6
|
+
import { mergeMemories } from '../memory/merge-view.js';
|
|
7
|
+
import { inferCategory } from '../memory/write-utils.js';
|
|
8
|
+
import { listFederationLinks } from './link.js';
|
|
9
|
+
/**
|
|
10
|
+
* Read memories from all federated teams.
|
|
11
|
+
* Respects each link's topic/category filters.
|
|
12
|
+
*/
|
|
13
|
+
export async function readFederatedMemories(teamId) {
|
|
14
|
+
const links = await listFederationLinks(teamId);
|
|
15
|
+
const activeLinks = links.filter(l => l.status === 'active');
|
|
16
|
+
if (activeLinks.length === 0)
|
|
17
|
+
return [];
|
|
18
|
+
const results = [];
|
|
19
|
+
for (const link of activeLinks) {
|
|
20
|
+
// Determine which team to read from
|
|
21
|
+
const remoteTeamId = link.source_team_id === teamId
|
|
22
|
+
? link.target_team_id
|
|
23
|
+
: link.source_team_id;
|
|
24
|
+
// For one_way links, only source can read target's data
|
|
25
|
+
if (link.direction === 'one_way' && link.target_team_id === teamId) {
|
|
26
|
+
continue; // Target can't read source in one_way
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const memories = await cloudReadAllMemories(remoteTeamId);
|
|
30
|
+
const entries = mergeMemories(memories, { limit: 999 });
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
// Skip private entries
|
|
33
|
+
if (entry.scope === 'private')
|
|
34
|
+
continue;
|
|
35
|
+
// Topic filter
|
|
36
|
+
if (link.shared_topics.length > 0 && !link.shared_topics.includes('*')) {
|
|
37
|
+
const matches = link.shared_topics.some(t => t.toLowerCase() === entry.topic.toLowerCase());
|
|
38
|
+
if (!matches)
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
// Category filter
|
|
42
|
+
if (link.shared_categories.length > 0) {
|
|
43
|
+
const cat = entry.category ?? inferCategory(entry.tags, entry.topic);
|
|
44
|
+
if (!link.shared_categories.includes(cat))
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
results.push({
|
|
48
|
+
...entry,
|
|
49
|
+
source_team_id: remoteTeamId,
|
|
50
|
+
federated: true,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Best-effort — skip unreachable federated teams
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return results;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/federation/reader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAUhD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAc;IAEd,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;IAE7D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAExC,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,oCAAoC;QACpC,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,KAAK,MAAM;YACjD,CAAC,CAAC,IAAI,CAAC,cAAc;YACrB,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;QAExB,wDAAwD;QACxD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;YACnE,SAAS,CAAC,sCAAsC;QAClD,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,YAAY,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YAExD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,uBAAuB;gBACvB,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;oBAAE,SAAS;gBAExC,eAAe;gBACf,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBACvE,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CACrC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,CACnD,CAAC;oBACF,IAAI,CAAC,OAAO;wBAAE,SAAS;gBACzB,CAAC;gBAED,kBAAkB;gBAClB,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtC,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;oBACrE,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,GAAqB,CAAC;wBAAE,SAAS;gBACxE,CAAC;gBAED,OAAO,CAAC,IAAI,CAAC;oBACX,GAAG,KAAK;oBACR,cAAc,EAAE,YAAY;oBAC5B,SAAS,EAAE,IAAI;iBAChB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,iDAAiD;QACnD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-team federation types.
|
|
3
|
+
*/
|
|
4
|
+
import type { MemoryCategory } from '../memory/types.js';
|
|
5
|
+
/** A federation link between two teams. */
|
|
6
|
+
export interface FederationLink {
|
|
7
|
+
id?: string;
|
|
8
|
+
source_team_id: string;
|
|
9
|
+
target_team_id: string;
|
|
10
|
+
/** Topics to share. Empty array or ['*'] means all topics. */
|
|
11
|
+
shared_topics: string[];
|
|
12
|
+
/** Categories to share. Empty means all. */
|
|
13
|
+
shared_categories: MemoryCategory[];
|
|
14
|
+
direction: 'one_way' | 'bidirectional';
|
|
15
|
+
status: 'pending' | 'active' | 'revoked';
|
|
16
|
+
created_at?: string;
|
|
17
|
+
accepted_at?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Options for creating a federation link. */
|
|
20
|
+
export interface CreateFederationOptions {
|
|
21
|
+
target_team_id: string;
|
|
22
|
+
shared_topics?: string[];
|
|
23
|
+
shared_categories?: MemoryCategory[];
|
|
24
|
+
direction?: 'one_way' | 'bidirectional';
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/federation/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,2CAA2C;AAC3C,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,4CAA4C;IAC5C,iBAAiB,EAAE,cAAc,EAAE,CAAC;IACpC,SAAS,EAAE,SAAS,GAAG,eAAe,CAAC;IACvC,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,8CAA8C;AAC9C,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,iBAAiB,CAAC,EAAE,cAAc,EAAE,CAAC;IACrC,SAAS,CAAC,EAAE,SAAS,GAAG,eAAe,CAAC;CACzC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/federation/types.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export * from './memory/index.js';
|
|
2
2
|
export * from './conversation/index.js';
|
|
3
3
|
export * from './cloud/index.js';
|
|
4
|
+
export * from './events/index.js';
|
|
5
|
+
export * from './templates/index.js';
|
|
6
|
+
export * from './federation/index.js';
|
|
4
7
|
export { AgentMeshClient } from './sdk.js';
|
|
5
8
|
export type { AgentMeshClientOptions, ReadMemoryOpts, WriteMemoryOpts, SearchMemoryOpts, WaitForRepliesOpts } from './sdk.js';
|
|
6
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,YAAY,EAAE,sBAAsB,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,YAAY,EAAE,sBAAsB,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export * from './memory/index.js';
|
|
2
2
|
export * from './conversation/index.js';
|
|
3
3
|
export * from './cloud/index.js';
|
|
4
|
+
export * from './events/index.js';
|
|
5
|
+
export * from './templates/index.js';
|
|
6
|
+
export * from './federation/index.js';
|
|
4
7
|
export { AgentMeshClient } from './sdk.js';
|
|
5
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-tools.d.ts","sourceRoot":"","sources":["../../src/mcp/conversation-tools.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAIzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,gEAAgE;AAChE,KAAK,qBAAqB,GAAG,kBAAkB,GAAG,uBAAuB,CAAC;AAc1E,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,SAAS,EACjB,cAAc,EAAE,MAAM,MAAM,EAC5B,UAAU,EAAE,MAAM,MAAM,EACxB,kBAAkB,EAAE,MAAM,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,EAC/D,SAAS,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"conversation-tools.d.ts","sourceRoot":"","sources":["../../src/mcp/conversation-tools.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAIzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,gEAAgE;AAChE,KAAK,qBAAqB,GAAG,kBAAkB,GAAG,uBAAuB,CAAC;AAc1E,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,SAAS,EACjB,cAAc,EAAE,MAAM,MAAM,EAC5B,UAAU,EAAE,MAAM,MAAM,EACxB,kBAAkB,EAAE,MAAM,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,EAC/D,SAAS,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,QAklBrC"}
|
|
@@ -116,7 +116,7 @@ If no conversation space is running, tells you so.`, {}, async () => {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
else {
|
|
119
|
-
lines.push('No active
|
|
119
|
+
lines.push('No active discussions. Start one by telling your human\'s AI: "discuss [topic] with the team".');
|
|
120
120
|
}
|
|
121
121
|
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
122
122
|
});
|
|
@@ -145,7 +145,7 @@ Your message will be seen by all connected agents.`, {
|
|
|
145
145
|
const recent = client.getTopicMessages(topic).slice(-10);
|
|
146
146
|
if (recent.length === 0) {
|
|
147
147
|
return {
|
|
148
|
-
content: [{ type: 'text', text: `Message sent to
|
|
148
|
+
content: [{ type: 'text', text: `Message sent to "${topic}". No replies yet — other agents will see it when their AI reads memory.` }]
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
151
|
const lines = [`Messages on "${topic}":\n`];
|
|
@@ -171,7 +171,7 @@ Use this to check if other agents have replied to your earlier message.`, {
|
|
|
171
171
|
}
|
|
172
172
|
if (messages.length === 0) {
|
|
173
173
|
return {
|
|
174
|
-
content: [{ type: 'text', text: `No messages on "${topic}"${since ? ' since ' + since : ''}.` }]
|
|
174
|
+
content: [{ type: 'text', text: `No messages on "${topic}"${since ? ' since ' + since : ''} yet. Send one with send_message, or start a full discussion with discuss.` }]
|
|
175
175
|
};
|
|
176
176
|
}
|
|
177
177
|
const lines = [`Messages on "${topic}" (${messages.length}):\n`];
|
|
@@ -247,7 +247,7 @@ If no other agents are online, you can discuss asynchronously through shared mem
|
|
|
247
247
|
return {
|
|
248
248
|
content: [{
|
|
249
249
|
type: 'text',
|
|
250
|
-
text: `
|
|
250
|
+
text: `No replies within ${wait_seconds ?? 60}s. Your message is saved in cloud.\nWhen other agents come online, they'll see your discussion request.\nYou can also ask their human to tell their AI: "go join the ${topic} discussion".`
|
|
251
251
|
}]
|
|
252
252
|
};
|
|
253
253
|
}
|
|
@@ -457,6 +457,7 @@ Flow:
|
|
|
457
457
|
lines.push(` Recommended: ${d.recommendation}`);
|
|
458
458
|
lines.push('');
|
|
459
459
|
}
|
|
460
|
+
lines.push('Ask your human which option they prefer, then call vote_on_decision with their choice.');
|
|
460
461
|
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
461
462
|
});
|
|
462
463
|
server.tool('vote_on_decision', `Vote on a pending team decision that was proposed by another agent.
|
|
@@ -710,7 +711,7 @@ async function restFallbackDiscuss(teamId, myId, getDir, topic, message, waitMs,
|
|
|
710
711
|
return {
|
|
711
712
|
content: [{
|
|
712
713
|
type: 'text',
|
|
713
|
-
text: `[REST mode]
|
|
714
|
+
text: `[REST mode] No replies within ${Math.round(waitMs / 1000)}s. Your message is saved in cloud.\nWhen other agents come online, they'll see your discussion request.\nAsk their human to tell their AI: "go join the ${topic} discussion".`
|
|
714
715
|
}]
|
|
715
716
|
};
|
|
716
717
|
}
|