this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

console.logs

alice b154cb1d a59b5839

+25 -4
+25 -4
src/label.ts
··· 9 9 import "dotenv/config"; 10 10 import fs from "node:fs"; 11 11 12 + console.log("Starting labeler application"); 12 13 13 14 const agent = new AtpAgent({ 14 15 service: process.env.BSKY_SERVICE ?? "https://bsky.social", ··· 25 26 26 27 server.start(PORT, (error, address) => { 27 28 if (error) { 28 - console.error(error); 29 + console.error("Failed to start labeler server:", error); 29 30 } else { 30 31 console.log(`Labeler server listening on ${address}`); 31 32 } ··· 37 38 subject: string | AppBskyActorDefs.ProfileView, 38 39 rkey: string 39 40 ) => { 41 + console.log(`Labeling subject: ${typeof subject === 'string' ? subject : subject.did}, rkey: ${rkey}`); 42 + 40 43 const did = AppBskyActorDefs.isProfileView(subject) ? subject.did : subject; 44 + console.log(`DID: ${did}`); 41 45 42 46 const query = server.db 43 47 .prepare<unknown[], ComAtprotoLabelDefs.Label>( 44 48 `SELECT * FROM labels WHERE uri = ?` 45 49 ) 46 50 .all(did); 51 + console.log(`Found ${query.length} existing labels for ${did}`); 47 52 48 53 const currentLabel = query.find( 49 54 (label) => !label.neg && HOUSES.includes(label.val) 50 55 ); 56 + console.log(`Current house label: ${currentLabel ? currentLabel.val : 'None'}`); 51 57 52 58 if (rkey.includes(DELETE)) { 59 + console.log(`Deleting label for ${did}`); 53 60 if (currentLabel) { 54 61 await server 55 62 .createLabels({ uri: did }, { negate: [currentLabel.val] }) 56 - .catch((err) => console.log(err)) 63 + .catch((err) => console.error(`Error deleting label: ${err}`)) 57 64 .then(() => console.log(`Deleted label for ${did}`)); 65 + } else { 66 + console.log(`No label to delete for ${did}`); 58 67 } 59 68 } else { 60 69 if (currentLabel) { ··· 62 71 return; 63 72 } 64 73 74 + console.log(`Fetching avatar for ${did}`); 65 75 let avatarBuffer: Buffer; 66 - 67 76 const avatar = `avatars/${subject}.png`; 68 77 69 78 if (typeof subject === "string") { 79 + console.log(`Fetching profile for ${subject}`); 70 80 const { data } = await agent.getProfile({ actor: subject }); 71 - if (!data) throw new Error("Profile not found"); 81 + if (!data) { 82 + console.error(`Profile not found for ${subject}`); 83 + throw new Error("Profile not found"); 84 + } 72 85 subject = data; 73 86 } 74 87 75 88 if (AppBskyActorDefs.isProfileView(subject) && subject.avatar) { 89 + console.log(`Loading avatar from URL: ${subject.avatar}`); 76 90 const image = await loadImage(subject.avatar); 77 91 const canvas = createCanvas(100, 100); 78 92 const ctx = canvas.getContext("2d"); 79 93 ctx.drawImage(image, 0, 0, 100, 100); 80 94 avatarBuffer = canvas.toBuffer(); 81 95 fs.writeFileSync(avatar, avatarBuffer); 96 + console.log(`Avatar saved to ${avatar}`); 82 97 } else { 98 + console.log(`No avatar found, using default 1x1 white image`); 83 99 const canvas = createCanvas(1, 1); 84 100 const ctx = canvas.getContext("2d"); 85 101 ctx.fillStyle = "white"; ··· 87 103 avatarBuffer = canvas.toBuffer(); 88 104 } 89 105 106 + console.log(`Generating prompt for ${did}`); 90 107 const promptTemplate = ` 91 108 You're the Sorting Hat from Harry Potter, operating as a bot on the microblogging social network BlueSky on data from user profiles. 92 109 Which Hogwarts house would this user belong to? ··· 97 114 If the user has an avatar, it's been attached to the message. If it's a 1x1 white image, please ignore it and focus on the name and bio. 98 115 `; 99 116 117 + console.log(`Calling AI to decide house for ${did}`); 100 118 await generateText({ 101 119 model: openai("gpt-4o"), 102 120 messages: [ ··· 130 148 }), 131 149 }, 132 150 }); 151 + console.log(`AI decision complete for ${did}`); 133 152 } 134 153 }; 154 + 155 + console.log("Labeler application initialized");