feat: config object to abstract user information

This commit is contained in:
2025-07-10 10:03:55 +01:00
parent b90d30316e
commit 60fed78d17
4 changed files with 50 additions and 20 deletions

View File

@ -1,28 +1,19 @@
import { createRequesty } from "@requesty/ai-sdk"; import { createRequesty } from "@requesty/ai-sdk";
import { generateText, tool, ToolResultUnion, type CoreMessage } from "ai"; import { generateText, tool, type CoreMessage } from "ai";
import z from "zod"; import z from "zod";
const requesty = createRequesty({ const requesty = createRequesty({
apiKey: process.env.REQUESTY_API_KEY, apiKey: process.env.REQUESTY_API_KEY,
}); });
const system = ` const getSystem = (bossInfo: string, userInfo: string) => `
Todays date: ${new Date().toISOString()} Todays date: ${new Date().toISOString()}
You are a personal assistant to John Costa, a software engineer. And you will mostly talk to Rio, John's Fiancee. # Boss Info
Your job is to make sure that Rio's queries are answered, without bothering John. ${bossInfo}
About John: # You are speaking with
- He is 23. ${userInfo}
- He is a bit silly.
- He loves cat memes.
- He is a programmer
- He loves Rio
You will be speaking to Rio. Only forward Rio's messages if you believe them to be urgent.
You must always return a message to Rio if you have forwarded the message.
You may also give John tasks, with a time and date attached to them.
`; `;
const createTools = () => ({ const createTools = () => ({
@ -70,6 +61,8 @@ export type ToolActions = {
export const getResponse = async ( export const getResponse = async (
actions: ToolActions, actions: ToolActions,
messages: CoreMessage[], messages: CoreMessage[],
bossInfo: string,
userInfo: string,
): Promise<CoreMessage[]> => { ): Promise<CoreMessage[]> => {
const tools = createTools(); const tools = createTools();
for (const [k, v] of Object.entries(tools)) { for (const [k, v] of Object.entries(tools)) {
@ -78,7 +71,7 @@ export const getResponse = async (
const result = await generateText({ const result = await generateText({
model: requesty("smart/task"), model: requesty("smart/task"),
system, system: getSystem(bossInfo, userInfo),
messages, messages,
tools, tools,
}); });

27
src/config/index.ts Normal file
View File

@ -0,0 +1,27 @@
export type Config = {
description: string;
// Map: Telegram Username -> User information for AI context.
whitelist: Record<string, string | null>;
};
export const testConfig: Config = {
description: `
Your boss is John Costa.
About John:
- He is 23.
- He is a bit silly.
- He loves cat memes.
- He is a programmer
- He loves Rio
He is very busy so he wishes you to do your best to answer users questions.
`,
whitelist: {
Johncosta27: `
This is Rio. She is John's wife, and she might have important things to tell John.
But you should try and not let her past you because John is very busy.
`,
},
};

View File

@ -1,6 +1,7 @@
import { testConfig } from "./config";
import { setupTelegram } from "./telegram"; import { setupTelegram } from "./telegram";
setupTelegram({ setupTelegram({
bossChatId: "1502730007", bossChatId: "1502730007",
whitelist: new Set(["Johncosta27"]), config: testConfig,
}); });

View File

@ -1,6 +1,7 @@
import type { CoreMessage } from "ai"; import type { CoreMessage } from "ai";
import TelegramBot from "node-telegram-bot-api"; import TelegramBot from "node-telegram-bot-api";
import { getResponse } from "../ai"; import { getResponse } from "../ai";
import { Config } from "../config";
const CHAT_MAX_LENGTH = 100; const CHAT_MAX_LENGTH = 100;
@ -42,16 +43,18 @@ const createChat = () => {
type TelegramOptions = { type TelegramOptions = {
bossChatId: string; bossChatId: string;
whitelist: Set<string>; config: Config;
}; };
export const setupTelegram = ({ bossChatId, whitelist }: TelegramOptions) => { export const setupTelegram = ({ bossChatId, config }: TelegramOptions) => {
console.log("Setting up telegram bot"); console.log("Setting up telegram bot");
const bot = new TelegramBot(process.env.TELEGRAM_TOKEN ?? "", { const bot = new TelegramBot(process.env.TELEGRAM_TOKEN ?? "", {
polling: true, polling: true,
}); });
const whitelistUsers = Object.keys(config.whitelist);
const chats = createChat(); const chats = createChat();
bot.on("message", async (msg, meta) => { bot.on("message", async (msg, meta) => {
@ -74,11 +77,15 @@ export const setupTelegram = ({ bossChatId, whitelist }: TelegramOptions) => {
return; return;
} }
if (!whitelist.has(fromUsername)) { if (!whitelistUsers.includes(fromUsername)) {
bot.sendMessage(msg.chat.id, "Sorry, you are not part of the whitelist."); bot.sendMessage(msg.chat.id, "Sorry, you are not part of the whitelist.");
return; return;
} }
const userInfo =
config.whitelist[fromUsername] ??
`This is ${msg.from?.first_name} ${msg.from?.last_name}. We don't know anything about them.`;
chats.addMessage(msg.chat.id, text); chats.addMessage(msg.chat.id, text);
const messages = await getResponse( const messages = await getResponse(
@ -96,6 +103,8 @@ export const setupTelegram = ({ bossChatId, whitelist }: TelegramOptions) => {
}, },
// SAFETY: addMessage is called before, therefore this function cannot throw. // SAFETY: addMessage is called before, therefore this function cannot throw.
chats.getChat(msg.chat.id), chats.getChat(msg.chat.id),
config.description,
userInfo,
); );
chats.setMessages(msg.chat.id, messages); chats.setMessages(msg.chat.id, messages);