feat: include image alt text with post context
This commit is contained in:
parent
b2ec6fd88d
commit
8724576366
5 changed files with 56 additions and 15 deletions
11
Dockerfile
11
Dockerfile
|
|
@ -8,15 +8,4 @@ RUN bun install --frozen-lockfile
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
ENV AUTHORIZED_USERS=""
|
|
||||||
ENV SERVICE="https://bsky.social"
|
|
||||||
ENV DB_PATH="data/sqlite.db"
|
|
||||||
ENV GEMINI_MODEL="gemini-2.5-flash"
|
|
||||||
ENV ADMIN_DID=""
|
|
||||||
ENV ADMIN_HANDLE=""
|
|
||||||
ENV DID=""
|
|
||||||
ENV HANDLE=""
|
|
||||||
ENV BSKY_PASSWORD=""
|
|
||||||
ENV GEMINI_API_KEY=""
|
|
||||||
|
|
||||||
CMD ["bun", "start"]
|
CMD ["bun", "start"]
|
||||||
17
docker-compose.yml
Normal file
17
docker-compose.yml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
services:
|
||||||
|
aero:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
environment:
|
||||||
|
- "AUTHORIZED_USERS="
|
||||||
|
- "SERVICE=${SERVICE:?https://bsky.social}"
|
||||||
|
- "DB_PATH=data/sqlite.db"
|
||||||
|
- "GEMINI_MODEL=${GEMINI_MODEL:?gemini-2.5-flash}"
|
||||||
|
- "DID=${DID:?}"
|
||||||
|
- "HANDLE=${HANDLE:?}"
|
||||||
|
- "BSKY_PASSWORD=${BSKY_PASSWORD:?}"
|
||||||
|
- "GEMINI_API_KEY=${GEMINI_API_KEY:?}"
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
- aero_db:/app/data
|
||||||
|
|
@ -11,8 +11,6 @@ const envSchema = z.object({
|
||||||
DB_PATH: z.string().default("sqlite.db"),
|
DB_PATH: z.string().default("sqlite.db"),
|
||||||
GEMINI_MODEL: z.string().default("gemini-2.5-flash"),
|
GEMINI_MODEL: z.string().default("gemini-2.5-flash"),
|
||||||
|
|
||||||
ADMIN_DID: z.string(),
|
|
||||||
ADMIN_HANDLE: z.string(),
|
|
||||||
DID: z.string(),
|
DID: z.string(),
|
||||||
HANDLE: z.string(),
|
HANDLE: z.string(),
|
||||||
BSKY_PASSWORD: z.string(),
|
BSKY_PASSWORD: z.string(),
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,11 @@ import { conversations, messages } from "../db/schema";
|
||||||
import { and, eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import { env } from "../env";
|
import { env } from "../env";
|
||||||
import { bot, MAX_GRAPHEMES } from "../core";
|
import { bot, MAX_GRAPHEMES } from "../core";
|
||||||
import { traverseThread } from "./thread";
|
import { parsePostImages, traverseThread } from "./post";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Utilities
|
||||||
|
*/
|
||||||
const resolveDid = (convo: Conversation, did: string) =>
|
const resolveDid = (convo: Conversation, did: string) =>
|
||||||
convo.members.find((actor) => actor.did == did)!;
|
convo.members.find((actor) => actor.did == did)!;
|
||||||
|
|
||||||
|
|
@ -23,6 +26,9 @@ function generateRevision(bytes = 8) {
|
||||||
return Array.from(array, (b) => b.toString(16).padStart(2, "0")).join("");
|
return Array.from(array, (b) => b.toString(16).padStart(2, "0")).join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Conversations
|
||||||
|
*/
|
||||||
async function initConvo(convo: Conversation) {
|
async function initConvo(convo: Conversation) {
|
||||||
const user = getUserDid(convo);
|
const user = getUserDid(convo);
|
||||||
|
|
||||||
|
|
@ -136,6 +142,7 @@ export async function parseConversation(convo: Conversation) {
|
||||||
? `${post.author.displayName} (${post.author.handle})`
|
? `${post.author.displayName} (${post.author.handle})`
|
||||||
: `Handle: ${post.author.handle}`,
|
: `Handle: ${post.author.handle}`,
|
||||||
text: post.text,
|
text: post.text,
|
||||||
|
images: parsePostImages(post),
|
||||||
likes: post.likeCount || 0,
|
likes: post.likeCount || 0,
|
||||||
replies: post.replyCount || 0,
|
replies: post.replyCount || 0,
|
||||||
},
|
},
|
||||||
|
|
@ -152,6 +159,9 @@ export async function parseConversation(convo: Conversation) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Messages
|
||||||
|
*/
|
||||||
async function parseMessagePostUri(message: ChatMessage) {
|
async function parseMessagePostUri(message: ChatMessage) {
|
||||||
if (!message.embed) return null;
|
if (!message.embed) return null;
|
||||||
const post = message.embed;
|
const post = message.embed;
|
||||||
|
|
@ -194,6 +204,9 @@ export async function saveMessage(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reponse Utilities
|
||||||
|
*/
|
||||||
export function exceedsGraphemes(content: string) {
|
export function exceedsGraphemes(content: string) {
|
||||||
return graphemeLength(content) > MAX_GRAPHEMES;
|
return graphemeLength(content) > MAX_GRAPHEMES;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,31 @@
|
||||||
import { Post } from "@skyware/bot";
|
import { EmbedImage, Post } from "@skyware/bot";
|
||||||
import * as c from "../core";
|
import * as c from "../core";
|
||||||
import * as yaml from "js-yaml";
|
import * as yaml from "js-yaml";
|
||||||
|
|
||||||
|
export function parsePostImages(post: Post) {
|
||||||
|
if (!post.embed) return [];
|
||||||
|
|
||||||
|
let images: EmbedImage[] = [];
|
||||||
|
|
||||||
|
if (post.embed.isImages()) {
|
||||||
|
images = post.embed.images;
|
||||||
|
} else if (post.embed.isRecordWithMedia()) {
|
||||||
|
const media = post.embed.media;
|
||||||
|
if (media && media.isImages()) {
|
||||||
|
images = media.images;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return images.map((image, idx) => parseImage(image, idx + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseImage(image: EmbedImage, index: number) {
|
||||||
|
return {
|
||||||
|
index: index,
|
||||||
|
alt: image.alt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Traversal
|
Traversal
|
||||||
*/
|
*/
|
||||||
Loading…
Reference in a new issue