Compare commits
20 Commits
add-websoc
...
d4ee457d74
Author | SHA1 | Date | |
---|---|---|---|
d4ee457d74 | |||
b8f6023029 | |||
ea5e783ee5 | |||
eb5282a50d | |||
9ee3663890 | |||
d85acd2179 | |||
856cc84208 | |||
ca4643092f | |||
b4b656f808 | |||
92f1366574 | |||
a64afa7e7b | |||
d63aa365e7 | |||
3759c5aa23 | |||
1a151b197b | |||
70180c5d5f | |||
dac037809c | |||
6088a2cbd3 | |||
ed8d148d0a | |||
379099dc7a | |||
c0ed38ac1a |
@ -5,5 +5,5 @@ ONLY_LOCAL_REPLIES="true" # reply to only users locally on your instance
|
|||||||
OLLAMA_URL="http://localhost:11434" # OLLAMA connection URL
|
OLLAMA_URL="http://localhost:11434" # OLLAMA connection URL
|
||||||
OLLAMA_SYSTEM_PROMPT="" # system prompt - used to help tune the responses from the AI
|
OLLAMA_SYSTEM_PROMPT="" # system prompt - used to help tune the responses from the AI
|
||||||
OLLAMA_MODEL="" # Ollama model for responses e.g dolphin-mistral:latest
|
OLLAMA_MODEL="" # Ollama model for responses e.g dolphin-mistral:latest
|
||||||
INSTANCE_BEARER_TOKEN="" # instance auth/bearer token (check the "verify_credentials" endpoint request headers in Chrome DevTools if on Soapbox)
|
FETCH_INTERVAL="" # interval for fetching new notifications from the instance, in milliseconds, recommend at least 15000
|
||||||
SOAPBOX_WS_PROTOCOL="" # this is the header required to authenticate to the websocket. No idea why Soapbox does it like this. You can get it in the request headers for the socket in Chrome DevTools
|
INSTANCE_BEARER_TOKEN="" # instance auth/bearer token (check the "verify_credentials" endpoint request headers in Chrome DevTools if on Soapbox)
|
10
README.md
10
README.md
@ -1,15 +1,15 @@
|
|||||||
## Pleroma -> Ollama Bot Setup
|
## Pleroma -> Ollama Bot Setup
|
||||||
|
|
||||||
1. Clone project
|
1. Clone project
|
||||||
2. Install npm 22.11.0 if you don't have it already
|
2. Install Node `v22.11.0` if you don't have it already
|
||||||
|
* If using `nvm`, just `nvm install 22.11.0` and then `nvm use 22.11.0` if necessary
|
||||||
3. `cd` into the project directory
|
3. `cd` into the project directory
|
||||||
4. Run `npm install`
|
4. Run `npm install`
|
||||||
6. Run `npx prisma migrate dev --name init`
|
6. Run `npx prisma migrate dev --name init`
|
||||||
7. To run the software on a cronjob, use `npm run once`
|
7. To start, run `npm run start`
|
||||||
8. To run continuously, use `npm run ws`
|
|
||||||
|
I recommend using `screen` to run this in the background until a `systemd` service can be created. I just haven't bothered to do it yet.
|
||||||
|
|
||||||
### Database Migrations
|
### Database Migrations
|
||||||
|
|
||||||
If you add stuff to the schema, follow the [Prisma development workflow](https://www.prisma.io/docs/orm/prisma-migrate/workflows/development-and-production). This will apply the new schema to the database and generate a new Prisma client with type safety.
|
If you add stuff to the schema, follow the [Prisma development workflow](https://www.prisma.io/docs/orm/prisma-migrate/workflows/development-and-production). This will apply the new schema to the database and generate a new Prisma client with type safety.
|
||||||
|
|
||||||
Setting as a system service will come at some point, or someone could contribute if they wanted.
|
|
24
package-lock.json
generated
24
package-lock.json
generated
@ -13,8 +13,7 @@
|
|||||||
"dotenv": "^17.0.0",
|
"dotenv": "^17.0.0",
|
||||||
"striptags": "^3.2.0",
|
"striptags": "^3.2.0",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.8.3",
|
"typescript": "^5.8.3"
|
||||||
"ws": "^8.18.3"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/ws": "^8.18.1",
|
"@types/ws": "^8.18.1",
|
||||||
@ -356,27 +355,6 @@
|
|||||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/ws": {
|
|
||||||
"version": "8.18.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
|
||||||
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"bufferutil": "^4.0.1",
|
|
||||||
"utf-8-validate": ">=5.0.2"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"bufferutil": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"utf-8-validate": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/yn": {
|
"node_modules/yn": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pleroma-ollama-bot",
|
"name": "pleroma-ollama-bot",
|
||||||
"version": "1.0.0",
|
"version": "1.0.5",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "tsc && node -r dotenv/config dist/main.js",
|
"start": "tsc && node -r dotenv/config dist/main.js",
|
||||||
@ -16,8 +16,7 @@
|
|||||||
"dotenv": "^17.0.0",
|
"dotenv": "^17.0.0",
|
||||||
"striptags": "^3.2.0",
|
"striptags": "^3.2.0",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.8.3",
|
"typescript": "^5.8.3"
|
||||||
"ws": "^8.18.3"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/ws": "^8.18.1",
|
"@types/ws": "^8.18.1",
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
-- RedefineTables
|
||||||
|
PRAGMA defer_foreign_keys=ON;
|
||||||
|
PRAGMA foreign_keys=OFF;
|
||||||
|
CREATE TABLE "new_Response" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
"pleromaNotificationId" TEXT NOT NULL DEFAULT 'null',
|
||||||
|
"to" TEXT NOT NULL,
|
||||||
|
"request" TEXT,
|
||||||
|
"response" TEXT,
|
||||||
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"processedAt" DATETIME,
|
||||||
|
"isProcessing" BOOLEAN NOT NULL DEFAULT true
|
||||||
|
);
|
||||||
|
INSERT INTO "new_Response" ("createdAt", "id", "pleromaNotificationId", "processedAt", "request", "response", "to") SELECT "createdAt", "id", "pleromaNotificationId", "processedAt", "request", "response", "to" FROM "Response";
|
||||||
|
DROP TABLE "Response";
|
||||||
|
ALTER TABLE "new_Response" RENAME TO "Response";
|
||||||
|
PRAGMA foreign_keys=ON;
|
||||||
|
PRAGMA defer_foreign_keys=OFF;
|
@ -0,0 +1,18 @@
|
|||||||
|
-- RedefineTables
|
||||||
|
PRAGMA defer_foreign_keys=ON;
|
||||||
|
PRAGMA foreign_keys=OFF;
|
||||||
|
CREATE TABLE "new_Response" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
"pleromaNotificationId" TEXT NOT NULL DEFAULT 'null',
|
||||||
|
"to" TEXT NOT NULL DEFAULT 'null',
|
||||||
|
"request" TEXT NOT NULL DEFAULT 'null',
|
||||||
|
"response" TEXT NOT NULL DEFAULT 'null',
|
||||||
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"processedAt" DATETIME,
|
||||||
|
"isProcessing" BOOLEAN NOT NULL DEFAULT true
|
||||||
|
);
|
||||||
|
INSERT INTO "new_Response" ("createdAt", "id", "isProcessing", "pleromaNotificationId", "processedAt", "request", "response", "to") SELECT "createdAt", "id", "isProcessing", "pleromaNotificationId", "processedAt", coalesce("request", 'null') AS "request", coalesce("response", 'null') AS "response", "to" FROM "Response";
|
||||||
|
DROP TABLE "Response";
|
||||||
|
ALTER TABLE "new_Response" RENAME TO "Response";
|
||||||
|
PRAGMA foreign_keys=ON;
|
||||||
|
PRAGMA defer_foreign_keys=OFF;
|
@ -14,11 +14,12 @@ datasource db {
|
|||||||
model Response {
|
model Response {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
pleromaNotificationId String @default("null")
|
pleromaNotificationId String @default("null")
|
||||||
to String
|
to String @default("null")
|
||||||
request String?
|
request String @default("null")
|
||||||
response String?
|
response String @default("null")
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
processedAt DateTime?
|
processedAt DateTime?
|
||||||
|
isProcessing Boolean @default(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
model User {
|
model User {
|
||||||
|
159
src/main.ts
159
src/main.ts
@ -3,35 +3,32 @@ import {
|
|||||||
OllamaResponse,
|
OllamaResponse,
|
||||||
NewStatusBody,
|
NewStatusBody,
|
||||||
Notification,
|
Notification,
|
||||||
WSEvent,
|
OllamaConfigOptions,
|
||||||
} from "../types.js";
|
} from "../types.js";
|
||||||
import striptags from "striptags";
|
import striptags from "striptags";
|
||||||
import { PrismaClient } from "../generated/prisma/client.js";
|
import { PrismaClient } from "../generated/prisma/client.js";
|
||||||
import { createWebsocket } from "./websocket.js";
|
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
// const getNotifications = async () => {
|
const getNotifications = async () => {
|
||||||
// try {
|
try {
|
||||||
// const request = await fetch(
|
const request = await fetch(
|
||||||
// `${process.env.PLEROMA_INSTANCE_URL}/api/v1/notifications?types[]=mention`,
|
`${process.env.PLEROMA_INSTANCE_URL}/api/v1/notifications?types[]=mention`,
|
||||||
// {
|
{
|
||||||
// method: "GET",
|
method: "GET",
|
||||||
// headers: {
|
headers: {
|
||||||
// Authorization: `Bearer ${process.env.INSTANCE_BEARER_TOKEN}`,
|
Authorization: `Bearer ${process.env.INSTANCE_BEARER_TOKEN}`,
|
||||||
// },
|
},
|
||||||
// }
|
}
|
||||||
// );
|
);
|
||||||
|
|
||||||
// const notifications: Notification[] = await request.json();
|
const notifications: Notification[] = await request.json();
|
||||||
|
|
||||||
// return notifications;
|
return notifications;
|
||||||
// } catch (error: any) {
|
} catch (error: any) {
|
||||||
// throw new Error(error.message);
|
throw new Error(error.message);
|
||||||
// }
|
}
|
||||||
// };
|
};
|
||||||
|
|
||||||
// const notifications = await getNotifications();
|
|
||||||
|
|
||||||
const storeUserData = async (notification: Notification): Promise<void> => {
|
const storeUserData = async (notification: Notification): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
@ -55,7 +52,7 @@ const alreadyRespondedTo = async (
|
|||||||
): Promise<boolean> => {
|
): Promise<boolean> => {
|
||||||
try {
|
try {
|
||||||
const duplicate = await prisma.response.findFirst({
|
const duplicate = await prisma.response.findFirst({
|
||||||
where: { pleromaNotificationId: notification.status.id },
|
where: { pleromaNotificationId: notification.id, isProcessing: true },
|
||||||
});
|
});
|
||||||
if (duplicate) {
|
if (duplicate) {
|
||||||
return true;
|
return true;
|
||||||
@ -71,12 +68,13 @@ const storePromptData = async (
|
|||||||
ollamaResponseBody: OllamaResponse
|
ollamaResponseBody: OllamaResponse
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
await prisma.response.create({
|
await prisma.response.updateMany({
|
||||||
|
where: { pleromaNotificationId: notification.id },
|
||||||
data: {
|
data: {
|
||||||
response: ollamaResponseBody.response,
|
response: ollamaResponseBody.response,
|
||||||
request: striptags(notification.status.content),
|
request: trimInputData(notification.status.content),
|
||||||
to: notification.account.fqn,
|
to: notification.account.fqn,
|
||||||
pleromaNotificationId: notification.status.id,
|
isProcessing: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@ -91,13 +89,26 @@ const trimInputData = (input: string) => {
|
|||||||
return split.slice(promptStringIndex + 1).join(" "); // returns everything after the !prompt
|
return split.slice(promptStringIndex + 1).join(" "); // returns everything after the !prompt
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const recordPendingResponse = async (notification: Notification) => {
|
||||||
|
try {
|
||||||
|
await prisma.response.create({
|
||||||
|
data: {
|
||||||
|
pleromaNotificationId: notification.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error: any) {
|
||||||
|
throw new Error(error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const generateOllamaRequest = async (
|
const generateOllamaRequest = async (
|
||||||
notification: Notification
|
notification: Notification
|
||||||
): Promise<OllamaResponse | undefined> => {
|
): Promise<OllamaResponse | undefined> => {
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
striptags(notification.status.content).includes("!prompt") &&
|
striptags(notification.status.content).includes("!prompt") &&
|
||||||
!notification.status.account.bot
|
!notification.status.account.bot && // sanity check, sort of
|
||||||
|
notification.type === "mention"
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
process.env.ONLY_LOCAL_REPLIES === "true" &&
|
process.env.ONLY_LOCAL_REPLIES === "true" &&
|
||||||
@ -110,7 +121,12 @@ const generateOllamaRequest = async (
|
|||||||
if (await alreadyRespondedTo(notification)) {
|
if (await alreadyRespondedTo(notification)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
await recordPendingResponse(notification);
|
||||||
await storeUserData(notification);
|
await storeUserData(notification);
|
||||||
|
const ollamaConfig: OllamaConfigOptions = {
|
||||||
|
temperature: 1.2,
|
||||||
|
num_predict: 400,
|
||||||
|
};
|
||||||
const ollamaRequestBody: OllamaRequest = {
|
const ollamaRequestBody: OllamaRequest = {
|
||||||
model: process.env.OLLAMA_MODEL as string,
|
model: process.env.OLLAMA_MODEL as string,
|
||||||
system: process.env.OLLAMA_SYSTEM_PROMPT as string,
|
system: process.env.OLLAMA_SYSTEM_PROMPT as string,
|
||||||
@ -118,6 +134,7 @@ const generateOllamaRequest = async (
|
|||||||
notification.status.content
|
notification.status.content
|
||||||
)}`,
|
)}`,
|
||||||
stream: false,
|
stream: false,
|
||||||
|
options: ollamaConfig,
|
||||||
};
|
};
|
||||||
const response = await fetch(`${process.env.OLLAMA_URL}/api/generate`, {
|
const response = await fetch(`${process.env.OLLAMA_URL}/api/generate`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@ -168,40 +185,70 @@ const postReplyToStatus = async (
|
|||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`New status request failed: ${response.statusText}`);
|
throw new Error(`New status request failed: ${response.statusText}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await deleteNotification(notification);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
throw new Error(error.message);
|
throw new Error(error.message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const ws = createWebsocket();
|
const deleteNotification = async (notification: Notification) => {
|
||||||
|
try {
|
||||||
ws.on("upgrade", () => {
|
if (!notification.id) {
|
||||||
console.log(
|
return;
|
||||||
`Websocket connection to ${process.env.PLEROMA_INSTANCE_DOMAIN} successful.`
|
}
|
||||||
);
|
await prisma.response.updateMany({
|
||||||
});
|
// this is probably not the best way to do this, but since we may have duplicate notifications, we have to update all of them - probably won't scale (lmao)
|
||||||
|
where: { pleromaNotificationId: notification.id },
|
||||||
ws.on("message", async (data) => {
|
data: { isProcessing: false },
|
||||||
const message: WSEvent = JSON.parse(data.toString("utf-8"));
|
});
|
||||||
if (message.event !== "notification") {
|
const response = await fetch(
|
||||||
// only watch for notification events
|
`${process.env.PLEROMA_INSTANCE_URL}/api/v1/notifications/${notification.id}/dismiss`,
|
||||||
return;
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${process.env.INSTANCE_BEARER_TOKEN}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (!response.ok) {
|
||||||
|
console.error(
|
||||||
|
`Could not delete notification ID: ${notification.id}\nReason: ${response.status} - ${response.statusText}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
throw new Error(error.message);
|
||||||
}
|
}
|
||||||
console.log("Websocket message received.");
|
};
|
||||||
const payload = JSON.parse(message.payload) as Notification;
|
|
||||||
const ollamaResponse = await generateOllamaRequest(payload);
|
|
||||||
if (ollamaResponse) {
|
|
||||||
await postReplyToStatus(payload, ollamaResponse);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// if (notifications) {
|
const fetchInterval = process.env.FETCH_INTERVAL
|
||||||
// await Promise.all(
|
? parseInt(process.env.FETCH_INTERVAL)
|
||||||
// notifications.map(async (notification) => {
|
: 15000;
|
||||||
// const ollamaResponse = await generateOllamaRequest(notification);
|
|
||||||
// if (ollamaResponse) {
|
let notifications = [];
|
||||||
// postReplyToStatus(notification, ollamaResponse);
|
const beginFetchCycle = async () => {
|
||||||
// }
|
setInterval(async () => {
|
||||||
// })
|
notifications = await getNotifications();
|
||||||
// );
|
if (notifications.length > 0) {
|
||||||
// }
|
await Promise.all(
|
||||||
|
notifications.map(async (notification) => {
|
||||||
|
try {
|
||||||
|
const ollamaResponse = await generateOllamaRequest(notification);
|
||||||
|
if (ollamaResponse) {
|
||||||
|
postReplyToStatus(notification, ollamaResponse);
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
throw new Error(error.message);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, fetchInterval); // lower intervals may cause the bot to respond multiple times to the same message, but we try to mitigate this with the deleteNotification function
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`Fetching notifications from ${process.env.PLEROMA_INSTANCE_DOMAIN}, every ${
|
||||||
|
fetchInterval / 1000
|
||||||
|
} seconds.`
|
||||||
|
);
|
||||||
|
await beginFetchCycle();
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
import { WebSocket } from "ws";
|
|
||||||
|
|
||||||
const scheme = process.env.PLEROMA_INSTANCE_URL?.startsWith("https")
|
|
||||||
? "wss"
|
|
||||||
: "ws"; // this is so nigger rigged
|
|
||||||
const host = process.env.PLEROMA_INSTANCE_DOMAIN;
|
|
||||||
|
|
||||||
export const createWebsocket = (): WebSocket => {
|
|
||||||
try {
|
|
||||||
const ws = new WebSocket( // only connects to Soapbox frontends right now, but could pretty easily connect to Pleroma frontends with some tweaking
|
|
||||||
`${scheme}://${host}/api/v1/streaming?stream=user`,
|
|
||||||
[process.env.SOAPBOX_WS_PROTOCOL as string],
|
|
||||||
{
|
|
||||||
followRedirects: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return ws;
|
|
||||||
} catch (error: any) {
|
|
||||||
throw new Error(error);
|
|
||||||
}
|
|
||||||
};
|
|
52
types.d.ts
vendored
52
types.d.ts
vendored
@ -1,6 +1,9 @@
|
|||||||
export interface Notification {
|
export interface Notification {
|
||||||
account: Account;
|
account: Account;
|
||||||
status: Status;
|
status: Status;
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
created_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NewStatusBody {
|
export interface NewStatusBody {
|
||||||
@ -38,6 +41,7 @@ export interface OllamaRequest {
|
|||||||
* Whether to stream responses from the API, or have it sent all as one payload.
|
* Whether to stream responses from the API, or have it sent all as one payload.
|
||||||
*/
|
*/
|
||||||
stream?: boolean = false; // stream response vs get response in one full message
|
stream?: boolean = false; // stream response vs get response in one full message
|
||||||
|
options?: OllamaConfigOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OllamaResponse {
|
export interface OllamaResponse {
|
||||||
@ -65,8 +69,48 @@ export interface Mention {
|
|||||||
username: string;
|
username: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WSEvent {
|
/**
|
||||||
event: "update" | "status.update" | "notification";
|
* Experimental settings, I wouldn't recommend messing with these if you don't know how they work (I don't either)
|
||||||
payload: string;
|
*/
|
||||||
stream: "user" | "direct";
|
export interface OllamaConfigOptions {
|
||||||
|
/**
|
||||||
|
* Number of tokens guaranteed to be kept in memory during response generation. Higher values leave less
|
||||||
|
* possible room for num_ctx
|
||||||
|
*/
|
||||||
|
num_keep?: number;
|
||||||
|
seed?: number;
|
||||||
|
/**
|
||||||
|
* Sets maximum of tokens in the response
|
||||||
|
*/
|
||||||
|
num_predict?: number;
|
||||||
|
top_k?: number;
|
||||||
|
top_p?: number;
|
||||||
|
min_p?: number;
|
||||||
|
typical_p?: number;
|
||||||
|
repeat_last_n?: number;
|
||||||
|
/**
|
||||||
|
* How close of a response should the response be to the original prompt - lower = more focused response
|
||||||
|
*/
|
||||||
|
temperature?: number;
|
||||||
|
repeat_penalty?: number;
|
||||||
|
presence_penalty?: number;
|
||||||
|
frequency_penalty?: number;
|
||||||
|
mirostat?: number;
|
||||||
|
mirostat_tau?: number;
|
||||||
|
mirostat_eta?: number;
|
||||||
|
penalize_newline?: boolean;
|
||||||
|
stop?: string[];
|
||||||
|
numa?: boolean;
|
||||||
|
/**
|
||||||
|
* Number of tokens for the prompt to keep in memory for the response, minus the value of num_keep
|
||||||
|
*/
|
||||||
|
num_ctx?: number;
|
||||||
|
num_batch?: number;
|
||||||
|
num_gpu?: number;
|
||||||
|
main_gpu?: number;
|
||||||
|
low_vram?: boolean;
|
||||||
|
vocab_only?: boolean;
|
||||||
|
use_mmap?: boolean;
|
||||||
|
use_mlock?: boolean;
|
||||||
|
num_thread?: number;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user