antenna-openclaw-plugin 1.1.0 โ 1.2.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/index.ts +102 -3
- package/package.json +1 -1
- package/skills/antenna/SKILL.md +25 -1
package/index.ts
CHANGED
|
@@ -288,7 +288,7 @@ export default function register(api: any) {
|
|
|
288
288
|
return { ref, emoji: p.emoji || "๐ค", name: p.display_name || "ๅฟๅ", line1: p.line1, line2: p.line2, line3: p.line3 };
|
|
289
289
|
});
|
|
290
290
|
(api as any)._antennaRefMap = gRefMap;
|
|
291
|
-
try { await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs:
|
|
291
|
+
try { await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs: gRefMap }); } catch {}
|
|
292
292
|
for (const p of globalOthers) {
|
|
293
293
|
try { await supabase.rpc("log_recommendation", { p_device_id: deviceId, p_recommended_id: p.device_id }); } catch {}
|
|
294
294
|
}
|
|
@@ -318,7 +318,7 @@ export default function register(api: any) {
|
|
|
318
318
|
// Store ref map for accept โ memory + DB
|
|
319
319
|
(api as any)._antennaRefMap = _refMap;
|
|
320
320
|
try {
|
|
321
|
-
await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs:
|
|
321
|
+
await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs: _refMap });
|
|
322
322
|
} catch { /* best effort */ }
|
|
323
323
|
|
|
324
324
|
return ok({
|
|
@@ -614,7 +614,7 @@ export default function register(api: any) {
|
|
|
614
614
|
// Persist refs + log recommendation
|
|
615
615
|
(api as any)._antennaRefMap = { ...(api as any)._antennaRefMap, ..._refMap };
|
|
616
616
|
try {
|
|
617
|
-
await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs:
|
|
617
|
+
await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs: _refMap });
|
|
618
618
|
} catch { /* best effort */ }
|
|
619
619
|
for (const p of results) {
|
|
620
620
|
await supabase.rpc("log_recommendation", { p_device_id: deviceId, p_recommended_id: p.device_id });
|
|
@@ -627,6 +627,105 @@ export default function register(api: any) {
|
|
|
627
627
|
},
|
|
628
628
|
});
|
|
629
629
|
|
|
630
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
631
|
+
// Tool: antenna_event_create
|
|
632
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
633
|
+
api.registerTool({
|
|
634
|
+
name: "antenna_event_create",
|
|
635
|
+
description: "Create an event. Returns a shareable link (antenna.fyi/e/CODE) for participants to join.",
|
|
636
|
+
parameters: {
|
|
637
|
+
type: "object",
|
|
638
|
+
properties: {
|
|
639
|
+
name: { type: "string", description: "Event name" },
|
|
640
|
+
sender_id: { type: "string" },
|
|
641
|
+
channel: { type: "string" },
|
|
642
|
+
lat: { type: "number", description: "Event latitude" },
|
|
643
|
+
lng: { type: "number", description: "Event longitude" },
|
|
644
|
+
starts_at: { type: "string", description: "Start time ISO" },
|
|
645
|
+
ends_at: { type: "string", description: "End time ISO" },
|
|
646
|
+
},
|
|
647
|
+
required: ["name", "sender_id", "channel"],
|
|
648
|
+
},
|
|
649
|
+
async execute(_id: string, params: any) {
|
|
650
|
+
const cfg = getConfig(api);
|
|
651
|
+
const supabase = getSupabase(cfg);
|
|
652
|
+
const deviceId = deriveDeviceId(params.sender_id, params.channel);
|
|
653
|
+
const { data, error } = await supabase.rpc("create_event", {
|
|
654
|
+
p_name: params.name,
|
|
655
|
+
p_lat: params.lat || null,
|
|
656
|
+
p_lng: params.lng || null,
|
|
657
|
+
p_created_by: deviceId,
|
|
658
|
+
p_starts_at: params.starts_at || new Date().toISOString(),
|
|
659
|
+
p_ends_at: params.ends_at || new Date(Date.now() + 12*60*60*1000).toISOString(),
|
|
660
|
+
});
|
|
661
|
+
if (error) return ok({ error: error.message });
|
|
662
|
+
return ok(data);
|
|
663
|
+
},
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
667
|
+
// Tool: antenna_event_join
|
|
668
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
669
|
+
api.registerTool({
|
|
670
|
+
name: "antenna_event_join",
|
|
671
|
+
description: "Join an event by its code from the event URL.",
|
|
672
|
+
parameters: {
|
|
673
|
+
type: "object",
|
|
674
|
+
properties: {
|
|
675
|
+
code: { type: "string", description: "Event code" },
|
|
676
|
+
sender_id: { type: "string" },
|
|
677
|
+
channel: { type: "string" },
|
|
678
|
+
},
|
|
679
|
+
required: ["code", "sender_id", "channel"],
|
|
680
|
+
},
|
|
681
|
+
async execute(_id: string, params: any) {
|
|
682
|
+
const cfg = getConfig(api);
|
|
683
|
+
const supabase = getSupabase(cfg);
|
|
684
|
+
const deviceId = deriveDeviceId(params.sender_id, params.channel);
|
|
685
|
+
const { data, error } = await supabase.rpc("join_event", { p_code: params.code, p_device_id: deviceId });
|
|
686
|
+
if (error) return ok({ error: error.message });
|
|
687
|
+
return ok(data);
|
|
688
|
+
},
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
692
|
+
// Tool: antenna_event_scan
|
|
693
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
694
|
+
api.registerTool({
|
|
695
|
+
name: "antenna_event_scan",
|
|
696
|
+
description: "Scan people in an event. No distance limit.",
|
|
697
|
+
parameters: {
|
|
698
|
+
type: "object",
|
|
699
|
+
properties: {
|
|
700
|
+
code: { type: "string", description: "Event code" },
|
|
701
|
+
sender_id: { type: "string" },
|
|
702
|
+
channel: { type: "string" },
|
|
703
|
+
},
|
|
704
|
+
required: ["code", "sender_id", "channel"],
|
|
705
|
+
},
|
|
706
|
+
async execute(_id: string, params: any) {
|
|
707
|
+
const cfg = getConfig(api);
|
|
708
|
+
const supabase = getSupabase(cfg);
|
|
709
|
+
const deviceId = deriveDeviceId(params.sender_id, params.channel);
|
|
710
|
+
|
|
711
|
+
const { data, error } = await supabase.rpc("event_participants_list", { p_code: params.code, p_device_id: deviceId });
|
|
712
|
+
if (error) return ok({ error: error.message });
|
|
713
|
+
|
|
714
|
+
const others = (data || []) as any[];
|
|
715
|
+
const _refMap: Record<string, string> = {};
|
|
716
|
+
const profiles = others.map((p, i) => {
|
|
717
|
+
const ref = String(i + 1);
|
|
718
|
+
_refMap[ref] = p.device_id;
|
|
719
|
+
return { ref, emoji: p.emoji || "๐ค", name: p.display_name || "ๅฟๅ", line1: p.line1, line2: p.line2, line3: p.line3, source: "event" };
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
(api as any)._antennaRefMap = { ...(api as any)._antennaRefMap, ..._refMap };
|
|
723
|
+
try { await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs: _refMap }); } catch {}
|
|
724
|
+
|
|
725
|
+
return ok({ count: profiles.length, profiles, event: true });
|
|
726
|
+
},
|
|
727
|
+
});
|
|
728
|
+
|
|
630
729
|
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
631
730
|
// Tool: antenna_pass
|
|
632
731
|
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
package/package.json
CHANGED
package/skills/antenna/SKILL.md
CHANGED
|
@@ -83,7 +83,7 @@ After receiving the nearby profiles, **you decide** who to recommend:
|
|
|
83
83
|
View or update the user's name card.
|
|
84
84
|
- `action`: "get" or "set"
|
|
85
85
|
- `sender_id`, `channel`: from context
|
|
86
|
-
- For "set": `display_name`, `emoji`, `line1`, `line2`, `line3`, `visible`
|
|
86
|
+
- For "set": `display_name`, `emoji`, `line1`, `line2`, `line3`, `visible`, `matching_context`
|
|
87
87
|
|
|
88
88
|
The name card has:
|
|
89
89
|
- **emoji**: a single emoji that represents them
|
|
@@ -91,6 +91,12 @@ The name card has:
|
|
|
91
91
|
- **line1**: who they are / what they do
|
|
92
92
|
- **line2**: what they're into
|
|
93
93
|
- **line3**: what they're looking for right now
|
|
94
|
+
- **matching_context** (optional, not shown to others): A richer description generated by the agent based on what it knows about the user โ career background, tech stack, interests, projects, personality traits. ~200 words. Only used for embedding-based matching, never displayed to other users.
|
|
95
|
+
|
|
96
|
+
**After saving the profile, generate `matching_context` automatically** based on your knowledge of the user (memory, conversations, context). Don't ask the user to write it โ you write it. Example:
|
|
97
|
+
> "Product designer at a tech company in Beijing, focusing on AI search experience. Interested in music (Sakamoto), swimming, cooking, language learning. Recently exploring AI agent ecosystems and social discovery. Looking to connect with AI builders, indie hackers, and creative technologists."
|
|
98
|
+
- **line2**: what they're into
|
|
99
|
+
- **line3**: what they're looking for right now
|
|
94
100
|
|
|
95
101
|
### `antenna_accept`
|
|
96
102
|
Accept a match after the user sees results. Can optionally include contact info to share.
|
|
@@ -251,3 +257,21 @@ Plugin ่ชๅธฆๅๅฐๆๅก๏ผๆฏ 10 ๅ้่ฝฎ่ฏขไธๆฌก Supabase ๆฅๆฐ็ mutual
|
|
|
251
257
|
3. ๅฆๆๅฏนๆนๅไบซไบ่็ณปๆนๅผ๏ผไธๅนถๅฑ็คบ
|
|
252
258
|
|
|
253
259
|
็จๆทไธ้่ฆไธปๅจ้ฎ๏ผagent ไผ่ชๅจๆถๅฐ้็ฅใ
|
|
260
|
+
|
|
261
|
+
### `antenna_event_create`
|
|
262
|
+
Create an event. Returns a shareable link (antenna.fyi/e/CODE).
|
|
263
|
+
- `name`: event name
|
|
264
|
+
- `sender_id`, `channel`: from context
|
|
265
|
+
- `lat`, `lng`: optional event location
|
|
266
|
+
- `starts_at`, `ends_at`: optional time range (default: now to +12h)
|
|
267
|
+
|
|
268
|
+
### `antenna_event_join`
|
|
269
|
+
Join an event by code.
|
|
270
|
+
- `code`: from the event URL (antenna.fyi/e/CODE)
|
|
271
|
+
- `sender_id`, `channel`: from context
|
|
272
|
+
|
|
273
|
+
### `antenna_event_scan`
|
|
274
|
+
Scan people in an event. No distance limit โ returns all participants.
|
|
275
|
+
- `code`: event code
|
|
276
|
+
- `sender_id`, `channel`: from context
|
|
277
|
+
- Returns profiles with `source: "event"` tag
|