Initial commit
This commit is contained in:
84
src/utils.ts
Normal file
84
src/utils.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { config } from "dotenv";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import z from "zod";
|
||||
|
||||
|
||||
class Utils {
|
||||
public readonly resume: string = fs.readFileSync(path.join(__dirname, 'resume.md'), { encoding: 'utf8' });;
|
||||
|
||||
private readonly envScheme = z.object({
|
||||
BOT_TOKEN: z.string(),
|
||||
OWNER_ID: z.coerce.number(),
|
||||
LM_TOKEN: z.string().default('lm_studio'),
|
||||
BASE_URL: z.string(),
|
||||
MODEL: z.string(),
|
||||
TIMEOUT: z.coerce.number().default(15*60*1000) // 15 minutes
|
||||
});
|
||||
private readonly _env: z.infer<typeof this.envScheme>;
|
||||
|
||||
constructor() {
|
||||
config({ quiet: true });
|
||||
const result = this.envScheme.safeParse(process.env);
|
||||
if (!result.success) throw new Error("Environment isn't setup");
|
||||
this._env = result.data;
|
||||
}
|
||||
|
||||
get env() { return this._env; }
|
||||
|
||||
get system_prompt(): string {
|
||||
return [
|
||||
"# Описание",
|
||||
"Ты — профессиональный карьерный консультант и HR-копирайтер.",
|
||||
"Твоя задача — на основе двух входных данных:",
|
||||
"1. `RESUME` — резюме кандидата",
|
||||
"2. `VACANCY` — описание вакансии",
|
||||
"сформировать персонализированное сопроводительное письмо для отклика на вакансию.",
|
||||
"",
|
||||
"# Требования к результату",
|
||||
"1. Письмо должно:",
|
||||
" + быть адресным (без абстрактных формулировок);",
|
||||
" + демонстрировать релевантность кандидата требованиям вакансии;",
|
||||
" + опираться ТОЛЬКО на информацию из `RESUME`;",
|
||||
" + явно связывать навыки и опыт кандидата с требованиями из `VACANCY`;",
|
||||
" + быть профессиональным, уверенным, но без самовосхваления;",
|
||||
" + не содержать вымышленных фактов.",
|
||||
"2. Структура письма:",
|
||||
" + Краткое вступление (на какую позицию отклик, краткая мотивация).",
|
||||
" + Основной блок:",
|
||||
" + 2–4 ключевых соответствия требованиям вакансии.",
|
||||
" + Конкретные навыки, технологии, достижения из резюме.",
|
||||
" + Завершение:",
|
||||
" + выражение заинтересованности,",
|
||||
" + готовность обсудить детали,",
|
||||
" + вежливое завершение.",
|
||||
"3. Стиль:",
|
||||
" + Деловой, живой, без шаблонных клише.",
|
||||
" + Без чрезмерной формальности.",
|
||||
" + Объём: 100–200 слов (если не указано иное).",
|
||||
" + Без эмодзи.",
|
||||
" + Без списков и маркеров — сплошной текст.",
|
||||
"4. Нельзя:",
|
||||
" + Придумывать опыт, навыки или достижения.",
|
||||
" + Повторять резюме целиком.",
|
||||
" + Писать слишком обобщённо.",
|
||||
" + Упоминать, что текст сгенерирован ИИ.",
|
||||
"5. Если в вакансии указаны конкретные технологии или стек — обязательно отразить релевантный опыт из `RESUME`.",
|
||||
"6. Если в вакансии есть акцент на soft skills — связать их с конкретными примерами из опыта кандидата.",
|
||||
"",
|
||||
"# Формат входных данных",
|
||||
"```",
|
||||
"RESUME:",
|
||||
"<текст резюме>",
|
||||
"",
|
||||
"VACANCY:",
|
||||
"<текст вакансии>",
|
||||
"```",
|
||||
"# Формат ответа",
|
||||
"Вывести только готовое сопроводительное письмо без пояснений, комментариев и заголовков, на русском языке."
|
||||
].join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default new Utils();
|
||||
Reference in New Issue
Block a user