misc: temp commits (a lot of mass)

This commit is contained in:
WJG 2024-01-26 02:06:22 +08:00
parent 3d472763c1
commit 9b79881c53
No known key found for this signature in database
GPG Key ID: 258474EF8590014A
21 changed files with 987 additions and 23 deletions

View File

@ -1,3 +1,5 @@
MI_USER="Xiaomi Account"
MI_PASS="Account Password"
MI_DID="Device ID or Name (optional - fill in after retrieving from the device list)"
MI_DID="Device ID or Name (optional - fill in after retrieving from the device list)"
OPENAI_MODEL=gpt-4-turbo-1106
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxx

3
.gitignore vendored
View File

@ -3,4 +3,5 @@ dist
.DS_Store
.yarn
.env
.mi.json
.mi.json
*.db*

View File

@ -20,5 +20,8 @@
"files.exclude": {
"**/.git": true,
"**/node_modules": true
},
"[prisma]": {
"editor.defaultFormatter": "Prisma.prisma"
}
}

View File

@ -20,10 +20,15 @@
],
"scripts": {
"build": "tsup",
"db:gen": "npx prisma generate",
"db:reset": "npx prisma migrate reset",
"prepublish": "npm run build"
},
"dependencies": {
"axios": "^1.6.5"
"@prisma/client": "^5.8.1",
"axios": "^1.6.5",
"openai": "^4.25.0",
"prisma": "^5.8.1"
},
"devDependencies": {
"@types/node": "^20.4.9",

76
prisma/schema.prisma Normal file
View File

@ -0,0 +1,76 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = "file:./hello.db"
}
model User {
id String @id @default(uuid())
name String
profile String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
messages Message[]
memories Memory[]
shortTermMemories ShortTermMemory[]
longTermMemories LongTermMemory[]
}
model Message {
id Int @id @default(autoincrement())
text String
// 消息发送者
sender User @relation(fields: [senderId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
senderId String
}
model Memory {
id Int @id @default(autoincrement())
// 记忆拥有者
owner User @relation(fields: [ownerId], references: [id])
// 记忆类型:目前有 [ "message" ]
type String
// 记忆内容JSON字符串{ data: any }
content String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
ownerId String
shortTermMemories ShortTermMemory[]
}
model ShortTermMemory {
id Int @id @default(autoincrement())
// 记忆拥有者
owner User @relation(fields: [ownerId], references: [id])
// 记忆最后更新的位置
cursor Memory @relation(fields: [cursorId], references: [id])
// 记忆内容:字符串
content String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
ownerId String
cursorId Int
longTermMemories LongTermMemory[]
}
model LongTermMemory {
id Int @id @default(autoincrement())
// 记忆拥有者
owner User @relation(fields: [ownerId], references: [id])
// 记忆最后更新的位置
cursor ShortTermMemory @relation(fields: [cursorId], references: [id])
// 记忆内容:字符串
content String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
ownerId String
cursorId Int
}

View File

@ -1,4 +1,9 @@
import { runWithDB } from "./services/db";
import { println } from "./utils/base";
import { kBannerASCII } from "./utils/string";
// todo
println("hello world!");
async function main() {
println(kBannerASCII);
}
runWithDB(main);

132
src/services/bot/bot.ts Normal file
View File

@ -0,0 +1,132 @@
import { User } from "@prisma/client";
import { jsonDecode, jsonEncode } from "../../utils/base";
import { buildPrompt, toUTC8Time } from "../../utils/string";
import { openai } from "../openai";
import { kPrisma } from "../db";
const systemTemplate = `
{{name}}
{{name}}
<profile>
{{profile}}
</profile>
{{wechatName}}{{wechatName}}{{wechatAlias}}
<history>
{{history}}
<history>
<contexts>
{{contexts}}
</contexts>
{{name}}
- {{name}}
- {{name}}仿
-
-
- {{name}}
JSON格式回复
{ message: "回复的消息内容" }
`.trim();
const userTemplate = `
{{message}}
`.trim();
export interface IPerson {
/**
*
*/
name: string;
/**
*
*/
profile: string;
}
export class MyBot {
private users: Record<string, User | undefined> = {
bot: undefined,
// 主人的个人信息
master: undefined,
};
constructor(config: { bot: IPerson; master: IPerson }) {
this.createOrUpdateUser("bot", config.bot);
this.createOrUpdateUser("master", config.master);
}
async ask(msg: string) {
const { bot, master } = this.users;
if (!bot || !master) {
console.error("❌ ask bot failed", bot, master);
return undefined;
}
const botMemory = new UserMemory(bot);
const result = await openai.chat({
system: buildPrompt(systemTemplate, {
bot_name: this.bot.name,
bot_profile: this.bot.profile,
master_name: this.master.name,
master_profile: this.master.profile,
history:
lastMessages.length < 1
? "暂无"
: lastMessages
.map((e) =>
jsonEncode({
time: toUTC8Time(e.createdAt),
user: e.user.name,
message: e.text,
})
)
.join("\n"),
}),
user: buildPrompt(userTemplate, {
message: jsonEncode({
time: toUTC8Time(new Date()),
user: this.master.name,
message: msg,
})!,
}),
tools: [
{
type: "function",
function: {
name: "reply",
description: "回复一条消息",
parameters: {
type: "object",
properties: {
message: { type: "string", description: "回复的消息内容" },
},
},
},
},
],
});
return jsonDecode(result?.content)?.message;
}
private async createOrUpdateUser(type: "bot" | "master", user: IPerson) {
this.users[type] = await kPrisma.user
.upsert({
where: { id: this.users[type]?.id },
create: user,
update: user,
})
.catch((e) => {
console.error("❌ update user failed", type, user, e);
return undefined;
});
}
}

View File

@ -0,0 +1,154 @@
import { kPrisma } from "../../db";
import { Memory, Message, User } from "@prisma/client";
import { jsonDecode, jsonEncode, lastOf } from "../../../utils/base";
import { ShortTermMemory } from "./short-term";
import { LongTermMemory } from "./long-term";
// todo 在会话中,向会话的参与者分发消息(记忆),公共记忆,个人记忆
export class UserMemory {
private user: User;
constructor(user: User) {
this.user = user;
}
async getRelatedMemories(limit: number): Promise<Memory[]> {
// todo search memory embeddings
return [];
}
async count(options?: { cursor?: Memory; ownerId?: "all" | string }) {
const { cursor, ownerId = this.user.id } = options ?? {};
return kPrisma.memory
.count({
where: {
ownerId: ownerId.toLowerCase() === "all" ? undefined : ownerId,
id: {
gt: cursor?.id,
},
},
})
.catch((e) => {
console.error("❌ get memory count failed", e);
return -1;
});
}
async gets(options?: {
ownerId?: "all" | string;
limit?: number;
offset?: number;
cursor?: Memory;
order?: "asc" | "desc";
}) {
const {
cursor,
limit = 10,
offset = 0,
order = "desc",
ownerId = this.user.id,
} = options ?? {};
const memories = await kPrisma.memory
.findMany({
cursor,
where: {
ownerId: ownerId.toLowerCase() === "all" ? undefined : ownerId,
},
take: limit,
skip: offset,
orderBy: { createdAt: order },
})
.catch((e) => {
console.error("❌ get memories failed", options, e);
return [];
});
const orderedMemories = order === "desc" ? memories.reverse() : memories;
return orderedMemories.map((e) => {
return { ...e, content: jsonDecode(e.content)!.data };
});
}
async add(message: Message) {
// todo create memory embedding
const data = {
ownerId: this.user.id,
type: "message",
content: jsonEncode({ data: message.text })!,
};
const memory = await kPrisma.memory.create({ data }).catch((e) => {
console.error("❌ add memory to db failed", data, e);
return undefined;
});
if (memory) {
// 异步更新
new ShortTermMemory(this.user).update(message, memory);
}
return memory;
}
}
export class MemoryHelper {
static async updateAndConnectRelations(config: {
user: User;
message?: Message;
memory?: Memory;
shortTermMemory?: ShortTermMemory;
longTermMemory?: LongTermMemory;
}) {
const { user, message, memory, shortTermMemory, longTermMemory } = config;
const connect = (key: any, value: any) => {
if (value) {
return {
[key]: {
connect: [{ id: value.id }],
},
};
}
return {};
};
await kPrisma.user
.update({
where: { id: user.id },
data: {
...connect("messages", message),
...connect("memories", memory),
...connect("shortTermMemories", shortTermMemory),
...connect("longTermMemories", longTermMemory),
},
})
.catch((e) => {
console.error("❌ updateAndConnectRelations failed: user", e);
});
if (memory && shortTermMemory) {
await kPrisma.memory
.update({
where: { id: memory.id },
data: {
shortTermMemories: {
connect: [{ id: shortTermMemory.id }],
},
},
})
.catch((e) => {
console.error("❌ updateAndConnectRelations failed: memory", e);
});
}
if (shortTermMemory && longTermMemory) {
await kPrisma.shortTermMemory
.update({
where: { id: shortTermMemory?.id },
data: {
longTermMemories: {
connect: [{ id: longTermMemory?.id }],
},
},
})
.catch((e) => {
console.error(
"❌ updateAndConnectRelations failed: shortTermMemory",
e
);
});
}
}
}

View File

@ -0,0 +1,67 @@
import { Memory, Message, User } from "@prisma/client";
import { kPrisma } from "../../db";
import { MemoryHelper, UserMemory } from "./base";
import { lastOf } from "../../../utils/base";
import { ShortTermMemory } from "./long-term";
export class LongTermMemory {
static async get(user: User) {
return kPrisma.longTermMemory
.findFirst({
include: { cursor: true },
where: { ownerId: user.id },
})
.catch((e) => {
console.error("❌ get long memory failed", user, e);
return undefined;
});
}
static async update(
user: User,
message: Message,
memory: Memory,
shortTermMemory: ShortTermMemory,
threshold = 10 // 每隔 10 条记忆更新一次短期记忆
) {
const current = await LongTermMemory.get(user);
const newMemories = await new ShortTermMemory(user).gets({
ownerId: "all",
cursor: current?.cursor,
order: "asc", // 从旧到新排序
});
if (newMemories.length < threshold) {
return undefined;
}
// todo update memory
const content = "todo";
const data = {
ownerId: user.id,
content,
cursorId: lastOf(newMemories)!.id,
};
// 直接插入新的长期记忆,不更新旧的长期记忆记录
const longTermMemory = await kPrisma.longTermMemory
.create({ data })
.catch((e) => {
console.error(
"❌ add or update longTermMemory failed",
current,
data,
e
);
return undefined;
});
if (longTermMemory) {
// 异步更新
MemoryHelper.updateAndConnectRelations({
user,
message,
memory,
shortTermMemory,
longTermMemory,
});
}
return memory;
}
}

View File

@ -0,0 +1,109 @@
import {
Memory,
Message,
User,
ShortTermMemory as _ShortTermMemory,
} from "@prisma/client";
import { kPrisma } from "../../db";
import { UserMemory } from "./base";
import { lastOf } from "../../../utils/base";
import { LongTermMemory } from "./long-term";
export class ShortTermMemory {
private user: User;
constructor(user: User) {
this.user = user;
}
async getRelatedMemories(limit: number): Promise<_ShortTermMemory[]> {
// todo search memory embeddings
return [];
}
async count(options?: {
cursor?: _ShortTermMemory;
ownerId?: "all" | string;
}) {
const { cursor, ownerId = this.user.id } = options ?? {};
return kPrisma.memory
.count({
where: {
ownerId: ownerId.toLowerCase() === "all" ? undefined : ownerId,
id: {
gt: cursor?.id,
},
},
})
.catch((e) => {
console.error("❌ get memory count failed", e);
return -1;
});
}
async get() {
return kPrisma.shortTermMemory
.findFirst({
include: { cursor: true },
where: { ownerId: this.user.id },
orderBy: { createdAt: "desc" },
})
.catch((e) => {
console.error("❌ get short memory failed", this.user, e);
return undefined;
});
}
async gets() {
return kPrisma.shortTermMemory
.findFirst({
include: { cursor: true },
where: { ownerId: this.user.id },
orderBy: { createdAt: "desc" },
})
.catch((e) => {
console.error("❌ get short memory failed", this.user, e);
return undefined;
});
}
async update(
message: Message,
memory: Memory,
threshold = 10 // 每隔 10 条记忆更新一次短期记忆
) {
const current = await this.get();
const newMemories = await new UserMemory(this.user).gets({
ownerId: "all",
cursor: current?.cursor,
order: "asc", // 从旧到新排序
});
if (newMemories.length < threshold) {
return undefined;
}
// todo update memory
const content = "todo";
const data = {
ownerId: this.user.id,
content,
cursorId: lastOf(newMemories)!.id,
};
// 直接插入新的短期记忆,不更新旧的短期记忆记录
const shortTermMemory = await kPrisma.shortTermMemory
.create({ data })
.catch((e) => {
console.error(
"❌ add or update shortTermMemory failed",
current,
data,
e
);
return undefined;
});
if (shortTermMemory) {
// 异步更新
LongTermMemory.update(this.user, message, memory, shortTermMemory);
}
return memory;
}
}

View File

@ -0,0 +1,83 @@
import { Message, User } from "@prisma/client";
import { kPrisma } from "../db";
import { UserMemory } from "./memory";
class _MessageHistory {
async count(options?: { cursor?: Message; sender?: User }) {
const { sender, cursor } = options ?? {};
return kPrisma.message
.count({
where: {
senderId: sender?.id,
id: {
gt: cursor?.id,
},
},
})
.catch((e) => {
console.error("❌ get msg count failed", e);
return -1;
});
}
/**
*
*/
async gets(options?: {
sender?: User;
limit?: number;
offset?: number;
cursor?: Message;
order?: "asc" | "desc";
}) {
const {
limit = 10,
offset = 0,
order = "desc",
sender,
cursor,
} = options ?? {};
const msgs = await kPrisma.message
.findMany({
cursor,
where: { senderId: sender?.id },
take: limit,
skip: offset,
orderBy: { createdAt: order },
})
.catch((e) => {
console.error("❌ get msgs failed", options, e);
return [];
});
return order === "desc" ? msgs.reverse() : msgs;
}
async addOrUpdate(
msg: Partial<Message> & {
text: string;
sender: User;
}
) {
const data = {
text: msg.text,
senderId: msg.sender?.id,
};
const message = await kPrisma.message
.upsert({
where: { id: msg.id },
create: data,
update: data,
})
.catch((e) => {
console.error("❌ add msg to db failed", msg, e);
return undefined;
});
if (message) {
// 异步更新记忆
new UserMemory(msg.sender).add(message);
}
return message;
}
}
export const MessageHistory = new _MessageHistory();

15
src/services/db.ts Normal file
View File

@ -0,0 +1,15 @@
import { PrismaClient } from "@prisma/client";
export const kPrisma = new PrismaClient();
export function runWithDB(main: () => Promise<void>) {
main()
.then(async () => {
await kPrisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await kPrisma.$disconnect();
process.exit(1);
});
}

View File

@ -1,5 +1,5 @@
import axios, { AxiosRequestConfig, CreateAxiosDefaults } from "axios";
import { isNotEmpty } from "./is";
import { isNotEmpty } from "../utils/is";
const _baseConfig: CreateAxiosDefaults = {
timeout: 10 * 1000,

36
src/services/openai.ts Normal file
View File

@ -0,0 +1,36 @@
import OpenAI from "openai";
import {
ChatCompletionMessageParam,
ChatCompletionTool,
} from "openai/resources";
import { kEnvs } from "../utils/env";
const client = new OpenAI({
apiKey: kEnvs.OPENAI_API_KEY!,
});
export const openai = {
async chat(options: {
user: string;
system?: string;
tools?: Array<ChatCompletionTool>;
jsonMode?: boolean;
}) {
const systemMsg: ChatCompletionMessageParam[] = options.system
? [{ role: "system", content: options.system }]
: [];
const chatCompletion = await client.chat.completions
.create({
tools: options.tools,
messages: [...systemMsg, { role: "user", content: options.user }],
model: kEnvs.OPENAI_MODEL ?? "gpt-3.5-turbo-1106",
response_format: options.jsonMode ? { type: "json_object" } : undefined,
})
.catch((e) => {
console.error("❌ openai chat failed", e);
return null;
});
return chatCompletion?.choices?.[0]?.message;
},
};

View File

@ -96,7 +96,7 @@ export function jsonEncode(obj: any, options?: { prettier?: boolean }) {
}
}
export function jsonDecode(json: string | undefined) {
export function jsonDecode(json: string | null | undefined) {
if (json == undefined) return undefined;
try {
return JSON.parse(json!);

7
src/utils/env.ts Normal file
View File

@ -0,0 +1,7 @@
export const kEnvs: Partial<{
MI_USER: string;
MI_PASS: string;
MI_DID: string;
OPENAI_MODEL: string;
OPENAI_API_KEY: string;
}> = process.env as any;

View File

@ -1,12 +1,10 @@
import * as fs from "fs";
import * as path from "path";
import { jsonDecode, jsonEncode } from "./json";
import { jsonDecode, jsonEncode } from "./base";
export const kRoot = process.cwd();
export const kEnvs = process.env as any;
export const exists = (filePath: string) => fs.existsSync(filePath);
export const deleteFile = (filePath: string) => {
@ -18,6 +16,14 @@ export const deleteFile = (filePath: string) => {
}
};
export const getFiles = (dir: string) => {
return new Promise<string[]>((resolve) => {
fs.readdir(dir, (err, files) => {
resolve(err ? [] : files);
});
});
};
export const readFile = <T = any>(
filePath: string,
options?: fs.WriteFileOptions
@ -33,6 +39,17 @@ export const readFile = <T = any>(
});
};
export const readFileSync = (
filePath: string,
options?: fs.WriteFileOptions
) => {
const dirname = path.dirname(filePath);
if (!fs.existsSync(dirname)) {
return undefined;
}
return fs.readFileSync(filePath, options);
};
export const writeFile = (
filePath: string,
data: string | NodeJS.ArrayBufferView,
@ -58,19 +75,17 @@ export const writeFile = (
export const readString = (filePath: string) =>
readFile<string>(filePath, "utf8");
export const readStringSync = (filePath: string) =>
readFileSync(filePath, "utf8")?.toString();
export const writeString = (filePath: string, content: string) =>
writeFile(filePath, content, "utf8");
export const readJSON = async (filePath: string) =>
jsonDecode(await readFile<string>(filePath, "utf8"));
jsonDecode(await readString(filePath));
export const readJSONSync = (filePath: string) =>
jsonDecode(readStringSync(filePath));
export const writeJSON = (filePath: string, content: any) =>
writeFile(filePath, jsonEncode(content) ?? "", "utf8");
export const getFiles = (dir: string) => {
return new Promise<string[]>((resolve) => {
fs.readdir(dir, (err, files) => {
resolve(err ? [] : files);
});
});
};

45
src/utils/string.ts Normal file
View File

@ -0,0 +1,45 @@
import { readJSONSync } from './io';
export const kVersion = readJSONSync('package.json').version;
export const kBannerASCII = `
/$$ /$$ /$$ /$$$$$$ /$$$$$$$ /$$$$$$$$
| $$$ /$$$|__/ /$$__ $$| $$__ $$|__ $$__/
| $$$$ /$$$$ /$$| $$ \__/| $$ \ $$ | $$
| $$ $$/$$ $$| $$| $$ /$$$$| $$$$$$$/ | $$
| $$ $$$| $$| $$| $$|_ $$| $$____/ | $$
| $$\ $ | $$| $$| $$ \ $$| $$ | $$
| $$ \/ | $$| $$| $$$$$$/| $$ | $$
|__/ |__/|__/ \______/ |__/ |__/
MiGPT v1.0.0 by: del-wang.eth
`.replace('1.0.0', kVersion);
/**
* 20231212 12:46
*/
export function toUTC8Time(date: Date) {
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
weekday: 'long',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false,
timeZone: 'Asia/Shanghai',
});
}
export function buildPrompt(
template: string,
variables: Record<string, string>
) {
for (const key in variables) {
const value = variables[key];
template = template.replaceAll(`{{${key}}}`, value);
}
return template;
}

View File

@ -1,9 +1,12 @@
import dotenv from "dotenv";
import { println } from "../src/utils/base";
import { kBannerASCII } from "../src/utils/string";
import { runWithDB } from "../src/services/db";
dotenv.config();
async function main() {
console.log("hello world!");
println(kBannerASCII);
}
main();
runWithDB(main);

View File

@ -8,6 +8,6 @@
"esModuleInterop": true,
"moduleResolution": "node"
},
"include": ["src"],
"exclude": ["node_modules"]
"include": ["src", "tests"],
"exclude": ["node_modules", "dist"]
}

206
yarn.lock
View File

@ -202,6 +202,47 @@
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
"@prisma/client@^5.8.1":
version "5.8.1"
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.8.1.tgz#7815ec51c0ca2a6de219c02e7846701ae3baf240"
integrity sha512-xQtMPfbIwLlbm0VVIVQY2yqQVOxPwRQhvIp7Z3m2900g1bu/zRHKhYZJQWELqmjl6d8YwBy0K2NvMqh47v1ubw==
"@prisma/debug@5.8.1":
version "5.8.1"
resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.8.1.tgz#704daa36919b0fc4d227260ecebfa1c94b155b07"
integrity sha512-tjuw7eA0Us3T42jx9AmAgL58rzwzpFGYc3R7Y4Ip75EBYrKMBA1YihuWMcBC92ILmjlQ/u3p8VxcIE0hr+fZfg==
"@prisma/engines-version@5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2":
version "5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2"
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2.tgz#f600a45afc4cf0c0356b6ed90add6050fa3f3239"
integrity sha512-f5C3JM3l9yhGr3cr4FMqWloFaSCpNpMi58Om22rjD2DOz3owci2mFdFXMgnAGazFPKrCbbEhcxdsRfspEYRoFQ==
"@prisma/engines@5.8.1":
version "5.8.1"
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.8.1.tgz#b850751f5bf7d5e570b9fe16cefdc2b1fd2c02c3"
integrity sha512-TJgYLRrZr56uhqcXO4GmP5be+zjCIHtLDK20Cnfg+o9d905hsN065QOL+3Z0zQAy6YD31Ol4u2kzSfRmbJv/uA==
dependencies:
"@prisma/debug" "5.8.1"
"@prisma/engines-version" "5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2"
"@prisma/fetch-engine" "5.8.1"
"@prisma/get-platform" "5.8.1"
"@prisma/fetch-engine@5.8.1":
version "5.8.1"
resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.8.1.tgz#38bb92f1fbd3669340a3cc49fce403ab4df671dd"
integrity sha512-+bgjjoSFa6uYEbAPlklfoVSStOEfcpheOjoBoNsNNSQdSzcwE2nM4Q0prun0+P8/0sCHo18JZ9xqa8gObvgOUw==
dependencies:
"@prisma/debug" "5.8.1"
"@prisma/engines-version" "5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2"
"@prisma/get-platform" "5.8.1"
"@prisma/get-platform@5.8.1":
version "5.8.1"
resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.8.1.tgz#8cd450b65a52a5a6ed5b2f52457136a492c0f251"
integrity sha512-wnA+6HTFcY+tkykMokix9GiAkaauPC5W/gg0O5JB0J8tCTNWrqpnQ7AsaGRfkYUbeOIioh6woDjQrGTTRf1Zag==
dependencies:
"@prisma/debug" "5.8.1"
"@rollup/rollup-android-arm-eabi@4.9.6":
version "4.9.6"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz#66b8d9cb2b3a474d115500f9ebaf43e2126fe496"
@ -292,6 +333,28 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
"@types/node-fetch@^2.6.4":
version "2.6.11"
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24"
integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==
dependencies:
"@types/node" "*"
form-data "^4.0.0"
"@types/node@*":
version "20.11.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.6.tgz#6adf4241460e28be53836529c033a41985f85b6e"
integrity sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==
dependencies:
undici-types "~5.26.4"
"@types/node@^18.11.18":
version "18.19.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.9.tgz#6c2624c3a05bfa3a2735c533f95597ffacbb5608"
integrity sha512-oZFKlC8l5YtzGQNT4zC2PiSSKzQVZ8bAwwd+EYdPLtyk0nSEq6O16SkK+rkkT2eflDAbormJgEF3QnH3oDrTSw==
dependencies:
undici-types "~5.26.4"
"@types/node@^20.4.9":
version "20.11.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.5.tgz#be10c622ca7fcaa3cf226cf80166abc31389d86e"
@ -299,6 +362,13 @@
dependencies:
undici-types "~5.26.4"
abort-controller@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
dependencies:
event-target-shim "^5.0.0"
acorn-walk@^8.1.1:
version "8.3.2"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa"
@ -309,6 +379,13 @@ acorn@^8.4.1:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
agentkeepalive@^4.2.1:
version "4.5.0"
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923"
integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==
dependencies:
humanize-ms "^1.2.1"
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
@ -373,6 +450,11 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base-64@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb"
integrity sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==
binary-extensions@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
@ -404,6 +486,11 @@ cac@^6.7.12:
resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959"
integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==
charenc@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==
chokidar@^3.5.1:
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
@ -457,6 +544,11 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
crypt@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==
debug@^4.3.1:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
@ -474,6 +566,14 @@ diff@^4.0.1:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
digest-fetch@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/digest-fetch/-/digest-fetch-1.3.0.tgz#898e69264d00012a23cf26e8a3e40320143fc661"
integrity sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==
dependencies:
base-64 "^0.1.0"
md5 "^2.3.0"
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
@ -530,6 +630,11 @@ esbuild@^0.19.2:
"@esbuild/win32-ia32" "0.19.12"
"@esbuild/win32-x64" "0.19.12"
event-target-shim@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
execa@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
@ -583,6 +688,11 @@ foreground-child@^3.1.0:
cross-spawn "^7.0.0"
signal-exit "^4.0.1"
form-data-encoder@1.7.2:
version "1.7.2"
resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz#1f1ae3dccf58ed4690b86d87e4f57c654fbab040"
integrity sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==
form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
@ -592,6 +702,14 @@ form-data@^4.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
formdata-node@^4.3.2:
version "4.4.1"
resolved "https://registry.yarnpkg.com/formdata-node/-/formdata-node-4.4.1.tgz#23f6a5cb9cb55315912cbec4ff7b0f59bbd191e2"
integrity sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==
dependencies:
node-domexception "1.0.0"
web-streams-polyfill "4.0.0-beta.3"
fsevents@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
@ -637,6 +755,13 @@ human-signals@^2.1.0:
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
humanize-ms@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed"
integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==
dependencies:
ms "^2.0.0"
ignore@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78"
@ -649,6 +774,11 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
is-buffer@~1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
@ -725,6 +855,15 @@ make-error@^1.1.1:
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
md5@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==
dependencies:
charenc "0.0.2"
crypt "0.0.2"
is-buffer "~1.1.6"
merge-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
@ -777,6 +916,11 @@ ms@2.1.2:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
ms@^2.0.0:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
mz@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
@ -786,6 +930,18 @@ mz@^2.7.0:
object-assign "^4.0.1"
thenify-all "^1.0.0"
node-domexception@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
node-fetch@^2.6.7:
version "2.7.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
dependencies:
whatwg-url "^5.0.0"
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
@ -810,6 +966,21 @@ onetime@^5.1.2:
dependencies:
mimic-fn "^2.1.0"
openai@^4.25.0:
version "4.25.0"
resolved "https://registry.yarnpkg.com/openai/-/openai-4.25.0.tgz#b40099d625cccb19cbf1cab88915ac1699ece0ed"
integrity sha512-qLMFOizjxKuDfQkBrczZPYo6XVL4bdcuz9MR11Q+M91kGcs8dQw+O90nRcC+qWuhaGphQkfXQJMn4cd7Yew3Kg==
dependencies:
"@types/node" "^18.11.18"
"@types/node-fetch" "^2.6.4"
abort-controller "^3.0.0"
agentkeepalive "^4.2.1"
digest-fetch "^1.3.0"
form-data-encoder "1.7.2"
formdata-node "^4.3.2"
node-fetch "^2.6.7"
web-streams-polyfill "^3.2.1"
path-key@^3.0.0, path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
@ -846,6 +1017,13 @@ postcss-load-config@^4.0.1:
lilconfig "^3.0.0"
yaml "^2.3.4"
prisma@^5.8.1:
version "5.8.1"
resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.8.1.tgz#1f101793a8831c0719dfbed5f85a96ea4888c9d3"
integrity sha512-N6CpjzECnUHZ5beeYpDzkt2rYpEdAeqXX2dweu6BoQaeYkNZrC/WJHM+5MO/uidFHTak8QhkPKBWck1o/4MD4A==
dependencies:
"@prisma/engines" "5.8.1"
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
@ -1021,6 +1199,11 @@ tr46@^1.0.1:
dependencies:
punycode "^2.1.0"
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
tree-kill@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
@ -1085,11 +1268,34 @@ v8-compile-cache-lib@^3.0.1:
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
web-streams-polyfill@4.0.0-beta.3:
version "4.0.0-beta.3"
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz#2898486b74f5156095e473efe989dcf185047a38"
integrity sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==
web-streams-polyfill@^3.2.1:
version "3.3.2"
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz#32e26522e05128203a7de59519be3c648004343b"
integrity sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
webidl-conversions@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
whatwg-url@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
dependencies:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
whatwg-url@^7.0.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06"