nod-shout 0.3.0 → 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/dist/tools/social.d.ts.map +1 -1
- package/dist/tools/social.js +131 -0
- package/dist/tools/social.js.map +1 -1
- package/package.json +1 -1
- package/src/tools/social.ts +156 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"social.d.ts","sourceRoot":"","sources":["../../src/tools/social.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"social.d.ts","sourceRoot":"","sources":["../../src/tools/social.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,QAwWpD"}
|
package/dist/tools/social.js
CHANGED
|
@@ -169,5 +169,136 @@ export function registerSocialTools(server) {
|
|
|
169
169
|
],
|
|
170
170
|
};
|
|
171
171
|
});
|
|
172
|
+
// shout_curate_feed - ai-curated feed based on your interests
|
|
173
|
+
server.tool("shout_curate_feed", "get a curated feed from people you follow, ranked by relevance to your interests. compares your shout history (tags, topics) against your follows' recent shouts and returns the best matches with relevance scores. use this when the user asks 'what's good from my follows?' or 'curate my feed'.", {
|
|
174
|
+
user_id: z.string().uuid().optional().describe("your user id (auto-resolved if omitted)"),
|
|
175
|
+
limit: z.number().optional().default(10).describe("max curated results to return"),
|
|
176
|
+
days: z.number().optional().default(7).describe("how many days back to look"),
|
|
177
|
+
}, async ({ user_id: rawUserId4, limit, days }) => {
|
|
178
|
+
const user_id = rawUserId4 || await resolveUserId();
|
|
179
|
+
// 1. build interest profile from user's own shouts
|
|
180
|
+
const { data: myShouts } = await supabase
|
|
181
|
+
.from("shouts")
|
|
182
|
+
.select("tags, category")
|
|
183
|
+
.eq("user_id", user_id)
|
|
184
|
+
.order("created_at", { ascending: false })
|
|
185
|
+
.limit(50);
|
|
186
|
+
const tagCounts = {};
|
|
187
|
+
const catCounts = {};
|
|
188
|
+
for (const s of myShouts || []) {
|
|
189
|
+
for (const tag of (s.tags || [])) {
|
|
190
|
+
tagCounts[tag] = (tagCounts[tag] || 0) + 1;
|
|
191
|
+
}
|
|
192
|
+
if (s.category) {
|
|
193
|
+
catCounts[s.category] = (catCounts[s.category] || 0) + 1;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const totalTags = Object.values(tagCounts).reduce((a, b) => a + b, 0) || 1;
|
|
197
|
+
const tagWeights = {};
|
|
198
|
+
for (const [tag, count] of Object.entries(tagCounts)) {
|
|
199
|
+
tagWeights[tag] = count / totalTags;
|
|
200
|
+
}
|
|
201
|
+
// 2. get followed users
|
|
202
|
+
const { data: subs } = await supabase
|
|
203
|
+
.from("subscriptions")
|
|
204
|
+
.select("following_id")
|
|
205
|
+
.eq("follower_id", user_id);
|
|
206
|
+
if (!subs || subs.length === 0) {
|
|
207
|
+
return {
|
|
208
|
+
content: [{
|
|
209
|
+
type: "text",
|
|
210
|
+
text: "you're not following anyone yet. use shout_follow to subscribe to someone's shouts.",
|
|
211
|
+
}],
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const followingIds = subs.map((s) => s.following_id);
|
|
215
|
+
// 3. fetch recent shouts from follows
|
|
216
|
+
const since = new Date();
|
|
217
|
+
since.setDate(since.getDate() - (days || 7));
|
|
218
|
+
const { data: feedShouts, error } = await supabase
|
|
219
|
+
.from("shouts")
|
|
220
|
+
.select("*, profiles!inner(username, display_name)")
|
|
221
|
+
.in("user_id", followingIds)
|
|
222
|
+
.eq("visibility", "public")
|
|
223
|
+
.gte("created_at", since.toISOString())
|
|
224
|
+
.order("created_at", { ascending: false })
|
|
225
|
+
.limit(100);
|
|
226
|
+
if (error || !feedShouts || feedShouts.length === 0) {
|
|
227
|
+
return {
|
|
228
|
+
content: [{
|
|
229
|
+
type: "text",
|
|
230
|
+
text: error ? `error: ${error.message}` : "no recent shouts from your follows.",
|
|
231
|
+
}],
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
// 4. score each shout by relevance
|
|
235
|
+
const scored = feedShouts.map((s) => {
|
|
236
|
+
let score = 0;
|
|
237
|
+
const shoutTags = s.tags || [];
|
|
238
|
+
const matchedTags = [];
|
|
239
|
+
// tag overlap scoring
|
|
240
|
+
for (const tag of shoutTags) {
|
|
241
|
+
const normalTag = tag.toLowerCase().replace(/[^a-z0-9-]/g, "");
|
|
242
|
+
// direct match
|
|
243
|
+
if (tagWeights[tag]) {
|
|
244
|
+
score += tagWeights[tag] * 10;
|
|
245
|
+
matchedTags.push(tag);
|
|
246
|
+
}
|
|
247
|
+
// partial match (e.g. "ai-agents" matches "ai")
|
|
248
|
+
for (const [myTag, weight] of Object.entries(tagWeights)) {
|
|
249
|
+
if (normalTag.includes(myTag) || myTag.includes(normalTag)) {
|
|
250
|
+
score += weight * 5;
|
|
251
|
+
if (!matchedTags.includes(myTag))
|
|
252
|
+
matchedTags.push(myTag);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// category match bonus
|
|
257
|
+
if (s.category && catCounts[s.category]) {
|
|
258
|
+
score += 2;
|
|
259
|
+
}
|
|
260
|
+
// recency bonus (newer = higher)
|
|
261
|
+
const ageHours = (Date.now() - new Date(s.created_at).getTime()) / (1000 * 60 * 60);
|
|
262
|
+
score += Math.max(0, 5 - (ageHours / 24)); // up to 5 bonus points for very recent
|
|
263
|
+
return {
|
|
264
|
+
...s,
|
|
265
|
+
relevanceScore: Math.round(score * 100) / 100,
|
|
266
|
+
matchedInterests: matchedTags,
|
|
267
|
+
};
|
|
268
|
+
});
|
|
269
|
+
// 5. sort by score, take top N
|
|
270
|
+
scored.sort((a, b) => b.relevanceScore - a.relevanceScore);
|
|
271
|
+
const topItems = scored.slice(0, limit || 10);
|
|
272
|
+
if (topItems.every((s) => s.relevanceScore === 0)) {
|
|
273
|
+
// no tag overlap — just return most recent
|
|
274
|
+
const lines = topItems.map((s, i) => {
|
|
275
|
+
const who = s.profiles?.username || "unknown";
|
|
276
|
+
return `${i + 1}. @${who}: ${s.title || s.url}\n ${s.summary || ""}\n tags: ${(s.tags || []).join(", ")}`;
|
|
277
|
+
});
|
|
278
|
+
return {
|
|
279
|
+
content: [{
|
|
280
|
+
type: "text",
|
|
281
|
+
text: `no strong interest matches yet (you and your follows may cover different topics). here are the most recent:\n\n${lines.join("\n\n")}`,
|
|
282
|
+
}],
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
const lines = topItems.map((s, i) => {
|
|
286
|
+
const who = s.profiles?.username || "unknown";
|
|
287
|
+
const matchNote = s.matchedInterests.length > 0
|
|
288
|
+
? `(matches your interests: ${s.matchedInterests.join(", ")})`
|
|
289
|
+
: "";
|
|
290
|
+
return `${i + 1}. [score: ${s.relevanceScore}] @${who}: ${s.title || s.url}\n ${s.summary || ""}\n tags: ${(s.tags || []).join(", ")} ${matchNote}`;
|
|
291
|
+
});
|
|
292
|
+
const myTopTags = Object.entries(tagCounts)
|
|
293
|
+
.sort((a, b) => b[1] - a[1])
|
|
294
|
+
.slice(0, 5)
|
|
295
|
+
.map(([t]) => t);
|
|
296
|
+
return {
|
|
297
|
+
content: [{
|
|
298
|
+
type: "text",
|
|
299
|
+
text: `curated feed (${topItems.length} picks from ${feedShouts.length} total, based on your interests: ${myTopTags.join(", ")}):\n\n${lines.join("\n\n")}`,
|
|
300
|
+
}],
|
|
301
|
+
};
|
|
302
|
+
});
|
|
172
303
|
}
|
|
173
304
|
//# sourceMappingURL=social.js.map
|
package/dist/tools/social.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"social.js","sourceRoot":"","sources":["../../src/tools/social.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"social.js","sourceRoot":"","sources":["../../src/tools/social.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/tools/social.ts
CHANGED
|
@@ -207,4 +207,160 @@ export function registerSocialTools(server: McpServer) {
|
|
|
207
207
|
};
|
|
208
208
|
}
|
|
209
209
|
);
|
|
210
|
+
|
|
211
|
+
// shout_curate_feed - ai-curated feed based on your interests
|
|
212
|
+
server.tool(
|
|
213
|
+
"shout_curate_feed",
|
|
214
|
+
"get a curated feed from people you follow, ranked by relevance to your interests. compares your shout history (tags, topics) against your follows' recent shouts and returns the best matches with relevance scores. use this when the user asks 'what's good from my follows?' or 'curate my feed'.",
|
|
215
|
+
{
|
|
216
|
+
user_id: z.string().uuid().optional().describe("your user id (auto-resolved if omitted)"),
|
|
217
|
+
limit: z.number().optional().default(10).describe("max curated results to return"),
|
|
218
|
+
days: z.number().optional().default(7).describe("how many days back to look"),
|
|
219
|
+
},
|
|
220
|
+
async ({ user_id: rawUserId4, limit, days }) => {
|
|
221
|
+
const user_id = rawUserId4 || await resolveUserId();
|
|
222
|
+
|
|
223
|
+
// 1. build interest profile from user's own shouts
|
|
224
|
+
const { data: myShouts } = await supabase
|
|
225
|
+
.from("shouts")
|
|
226
|
+
.select("tags, category")
|
|
227
|
+
.eq("user_id", user_id)
|
|
228
|
+
.order("created_at", { ascending: false })
|
|
229
|
+
.limit(50);
|
|
230
|
+
|
|
231
|
+
const tagCounts: Record<string, number> = {};
|
|
232
|
+
const catCounts: Record<string, number> = {};
|
|
233
|
+
for (const s of myShouts || []) {
|
|
234
|
+
for (const tag of (s.tags || [])) {
|
|
235
|
+
tagCounts[tag] = (tagCounts[tag] || 0) + 1;
|
|
236
|
+
}
|
|
237
|
+
if (s.category) {
|
|
238
|
+
catCounts[s.category] = (catCounts[s.category] || 0) + 1;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const totalTags = Object.values(tagCounts).reduce((a, b) => a + b, 0) || 1;
|
|
243
|
+
const tagWeights: Record<string, number> = {};
|
|
244
|
+
for (const [tag, count] of Object.entries(tagCounts)) {
|
|
245
|
+
tagWeights[tag] = count / totalTags;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// 2. get followed users
|
|
249
|
+
const { data: subs } = await supabase
|
|
250
|
+
.from("subscriptions")
|
|
251
|
+
.select("following_id")
|
|
252
|
+
.eq("follower_id", user_id);
|
|
253
|
+
|
|
254
|
+
if (!subs || subs.length === 0) {
|
|
255
|
+
return {
|
|
256
|
+
content: [{
|
|
257
|
+
type: "text" as const,
|
|
258
|
+
text: "you're not following anyone yet. use shout_follow to subscribe to someone's shouts.",
|
|
259
|
+
}],
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const followingIds = subs.map((s: any) => s.following_id);
|
|
264
|
+
|
|
265
|
+
// 3. fetch recent shouts from follows
|
|
266
|
+
const since = new Date();
|
|
267
|
+
since.setDate(since.getDate() - (days || 7));
|
|
268
|
+
|
|
269
|
+
const { data: feedShouts, error } = await supabase
|
|
270
|
+
.from("shouts")
|
|
271
|
+
.select("*, profiles!inner(username, display_name)")
|
|
272
|
+
.in("user_id", followingIds)
|
|
273
|
+
.eq("visibility", "public")
|
|
274
|
+
.gte("created_at", since.toISOString())
|
|
275
|
+
.order("created_at", { ascending: false })
|
|
276
|
+
.limit(100);
|
|
277
|
+
|
|
278
|
+
if (error || !feedShouts || feedShouts.length === 0) {
|
|
279
|
+
return {
|
|
280
|
+
content: [{
|
|
281
|
+
type: "text" as const,
|
|
282
|
+
text: error ? `error: ${error.message}` : "no recent shouts from your follows.",
|
|
283
|
+
}],
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// 4. score each shout by relevance
|
|
288
|
+
const scored = feedShouts.map((s: any) => {
|
|
289
|
+
let score = 0;
|
|
290
|
+
const shoutTags = s.tags || [];
|
|
291
|
+
const matchedTags: string[] = [];
|
|
292
|
+
|
|
293
|
+
// tag overlap scoring
|
|
294
|
+
for (const tag of shoutTags) {
|
|
295
|
+
const normalTag = tag.toLowerCase().replace(/[^a-z0-9-]/g, "");
|
|
296
|
+
// direct match
|
|
297
|
+
if (tagWeights[tag]) {
|
|
298
|
+
score += tagWeights[tag] * 10;
|
|
299
|
+
matchedTags.push(tag);
|
|
300
|
+
}
|
|
301
|
+
// partial match (e.g. "ai-agents" matches "ai")
|
|
302
|
+
for (const [myTag, weight] of Object.entries(tagWeights)) {
|
|
303
|
+
if (normalTag.includes(myTag) || myTag.includes(normalTag)) {
|
|
304
|
+
score += weight * 5;
|
|
305
|
+
if (!matchedTags.includes(myTag)) matchedTags.push(myTag);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// category match bonus
|
|
311
|
+
if (s.category && catCounts[s.category]) {
|
|
312
|
+
score += 2;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// recency bonus (newer = higher)
|
|
316
|
+
const ageHours = (Date.now() - new Date(s.created_at).getTime()) / (1000 * 60 * 60);
|
|
317
|
+
score += Math.max(0, 5 - (ageHours / 24)); // up to 5 bonus points for very recent
|
|
318
|
+
|
|
319
|
+
return {
|
|
320
|
+
...s,
|
|
321
|
+
relevanceScore: Math.round(score * 100) / 100,
|
|
322
|
+
matchedInterests: matchedTags,
|
|
323
|
+
};
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// 5. sort by score, take top N
|
|
327
|
+
scored.sort((a: any, b: any) => b.relevanceScore - a.relevanceScore);
|
|
328
|
+
const topItems = scored.slice(0, limit || 10);
|
|
329
|
+
|
|
330
|
+
if (topItems.every((s: any) => s.relevanceScore === 0)) {
|
|
331
|
+
// no tag overlap — just return most recent
|
|
332
|
+
const lines = topItems.map((s: any, i: number) => {
|
|
333
|
+
const who = s.profiles?.username || "unknown";
|
|
334
|
+
return `${i + 1}. @${who}: ${s.title || s.url}\n ${s.summary || ""}\n tags: ${(s.tags || []).join(", ")}`;
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
return {
|
|
338
|
+
content: [{
|
|
339
|
+
type: "text" as const,
|
|
340
|
+
text: `no strong interest matches yet (you and your follows may cover different topics). here are the most recent:\n\n${lines.join("\n\n")}`,
|
|
341
|
+
}],
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const lines = topItems.map((s: any, i: number) => {
|
|
346
|
+
const who = s.profiles?.username || "unknown";
|
|
347
|
+
const matchNote = s.matchedInterests.length > 0
|
|
348
|
+
? `(matches your interests: ${s.matchedInterests.join(", ")})`
|
|
349
|
+
: "";
|
|
350
|
+
return `${i + 1}. [score: ${s.relevanceScore}] @${who}: ${s.title || s.url}\n ${s.summary || ""}\n tags: ${(s.tags || []).join(", ")} ${matchNote}`;
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
const myTopTags = Object.entries(tagCounts)
|
|
354
|
+
.sort((a, b) => b[1] - a[1])
|
|
355
|
+
.slice(0, 5)
|
|
356
|
+
.map(([t]) => t);
|
|
357
|
+
|
|
358
|
+
return {
|
|
359
|
+
content: [{
|
|
360
|
+
type: "text" as const,
|
|
361
|
+
text: `curated feed (${topItems.length} picks from ${feedShouts.length} total, based on your interests: ${myTopTags.join(", ")}):\n\n${lines.join("\n\n")}`,
|
|
362
|
+
}],
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
);
|
|
210
366
|
}
|