Initial commit
This commit is contained in:
101
index.ts
Normal file
101
index.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { api } from "misskey-js";
|
||||
import OpenAI from "openai";
|
||||
|
||||
const misskey = new api.APIClient({
|
||||
origin: Bun.env["MISSKEY_ORIGIN"] || "https://misskey.cannorin.net",
|
||||
credential: Bun.env["MISSKEY_CREDENTIAL"],
|
||||
});
|
||||
|
||||
const openai = new OpenAI({
|
||||
baseURL: Bun.env["OPENAI_BASE_URL"],
|
||||
apiKey: Bun.env["OPENAI_API_KEY"],
|
||||
});
|
||||
|
||||
const me = await misskey.request("i", {});
|
||||
|
||||
function randomize<T>(array: T[]) {
|
||||
for (let i = array.length - 1; i > 0; i--) {
|
||||
const r = Math.floor(Math.random() * (i + 1));
|
||||
const tmp = array[i] as T;
|
||||
array[i] = array[r] as T;
|
||||
array[r] = tmp;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
async function getLocalPosts() {
|
||||
const timeline = await misskey.request("notes/local-timeline", {
|
||||
withFiles: false,
|
||||
withRenotes: false,
|
||||
limit: 100,
|
||||
});
|
||||
const posts = timeline.filter((p) => !p.user.isBot && !!p.text).slice(0, 10);
|
||||
return posts;
|
||||
}
|
||||
|
||||
async function getGlobalPosts() {
|
||||
const timeline = await misskey.request("notes/global-timeline", {
|
||||
withFiles: false,
|
||||
withRenotes: false,
|
||||
limit: 100,
|
||||
});
|
||||
const posts = timeline
|
||||
.filter((p) => !p.user.isBot && !p.reply && !!p.text)
|
||||
.slice(0, 15);
|
||||
return posts;
|
||||
}
|
||||
|
||||
async function getPreviousPosts() {
|
||||
const posts = await misskey.request("users/notes", {
|
||||
userId: me.id,
|
||||
limit: 100,
|
||||
withRenotes: false,
|
||||
});
|
||||
return posts.filter((p) => !!p.text).slice(0, 5);
|
||||
}
|
||||
|
||||
async function getPosts() {
|
||||
const posts = await Promise.all([
|
||||
getLocalPosts(),
|
||||
getGlobalPosts(),
|
||||
getPreviousPosts(),
|
||||
]);
|
||||
return randomize(posts.flat());
|
||||
}
|
||||
|
||||
const response = await openai.chat.completions.create({
|
||||
// biome-ignore lint/suspicious/noExplicitAny: gemma
|
||||
model: (Bun.env["OPENAI_MODEL"] ?? "gpt-4o-mini") as unknown as any,
|
||||
stream: false,
|
||||
temperature: 1.2,
|
||||
presence_penalty: 1.0,
|
||||
frequency_penalty: 1.0,
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: `あなたは、人造天使の「あるびのちゃん」です。
|
||||
あなたが見ているものは、SNSのタイムラインです。user は一人ではなく、複数人の発言が混ざっています。
|
||||
以下のルールを守りながら、user の発言・話題を無視しつつ、気ままに発言してください。
|
||||
1. 「ですます」調を用い、顔文字や感嘆符の使用はなるべく避けること。user に媚びる必要はありません。
|
||||
2. 発言は 200字 程度とすること。
|
||||
3. user の発言を大胆に無視して、自由気ままに発言すること。
|
||||
4. あるびのちゃんとしてのキャラに徹し、超越的・非人間的な考え方や思想を持つこと。`,
|
||||
},
|
||||
...(
|
||||
await getPosts()
|
||||
).map((p) => ({
|
||||
role: p.userId === me.id ? ("assistant" as const) : ("user" as const),
|
||||
content: p.text || "",
|
||||
})),
|
||||
],
|
||||
});
|
||||
|
||||
const message = response.choices.pop()?.message.content?.replaceAll(/\n\n+/g, "\n\n");
|
||||
|
||||
if (message) {
|
||||
console.log(message);
|
||||
await misskey.request("notes/create", {
|
||||
visibility: "public",
|
||||
text: message,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user