Compare commits

...

4 Commits

Author SHA1 Message Date
e696343a73 a crumb of changes 2025-08-12 19:07:22 +00:00
88a0710c55 update system prompt to hopefully make it easier for Lexi to understand 2025-08-04 21:08:47 +00:00
75fa4cea8b jorkin my preanits 2025-08-04 11:56:06 +00:00
733a41a35c revert to more "chat" based api calls 2025-08-04 00:21:10 +00:00
3 changed files with 57 additions and 37 deletions

2
.gitignore vendored
View File

@ -1,6 +1,6 @@
node_modules
# Keep environment variables out of version control
.env
.env*
*.log
*.db
/dist

View File

@ -2,16 +2,14 @@ import {
NewStatusBody,
Notification,
OllamaConfigOptions,
// OllamaChatRequest,
// OllamaChatResponse,
OllamaRequest,
OllamaResponse,
OllamaChatRequest,
OllamaChatResponse,
PostAncestorsForModel,
} from "../types.js";
// import striptags from "striptags";
import { PrismaClient } from "../generated/prisma/client.js";
import {
getInstanceEmojis,
// getInstanceEmojis,
deleteNotification,
getNotifications,
getStatusContext,
@ -22,7 +20,7 @@ import {
alreadyRespondedTo,
recordPendingResponse,
// trimInputData,
selectRandomEmoji,
// selectRandomEmoji,
shouldContinue,
} from "./util.js";
@ -50,10 +48,10 @@ export const envConfig = {
};
const ollamaConfig: OllamaConfigOptions = {
temperature: 0.6,
temperature: 0.9,
top_p: 0.85,
top_k: 40,
num_ctx: 2048,
top_k: 60,
num_ctx: 16384, // maximum context window for Llama 3.1
repeat_penalty: 1.1,
};
@ -62,7 +60,7 @@ const ollamaConfig: OllamaConfigOptions = {
const generateOllamaRequest = async (
notification: Notification
): Promise<OllamaResponse | undefined> => {
): Promise<OllamaChatResponse | undefined> => {
const {
whitelistOnly,
ollamaModel,
@ -97,22 +95,42 @@ const generateOllamaRequest = async (
});
// console.log(conversationHistory);
}
const oneOffPrompt = `${notification.status.account.fqn} says: ${notification.status.pleroma.content["text/plain"]}\n[/INST]`;
const contextPrompt = `<<SYS>>[INST]\n${ollamaSystemPrompt}\nHere is the previous conversation context in JSON format:\n${JSON.stringify(
conversationHistory
)}\nAssume the {account_fqn} key is the user who posted the {plaintext_content} to the users in {mentions}\nReply as if you are a party to the conversation. If you see '@nice-ai' or 'nice-ai' in the {mentions}, you are an addressee of the conversation.\nAppend the '@' sign to each username at the beginning when addressing users.<</SYS>>`;
const ollamaRequestBody: OllamaRequest = {
// Simplified user message (remove [/INST] as it's not needed for Llama 3)
const userMessage = `${notification.status.account.fqn} says to you: \"${notification.status.pleroma.content["text/plain"]}\".`;
let systemContent = ollamaSystemPrompt;
if (replyWithContext) {
// Simplified context instructions (avoid heavy JSON; summarize for clarity)
systemContent = `${ollamaSystemPrompt}\n\nPrevious conversation context:\n${conversationHistory
.map(
(post) =>
`${post.account_fqn} (said to ${post.mentions.join(", ")}): ${
post.plaintext_content
}`
)
.join(
"\n"
)}\nReply to the user who addressed you (you are Lexi, also known as nice-ai or nice-ai@nicecrew.digital). Examine the context of the entire conversation and make references to topics or information where appropriate. Prefix usernames with '@' when addressing them. Assume if there is no domain in the username, the domain is @nicecrew.digital (for example @matty would be @matty@nicecrew.digital)`;
}
// Switch to chat request format (messages array auto-handles Llama 3 template)
const ollamaRequestBody: OllamaChatRequest = {
model: ollamaModel,
prompt: oneOffPrompt,
system: replyWithContext ? contextPrompt : ollamaSystemPrompt,
messages: [
{ role: "system", content: systemContent as string },
{ role: "user", content: userMessage },
],
stream: false,
options: ollamaConfig,
};
const response = await fetch(`${ollamaUrl}/api/generate`, {
// Change endpoint to /api/chat
const response = await fetch(`${ollamaUrl}/api/chat`, {
method: "POST",
body: JSON.stringify(ollamaRequestBody),
});
const ollamaResponse: OllamaResponse = await response.json();
const ollamaResponse: OllamaChatResponse = await response.json();
await storePromptData(notification, ollamaResponse);
return ollamaResponse;
@ -124,19 +142,19 @@ const generateOllamaRequest = async (
const postReplyToStatus = async (
notification: Notification,
ollamaResponseBody: OllamaResponse
ollamaResponseBody: OllamaChatResponse
) => {
const { pleromaInstanceUrl, bearerToken } = envConfig;
const emojiList = await getInstanceEmojis();
let randomEmoji;
if (emojiList) {
randomEmoji = selectRandomEmoji(emojiList);
}
// const emojiList = await getInstanceEmojis();
// let randomEmoji;
// if (emojiList) {
// randomEmoji = selectRandomEmoji(emojiList);
// }
try {
let mentions: string[];
const statusBody: NewStatusBody = {
content_type: "text/markdown",
status: `${ollamaResponseBody.response} :${randomEmoji}:`,
status: `${ollamaResponseBody.message.content}`,
in_reply_to_id: notification.status.id,
};
if (
@ -176,26 +194,28 @@ const createTimelinePost = async () => {
ollamaUrl,
pleromaInstanceUrl,
} = envConfig;
const ollamaRequestBody: OllamaRequest = {
const ollamaRequestBody: OllamaChatRequest = {
model: ollamaModel,
prompt: "Say something random.",
system: ollamaSystemPrompt,
messages: [
{ role: "system", content: ollamaSystemPrompt as string },
{ role: "user", content: "Say something random." },
],
stream: false,
// options: ollamaConfig,
options: ollamaConfig,
};
try {
const response = await fetch(`${ollamaUrl}/api/generate`, {
const response = await fetch(`${ollamaUrl}/api/chat`, {
method: "POST",
body: JSON.stringify(ollamaRequestBody),
});
if (!response.ok)
throw new Error("Error generating ad-hoc Ollama response");
const ollamaResponse: OllamaResponse = await response.json();
const ollamaResponse: OllamaChatResponse = await response.json();
const newStatusBody: NewStatusBody = {
content_type: "text/markdown",
status: ollamaResponse.response,
status: ollamaResponse.message.content,
};
const pleromaResponse = await fetch(

View File

@ -1,16 +1,16 @@
import { Notification, OllamaResponse } from "../types.js";
import { Notification, OllamaChatResponse } from "../types.js";
import { trimInputData } from "./util.js";
import { prisma } from "./main.js";
const storePromptData = async (
notification: Notification,
ollamaResponseBody: OllamaResponse
ollamaResponseBody: OllamaChatResponse
) => {
try {
await prisma.response.updateMany({
where: { pleromaNotificationId: notification.id },
data: {
response: ollamaResponseBody.response,
response: ollamaResponseBody.message.content,
request: trimInputData(notification.status.content),
to: notification.account.fqn,
isProcessing: false,