@elizaos/plugin-bluesky 2.0.0-alpha.7 → 2.0.11-beta.7

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.
@@ -1,715 +0,0 @@
1
- // index.ts
2
- import { logger as logger4 } from "@elizaos/core";
3
-
4
- // services/bluesky.ts
5
- import { logger as logger3, Service } from "@elizaos/core";
6
-
7
- // client.ts
8
- import { BskyAgent, RichText } from "@atproto/api";
9
- import { logger } from "@elizaos/core";
10
- import { LRUCache } from "lru-cache";
11
-
12
- // types/index.ts
13
- import { z } from "zod";
14
- var BLUESKY_SERVICE_URL = "https://bsky.social";
15
- var BLUESKY_MAX_POST_LENGTH = 300;
16
- var BLUESKY_POLL_INTERVAL = 60;
17
- var BLUESKY_POST_INTERVAL_MIN = 1800;
18
- var BLUESKY_POST_INTERVAL_MAX = 3600;
19
- var BLUESKY_ACTION_INTERVAL = 120;
20
- var BLUESKY_MAX_ACTIONS = 5;
21
- var BLUESKY_CHAT_SERVICE_DID = "did:web:api.bsky.chat";
22
- var BLUESKY_SERVICE_NAME = "bluesky";
23
- var AT_PROTOCOL_HANDLE_REGEX = /^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/;
24
- var CACHE_TTL = {
25
- PROFILE: 3600000,
26
- TIMELINE: 300000,
27
- POST: 1800000,
28
- NOTIFICATIONS: 300000,
29
- CONVERSATIONS: 300000
30
- };
31
- var CACHE_SIZE = {
32
- PROFILE: 1000,
33
- TIMELINE: 500,
34
- POST: 1e4,
35
- NOTIFICATIONS: 1000,
36
- CONVERSATIONS: 100
37
- };
38
- var BlueSkyConfigSchema = z.object({
39
- handle: z.string().regex(AT_PROTOCOL_HANDLE_REGEX, "Invalid handle format"),
40
- password: z.string().min(1),
41
- service: z.string().url().default(BLUESKY_SERVICE_URL),
42
- dryRun: z.boolean().default(false),
43
- pollInterval: z.number().positive().default(BLUESKY_POLL_INTERVAL),
44
- enablePost: z.boolean().default(true),
45
- postIntervalMin: z.number().positive().default(BLUESKY_POST_INTERVAL_MIN),
46
- postIntervalMax: z.number().positive().default(BLUESKY_POST_INTERVAL_MAX),
47
- enableActionProcessing: z.boolean().default(true),
48
- actionInterval: z.number().positive().default(BLUESKY_ACTION_INTERVAL),
49
- postImmediately: z.boolean().default(false),
50
- maxActionsProcessing: z.number().positive().default(BLUESKY_MAX_ACTIONS),
51
- enableDMs: z.boolean().default(true)
52
- });
53
-
54
- class BlueSkyError extends Error {
55
- code;
56
- status;
57
- constructor(message, code, status) {
58
- super(message);
59
- this.code = code;
60
- this.status = status;
61
- this.name = "BlueSkyError";
62
- }
63
- }
64
-
65
- // client.ts
66
- function isPostView(item) {
67
- return typeof item === "object" && item !== null && "uri" in item && "cid" in item && "author" in item && "record" in item && "indexedAt" in item && typeof item.uri === "string" && typeof item.cid === "string";
68
- }
69
- function isReplyWithPostViews(reply) {
70
- return typeof reply === "object" && reply !== null && "root" in reply && "parent" in reply && isPostView(reply.root) && isPostView(reply.parent);
71
- }
72
- function adaptPostView(postView) {
73
- const author = postView.author;
74
- const record = postView.record;
75
- return {
76
- uri: postView.uri,
77
- cid: postView.cid,
78
- author: {
79
- did: author.did,
80
- handle: author.handle,
81
- displayName: author.displayName,
82
- description: author.description,
83
- avatar: author.avatar,
84
- banner: author.banner,
85
- followersCount: author.followersCount,
86
- followsCount: author.followsCount,
87
- postsCount: author.postsCount,
88
- indexedAt: author.indexedAt,
89
- createdAt: author.createdAt
90
- },
91
- record: {
92
- $type: record.$type ?? "app.bsky.feed.post",
93
- text: record.text ?? "",
94
- facets: record.facets,
95
- embed: record.embed,
96
- createdAt: record.createdAt ?? ""
97
- },
98
- embed: postView.embed,
99
- replyCount: postView.replyCount,
100
- repostCount: postView.repostCount,
101
- likeCount: postView.likeCount,
102
- quoteCount: postView.quoteCount,
103
- indexedAt: postView.indexedAt
104
- };
105
- }
106
-
107
- class BlueSkyClient {
108
- config;
109
- agent;
110
- session = null;
111
- profileCache;
112
- constructor(config) {
113
- this.config = config;
114
- this.agent = new BskyAgent({ service: config.service });
115
- this.profileCache = new LRUCache({
116
- max: CACHE_SIZE.PROFILE,
117
- ttl: CACHE_TTL.PROFILE
118
- });
119
- }
120
- async authenticate() {
121
- const response = await this.agent.login({
122
- identifier: this.config.handle,
123
- password: this.config.password
124
- });
125
- if (!response.success) {
126
- throw new BlueSkyError("Authentication failed", "AUTH_FAILED");
127
- }
128
- this.session = {
129
- did: response.data.did,
130
- handle: response.data.handle,
131
- email: response.data.email,
132
- accessJwt: response.data.accessJwt,
133
- refreshJwt: response.data.refreshJwt
134
- };
135
- logger.info(`Authenticated with BlueSky: ${this.session.handle}`);
136
- return this.session;
137
- }
138
- getSession() {
139
- return this.session;
140
- }
141
- async getProfile(handle) {
142
- const cached = this.profileCache.get(handle);
143
- if (cached)
144
- return cached;
145
- const response = await this.agent.getProfile({ actor: handle });
146
- const profile = {
147
- did: response.data.did,
148
- handle: response.data.handle,
149
- displayName: response.data.displayName,
150
- description: response.data.description,
151
- avatar: response.data.avatar,
152
- banner: response.data.banner,
153
- followersCount: response.data.followersCount,
154
- followsCount: response.data.followsCount,
155
- postsCount: response.data.postsCount,
156
- indexedAt: response.data.indexedAt,
157
- createdAt: response.data.createdAt
158
- };
159
- this.profileCache.set(handle, profile);
160
- return profile;
161
- }
162
- async getTimeline(params = {}) {
163
- const response = await this.agent.getTimeline({
164
- algorithm: params.algorithm,
165
- limit: params.limit ?? 50,
166
- cursor: params.cursor
167
- });
168
- return {
169
- cursor: response.data.cursor,
170
- feed: response.data.feed.map((item) => {
171
- const reply = isReplyWithPostViews(item.reply) ? {
172
- root: adaptPostView(item.reply.root),
173
- parent: adaptPostView(item.reply.parent)
174
- } : undefined;
175
- return {
176
- post: adaptPostView(item.post),
177
- reply,
178
- reason: item.reason
179
- };
180
- })
181
- };
182
- }
183
- async sendPost(request) {
184
- if (this.config.dryRun) {
185
- logger.info(`Dry run: would create post with text: ${request.content.text}`);
186
- return this.mockPost(request.content.text);
187
- }
188
- const rt = new RichText({ text: request.content.text });
189
- await rt.detectFacets(this.agent);
190
- const record = {
191
- $type: "app.bsky.feed.post",
192
- text: rt.text,
193
- facets: rt.facets,
194
- createdAt: new Date().toISOString()
195
- };
196
- if (request.replyTo) {
197
- record.reply = { root: request.replyTo, parent: request.replyTo };
198
- }
199
- if (request.content.embed) {
200
- record.embed = request.content.embed;
201
- }
202
- const response = await this.agent.post(record);
203
- const thread = await this.agent.getPostThread({
204
- uri: response.uri,
205
- depth: 0
206
- });
207
- if (thread.data.thread.$type !== "app.bsky.feed.defs#threadViewPost") {
208
- throw new BlueSkyError("Failed to retrieve created post", "POST_CREATE_FAILED");
209
- }
210
- const threadViewPost = thread.data.thread;
211
- return adaptPostView(threadViewPost.post);
212
- }
213
- async deletePost(uri) {
214
- if (this.config.dryRun) {
215
- logger.info(`Dry run: would delete post: ${uri}`);
216
- return;
217
- }
218
- await this.agent.deletePost(uri);
219
- }
220
- async likePost(uri, cid) {
221
- if (this.config.dryRun) {
222
- logger.info(`Dry run: would like post: ${uri}`);
223
- return;
224
- }
225
- await this.agent.like(uri, cid);
226
- }
227
- async repost(uri, cid) {
228
- if (this.config.dryRun) {
229
- logger.info({ uri }, "Dry run: would repost");
230
- return;
231
- }
232
- await this.agent.repost(uri, cid);
233
- }
234
- async getNotifications(limit = 50, cursor) {
235
- const response = await this.agent.listNotifications({ limit, cursor });
236
- return {
237
- notifications: response.data.notifications,
238
- cursor: response.data.cursor
239
- };
240
- }
241
- async updateSeenNotifications() {
242
- await this.agent.updateSeenNotifications();
243
- }
244
- async getConversations(limit = 50, cursor) {
245
- const response = await this.agent.api.chat.bsky.convo.listConvos({ limit, cursor }, { headers: { "atproto-proxy": BLUESKY_CHAT_SERVICE_DID } });
246
- return {
247
- conversations: response.data.convos,
248
- cursor: response.data.cursor
249
- };
250
- }
251
- async getMessages(convoId, limit = 50, cursor) {
252
- const response = await this.agent.api.chat.bsky.convo.getMessages({ convoId, limit, cursor }, { headers: { "atproto-proxy": BLUESKY_CHAT_SERVICE_DID } });
253
- return {
254
- messages: response.data.messages,
255
- cursor: response.data.cursor
256
- };
257
- }
258
- async sendMessage(request) {
259
- if (this.config.dryRun) {
260
- logger.info({ convoId: request.convoId }, "Dry run: would send message");
261
- return this.mockMessage(request.message.text ?? "");
262
- }
263
- const response = await this.agent.api.chat.bsky.convo.sendMessage({
264
- convoId: request.convoId,
265
- message: { text: request.message.text ?? "" }
266
- }, { headers: { "atproto-proxy": BLUESKY_CHAT_SERVICE_DID } });
267
- return response.data;
268
- }
269
- async cleanup() {
270
- this.profileCache.clear();
271
- this.session = null;
272
- }
273
- mockPost(text) {
274
- const now = new Date().toISOString();
275
- return {
276
- uri: `mock://post/${Date.now()}`,
277
- cid: `mock-cid-${Date.now()}`,
278
- author: {
279
- did: this.session?.did ?? "did:plc:mock",
280
- handle: this.session?.handle ?? "mock.handle"
281
- },
282
- record: { $type: "app.bsky.feed.post", text, createdAt: now },
283
- indexedAt: now
284
- };
285
- }
286
- mockMessage(text) {
287
- return {
288
- id: `mock-msg-${Date.now()}`,
289
- rev: "1",
290
- text,
291
- sender: { did: this.session?.did ?? "did:plc:mock" },
292
- sentAt: new Date().toISOString()
293
- };
294
- }
295
- }
296
-
297
- // managers/agent.ts
298
- import { logger as logger2 } from "@elizaos/core";
299
-
300
- // utils/config.ts
301
- function getApiKeyOptional(runtime, key) {
302
- const value = runtime.getSetting(key);
303
- return typeof value === "string" ? value : undefined;
304
- }
305
- function hasBlueSkyEnabled(runtime) {
306
- const enabled = runtime.getSetting("BLUESKY_ENABLED");
307
- if (enabled)
308
- return String(enabled).toLowerCase() === "true";
309
- return Boolean(runtime.getSetting("BLUESKY_HANDLE") && runtime.getSetting("BLUESKY_PASSWORD"));
310
- }
311
- function validateBlueSkyConfig(runtime) {
312
- const result = BlueSkyConfigSchema.safeParse({
313
- handle: String(runtime.getSetting("BLUESKY_HANDLE") ?? ""),
314
- password: String(runtime.getSetting("BLUESKY_PASSWORD") ?? ""),
315
- service: String(runtime.getSetting("BLUESKY_SERVICE") ?? BLUESKY_SERVICE_URL),
316
- dryRun: runtime.getSetting("BLUESKY_DRY_RUN") === "true",
317
- pollInterval: parseInt(String(runtime.getSetting("BLUESKY_POLL_INTERVAL") ?? ""), 10) || BLUESKY_POLL_INTERVAL,
318
- enablePost: runtime.getSetting("BLUESKY_ENABLE_POSTING") !== "false",
319
- postIntervalMin: parseInt(String(runtime.getSetting("BLUESKY_POST_INTERVAL_MIN") ?? ""), 10) || BLUESKY_POST_INTERVAL_MIN,
320
- postIntervalMax: parseInt(String(runtime.getSetting("BLUESKY_POST_INTERVAL_MAX") ?? ""), 10) || BLUESKY_POST_INTERVAL_MAX,
321
- enableActionProcessing: runtime.getSetting("BLUESKY_ENABLE_ACTION_PROCESSING") !== "false",
322
- actionInterval: parseInt(String(runtime.getSetting("BLUESKY_ACTION_INTERVAL") ?? ""), 10) || BLUESKY_ACTION_INTERVAL,
323
- postImmediately: runtime.getSetting("BLUESKY_POST_IMMEDIATELY") === "true",
324
- maxActionsProcessing: parseInt(String(runtime.getSetting("BLUESKY_MAX_ACTIONS_PROCESSING") ?? ""), 10) || BLUESKY_MAX_ACTIONS,
325
- enableDMs: runtime.getSetting("BLUESKY_ENABLE_DMS") !== "false"
326
- });
327
- if (!result.success) {
328
- const errors = result.error.errors?.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ") || result.error.toString();
329
- throw new Error(`Invalid BlueSky configuration: ${errors}`);
330
- }
331
- return result.data;
332
- }
333
- function getPollInterval(runtime) {
334
- const seconds = parseInt(String(runtime.getSetting("BLUESKY_POLL_INTERVAL") ?? ""), 10) || BLUESKY_POLL_INTERVAL;
335
- return seconds * 1000;
336
- }
337
- function getActionInterval(runtime) {
338
- const seconds = parseInt(String(runtime.getSetting("BLUESKY_ACTION_INTERVAL") ?? ""), 10) || BLUESKY_ACTION_INTERVAL;
339
- return seconds * 1000;
340
- }
341
- function getMaxActionsProcessing(runtime) {
342
- return parseInt(String(runtime.getSetting("BLUESKY_MAX_ACTIONS_PROCESSING") ?? ""), 10) || BLUESKY_MAX_ACTIONS;
343
- }
344
- function isPostingEnabled(runtime) {
345
- return runtime.getSetting("BLUESKY_ENABLE_POSTING") !== "false";
346
- }
347
- function shouldPostImmediately(runtime) {
348
- return runtime.getSetting("BLUESKY_POST_IMMEDIATELY") === "true";
349
- }
350
- function getPostIntervalRange(runtime) {
351
- const min = parseInt(String(runtime.getSetting("BLUESKY_POST_INTERVAL_MIN") ?? ""), 10) || BLUESKY_POST_INTERVAL_MIN;
352
- const max = parseInt(String(runtime.getSetting("BLUESKY_POST_INTERVAL_MAX") ?? ""), 10) || BLUESKY_POST_INTERVAL_MAX;
353
- return { min: min * 1000, max: max * 1000 };
354
- }
355
-
356
- // managers/agent.ts
357
- class BlueSkyAgentManager {
358
- runtime;
359
- config;
360
- client;
361
- pollTimer = null;
362
- actionTimer = null;
363
- postTimer = null;
364
- running = false;
365
- lastSeenAt = null;
366
- constructor(runtime, config, client) {
367
- this.runtime = runtime;
368
- this.config = config;
369
- this.client = client;
370
- }
371
- async start() {
372
- if (this.running)
373
- return;
374
- await this.client.authenticate();
375
- this.running = true;
376
- this.startNotificationPolling();
377
- if (this.config.enableActionProcessing) {
378
- this.startActionProcessing();
379
- }
380
- if (isPostingEnabled(this.runtime)) {
381
- this.startAutomatedPosting();
382
- }
383
- logger2.success({ agentId: this.runtime.agentId }, "BlueSky agent manager started");
384
- }
385
- async stop() {
386
- this.running = false;
387
- if (this.pollTimer)
388
- clearInterval(this.pollTimer);
389
- if (this.actionTimer)
390
- clearInterval(this.actionTimer);
391
- if (this.postTimer)
392
- clearTimeout(this.postTimer);
393
- this.pollTimer = null;
394
- this.actionTimer = null;
395
- this.postTimer = null;
396
- await this.client.cleanup();
397
- logger2.info({ agentId: this.runtime.agentId }, "BlueSky agent manager stopped");
398
- }
399
- startNotificationPolling() {
400
- const interval = getPollInterval(this.runtime);
401
- this.pollNotifications();
402
- this.pollTimer = setInterval(() => this.pollNotifications(), interval);
403
- }
404
- async pollNotifications() {
405
- if (!this.running)
406
- return;
407
- const { notifications } = await this.client.getNotifications(50);
408
- if (notifications.length === 0)
409
- return;
410
- const newNotifications = this.lastSeenAt ? notifications.filter((n) => {
411
- const lastSeen = this.lastSeenAt;
412
- return lastSeen !== null && n.indexedAt > lastSeen;
413
- }) : notifications;
414
- if (newNotifications.length > 0) {
415
- this.lastSeenAt = notifications[0].indexedAt;
416
- for (const notification of newNotifications) {
417
- this.emitNotificationEvent(notification);
418
- }
419
- await this.client.updateSeenNotifications();
420
- }
421
- }
422
- emitNotificationEvent(notification) {
423
- const eventMap = {
424
- mention: "bluesky.mention_received",
425
- reply: "bluesky.mention_received",
426
- follow: "bluesky.follow_received",
427
- like: "bluesky.like_received",
428
- repost: "bluesky.repost_received",
429
- quote: "bluesky.quote_received"
430
- };
431
- const event = eventMap[notification.reason];
432
- if (event) {
433
- const payload = {
434
- runtime: this.runtime,
435
- source: "bluesky",
436
- notification
437
- };
438
- this.runtime.emitEvent(event, payload);
439
- }
440
- }
441
- startActionProcessing() {
442
- const interval = getActionInterval(this.runtime);
443
- this.processActions();
444
- this.actionTimer = setInterval(() => this.processActions(), interval);
445
- }
446
- async processActions() {
447
- if (!this.running)
448
- return;
449
- const max = getMaxActionsProcessing(this.runtime);
450
- const { notifications } = await this.client.getNotifications(max);
451
- for (const notification of notifications) {
452
- if (notification.reason === "mention" || notification.reason === "reply") {
453
- const payload = {
454
- runtime: this.runtime,
455
- source: "bluesky",
456
- notification
457
- };
458
- this.runtime.emitEvent("bluesky.should_respond", payload);
459
- }
460
- }
461
- }
462
- startAutomatedPosting() {
463
- if (shouldPostImmediately(this.runtime)) {
464
- this.createAutomatedPost();
465
- }
466
- this.scheduleNextPost();
467
- }
468
- scheduleNextPost() {
469
- const { min, max } = getPostIntervalRange(this.runtime);
470
- const interval = Math.random() * (max - min) + min;
471
- this.postTimer = setTimeout(() => {
472
- if (this.running) {
473
- this.createAutomatedPost();
474
- this.scheduleNextPost();
475
- }
476
- }, interval);
477
- }
478
- createAutomatedPost() {
479
- const payload = {
480
- runtime: this.runtime,
481
- source: "bluesky",
482
- automated: true
483
- };
484
- this.runtime.emitEvent("bluesky.create_post", payload);
485
- }
486
- }
487
-
488
- // services/message.ts
489
- import { composePrompt, ModelType } from "@elizaos/core";
490
-
491
- // generated/prompts/typescript/prompts.ts
492
- var generateDmTemplate = `Generate a friendly direct message response under 200 characters.`;
493
- var generatePostTemplate = `Generate an engaging BlueSky post under {{maxLength}} characters.`;
494
- var truncatePostTemplate = `Shorten to under {{maxLength}} characters: "{{text}}"`;
495
-
496
- // services/message.ts
497
- class BlueSkyMessageService {
498
- client;
499
- runtime;
500
- static serviceType = "IMessageService";
501
- constructor(client, runtime) {
502
- this.client = client;
503
- this.runtime = runtime;
504
- }
505
- async getMessages(convoId, limit = 50) {
506
- const response = await this.client.getMessages(convoId, limit);
507
- return response.messages;
508
- }
509
- async sendMessage(convoId, text) {
510
- const messageText = text.trim() || await this.generateReply();
511
- return this.client.sendMessage({ convoId, message: { text: messageText } });
512
- }
513
- async getConversations(limit = 50) {
514
- const response = await this.client.getConversations(limit);
515
- return response.conversations;
516
- }
517
- async generateReply() {
518
- const prompt = composePrompt({
519
- state: {},
520
- template: generateDmTemplate
521
- });
522
- const response = await this.runtime.useModel(ModelType.TEXT_SMALL, {
523
- prompt,
524
- maxTokens: 50
525
- });
526
- return response;
527
- }
528
- }
529
-
530
- // services/post.ts
531
- import { composePrompt as composePrompt2, ModelType as ModelType2 } from "@elizaos/core";
532
- class BlueSkyPostService {
533
- client;
534
- runtime;
535
- static serviceType = "IPostService";
536
- constructor(client, runtime) {
537
- this.client = client;
538
- this.runtime = runtime;
539
- }
540
- async getPosts(limit = 50, cursor) {
541
- const response = await this.client.getTimeline({ limit, cursor });
542
- return response.feed.map((item) => item.post);
543
- }
544
- async createPost(text, replyTo) {
545
- let postText = text.trim() || await this.generateContent();
546
- if (postText.length > BLUESKY_MAX_POST_LENGTH) {
547
- postText = await this.truncate(postText);
548
- }
549
- const request = {
550
- content: { text: postText },
551
- replyTo
552
- };
553
- return this.client.sendPost(request);
554
- }
555
- async deletePost(uri) {
556
- await this.client.deletePost(uri);
557
- }
558
- async generateContent() {
559
- const prompt = composePrompt2({
560
- state: {
561
- maxLength: String(BLUESKY_MAX_POST_LENGTH)
562
- },
563
- template: generatePostTemplate
564
- });
565
- const response = await this.runtime.useModel(ModelType2.TEXT_SMALL, {
566
- prompt,
567
- maxTokens: 100
568
- });
569
- return response;
570
- }
571
- async truncate(text) {
572
- const prompt = composePrompt2({
573
- state: {
574
- maxLength: String(BLUESKY_MAX_POST_LENGTH),
575
- text
576
- },
577
- template: truncatePostTemplate
578
- });
579
- const response = await this.runtime.useModel(ModelType2.TEXT_SMALL, {
580
- prompt,
581
- maxTokens: 100
582
- });
583
- const truncated = response;
584
- return truncated.length > BLUESKY_MAX_POST_LENGTH ? `${truncated.substring(0, BLUESKY_MAX_POST_LENGTH - 3)}...` : truncated;
585
- }
586
- }
587
-
588
- // services/bluesky.ts
589
- class BlueSkyService extends Service {
590
- static instance;
591
- managers = new Map;
592
- messageServices = new Map;
593
- postServices = new Map;
594
- static serviceType = BLUESKY_SERVICE_NAME;
595
- capabilityDescription = "Send and receive messages on BlueSky";
596
- static getInstance() {
597
- BlueSkyService.instance ??= new BlueSkyService;
598
- return BlueSkyService.instance;
599
- }
600
- static async start(runtime) {
601
- const service = BlueSkyService.getInstance();
602
- if (service.managers.has(runtime.agentId)) {
603
- return service;
604
- }
605
- if (!hasBlueSkyEnabled(runtime)) {
606
- return service;
607
- }
608
- const config = validateBlueSkyConfig(runtime);
609
- const client = new BlueSkyClient({
610
- service: config.service,
611
- handle: config.handle,
612
- password: config.password,
613
- dryRun: config.dryRun
614
- });
615
- const manager = new BlueSkyAgentManager(runtime, config, client);
616
- service.managers.set(runtime.agentId, manager);
617
- service.messageServices.set(runtime.agentId, new BlueSkyMessageService(client, runtime));
618
- service.postServices.set(runtime.agentId, new BlueSkyPostService(client, runtime));
619
- await manager.start();
620
- logger3.success({ agentId: runtime.agentId }, "BlueSky client started");
621
- return service;
622
- }
623
- static async stop(runtime) {
624
- const service = BlueSkyService.getInstance();
625
- const manager = service.managers.get(runtime.agentId);
626
- if (!manager)
627
- return;
628
- await manager.stop();
629
- service.managers.delete(runtime.agentId);
630
- service.messageServices.delete(runtime.agentId);
631
- service.postServices.delete(runtime.agentId);
632
- logger3.info({ agentId: runtime.agentId }, "BlueSky client stopped");
633
- }
634
- async stop() {
635
- for (const manager of this.managers.values()) {
636
- await BlueSkyService.stop(manager.runtime);
637
- }
638
- }
639
- getMessageService(agentId) {
640
- return this.messageServices.get(agentId);
641
- }
642
- getPostService(agentId) {
643
- return this.postServices.get(agentId);
644
- }
645
- }
646
-
647
- // index.ts
648
- var pluginTests = [
649
- {
650
- name: "bluesky_plugin_tests",
651
- tests: [
652
- {
653
- name: "bluesky_test_credentials_validation",
654
- fn: async (runtime) => {
655
- const handle = getApiKeyOptional(runtime, "BLUESKY_HANDLE");
656
- const password = getApiKeyOptional(runtime, "BLUESKY_PASSWORD");
657
- if (!handle || !password) {
658
- throw new Error("BLUESKY_HANDLE and BLUESKY_PASSWORD are not configured");
659
- }
660
- logger4.log("BlueSky credentials are configured");
661
- }
662
- },
663
- {
664
- name: "bluesky_test_service_initialization",
665
- fn: async (runtime) => {
666
- const handle = getApiKeyOptional(runtime, "BLUESKY_HANDLE");
667
- const password = getApiKeyOptional(runtime, "BLUESKY_PASSWORD");
668
- if (!handle || !password) {
669
- logger4.log("Skipping service initialization test - credentials not configured");
670
- return;
671
- }
672
- const service = await BlueSkyService.start(runtime);
673
- if (!service) {
674
- throw new Error("Failed to initialize BlueSky service");
675
- }
676
- logger4.log("BlueSky service initialized successfully");
677
- }
678
- }
679
- ]
680
- }
681
- ];
682
- var blueSkyPlugin = {
683
- name: "bluesky",
684
- description: "BlueSky client plugin using AT Protocol for social interactions",
685
- config: {
686
- BLUESKY_HANDLE: process.env.BLUESKY_HANDLE ?? null,
687
- BLUESKY_PASSWORD: process.env.BLUESKY_PASSWORD ?? null,
688
- BLUESKY_SERVICE: process.env.BLUESKY_SERVICE ?? null,
689
- BLUESKY_DRY_RUN: process.env.BLUESKY_DRY_RUN ?? null,
690
- BLUESKY_POLL_INTERVAL: process.env.BLUESKY_POLL_INTERVAL ?? null,
691
- BLUESKY_ENABLE_POSTING: process.env.BLUESKY_ENABLE_POSTING ?? null,
692
- BLUESKY_ENABLE_DMS: process.env.BLUESKY_ENABLE_DMS ?? null,
693
- BLUESKY_POST_INTERVAL_MIN: process.env.BLUESKY_POST_INTERVAL_MIN ?? null,
694
- BLUESKY_POST_INTERVAL_MAX: process.env.BLUESKY_POST_INTERVAL_MAX ?? null,
695
- BLUESKY_ENABLE_ACTION_PROCESSING: process.env.BLUESKY_ENABLE_ACTION_PROCESSING ?? null,
696
- BLUESKY_ACTION_INTERVAL: process.env.BLUESKY_ACTION_INTERVAL ?? null,
697
- BLUESKY_POST_IMMEDIATELY: process.env.BLUESKY_POST_IMMEDIATELY ?? null,
698
- BLUESKY_MAX_ACTIONS_PROCESSING: process.env.BLUESKY_MAX_ACTIONS_PROCESSING ?? null,
699
- BLUESKY_MAX_POST_LENGTH: process.env.BLUESKY_MAX_POST_LENGTH ?? null
700
- },
701
- async init(_config, _runtime) {
702
- logger4.log("BlueSky plugin initialized");
703
- },
704
- services: [BlueSkyService],
705
- tests: pluginTests
706
- };
707
- var typescript_default = blueSkyPlugin;
708
- export {
709
- typescript_default as default,
710
- blueSkyPlugin,
711
- BlueSkyService,
712
- BlueSkyClient
713
- };
714
-
715
- //# debugId=8E1C17CA465481F364756E2164756E21