feat: use jetstream instead of firehose
This commit is contained in:
parent
f237f33946
commit
dda2552126
6 changed files with 58 additions and 12 deletions
|
|
@ -11,10 +11,10 @@ DID=""
|
||||||
HANDLE=""
|
HANDLE=""
|
||||||
|
|
||||||
# https://bsky.app/settings/app-passwords
|
# https://bsky.app/settings/app-passwords
|
||||||
BSKY_PASSWORD=""
|
APP_PASSWORD=""
|
||||||
|
|
||||||
# https://aistudio.google.com/apikey
|
# https://aistudio.google.com/apikey
|
||||||
GEMINI_API_KEY=""
|
GEMINI_API_KEY=""
|
||||||
|
|
||||||
DAILY_QUERY_LIMIT=15
|
DAILY_QUERY_LIMIT=15
|
||||||
USE_FIREHOSE=false
|
USE_JETSTREAM=false
|
||||||
|
|
@ -10,7 +10,7 @@ services:
|
||||||
- "GEMINI_MODEL=${GEMINI_MODEL:-gemini-2.5-flash}"
|
- "GEMINI_MODEL=${GEMINI_MODEL:-gemini-2.5-flash}"
|
||||||
- "DID=${DID:?}"
|
- "DID=${DID:?}"
|
||||||
- "HANDLE=${HANDLE:?}"
|
- "HANDLE=${HANDLE:?}"
|
||||||
- "BSKY_PASSWORD=${BSKY_PASSWORD:?}"
|
- "APP_PASSWORD=${APP_PASSWORD:?}"
|
||||||
- "GEMINI_API_KEY=${GEMINI_API_KEY:?}"
|
- "GEMINI_API_KEY=${GEMINI_API_KEY:?}"
|
||||||
volumes:
|
volumes:
|
||||||
- aero_db:/sqlite.db
|
- aero_db:/sqlite.db
|
||||||
|
|
|
||||||
48
src/core.ts
48
src/core.ts
|
|
@ -1,13 +1,57 @@
|
||||||
import { GoogleGenAI } from "@google/genai";
|
import { GoogleGenAI } from "@google/genai";
|
||||||
import { Bot, EventStrategy } from "@skyware/bot";
|
import { Bot, EventStrategy } from "@skyware/bot";
|
||||||
import { env } from "./env";
|
import { env } from "./env";
|
||||||
|
import type { BinaryType } from "bun";
|
||||||
|
|
||||||
|
// Websocket patch was written by Claude, hopefully it doesn't suck
|
||||||
|
const OriginalWebSocket = global.WebSocket;
|
||||||
|
const binaryTypeDescriptor = Object.getOwnPropertyDescriptor(
|
||||||
|
OriginalWebSocket.prototype,
|
||||||
|
"binaryType",
|
||||||
|
);
|
||||||
|
|
||||||
|
const originalSetter = binaryTypeDescriptor?.set;
|
||||||
|
|
||||||
|
if (OriginalWebSocket && originalSetter) {
|
||||||
|
global.WebSocket = new Proxy(OriginalWebSocket, {
|
||||||
|
construct(target, args) {
|
||||||
|
//@ts-ignore
|
||||||
|
const ws = new target(...args) as WebSocket & {
|
||||||
|
_binaryType?: BinaryType;
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.defineProperty(ws, "binaryType", {
|
||||||
|
get(): BinaryType {
|
||||||
|
return ws._binaryType ||
|
||||||
|
(binaryTypeDescriptor.get
|
||||||
|
? binaryTypeDescriptor.get.call(ws)
|
||||||
|
: "arraybuffer");
|
||||||
|
},
|
||||||
|
set(value: BinaryType) {
|
||||||
|
//@ts-ignore
|
||||||
|
if (value === "blob") {
|
||||||
|
originalSetter.call(ws, "arraybuffer");
|
||||||
|
//@ts-ignore
|
||||||
|
ws._binaryType = "blob";
|
||||||
|
} else {
|
||||||
|
originalSetter.call(ws, value);
|
||||||
|
ws._binaryType = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return ws;
|
||||||
|
},
|
||||||
|
}) as typeof WebSocket;
|
||||||
|
}
|
||||||
|
|
||||||
export const bot = new Bot({
|
export const bot = new Bot({
|
||||||
service: env.SERVICE,
|
service: env.SERVICE,
|
||||||
emitChatEvents: true,
|
emitChatEvents: true,
|
||||||
eventEmitterOptions: {
|
eventEmitterOptions: {
|
||||||
strategy: env.USE_FIREHOSE
|
strategy: env.USE_JETSTREAM
|
||||||
? EventStrategy.Firehose
|
? EventStrategy.Jetstream
|
||||||
: EventStrategy.Polling,
|
: EventStrategy.Polling,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,11 @@ 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().optional(),
|
||||||
|
|
||||||
DID: z.string(),
|
DID: z.string(),
|
||||||
HANDLE: z.string(),
|
HANDLE: z.string(),
|
||||||
BSKY_PASSWORD: z.string(),
|
APP_PASSWORD: z.string(),
|
||||||
|
|
||||||
GEMINI_API_KEY: z.string(),
|
GEMINI_API_KEY: z.string(),
|
||||||
DAILY_QUERY_LIMIT: z.preprocess(
|
DAILY_QUERY_LIMIT: z.preprocess(
|
||||||
|
|
@ -21,7 +23,7 @@ const envSchema = z.object({
|
||||||
(typeof val === "string" && val.trim() !== "") ? Number(val) : undefined,
|
(typeof val === "string" && val.trim() !== "") ? Number(val) : undefined,
|
||||||
z.number().int().positive().default(15),
|
z.number().int().positive().default(15),
|
||||||
),
|
),
|
||||||
USE_FIREHOSE: z.preprocess(
|
USE_JETSTREAM: z.preprocess(
|
||||||
(val) => val === "true",
|
(val) => val === "true",
|
||||||
z.boolean().default(false),
|
z.boolean().default(false),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -170,12 +170,12 @@ export async function handler(message: ChatMessage): Promise<void> {
|
||||||
throw new Error("Failed to generate text. Returned undefined.");
|
throw new Error("Failed to generate text. Returned undefined.");
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.success("Generated text:", inference.text);
|
|
||||||
|
|
||||||
saveMessage(conversation, env.DID, inference.text!);
|
|
||||||
|
|
||||||
const responseText = inference.text;
|
const responseText = inference.text;
|
||||||
|
|
||||||
if (responseText) {
|
if (responseText) {
|
||||||
|
logger.success("Generated text:", inference.text);
|
||||||
|
saveMessage(conversation, env.DID, inference.text!);
|
||||||
|
|
||||||
await sendResponse(conversation, responseText);
|
await sendResponse(conversation, responseText);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ logger.info("Logging in..");
|
||||||
try {
|
try {
|
||||||
await bot.login({
|
await bot.login({
|
||||||
identifier: env.HANDLE,
|
identifier: env.HANDLE,
|
||||||
password: env.BSKY_PASSWORD,
|
password: env.APP_PASSWORD,
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.success(`Logged in as @${env.HANDLE} (${env.DID})`);
|
logger.success(`Logged in as @${env.HANDLE} (${env.DID})`);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue