112 lines
No EOL
4 KiB
TypeScript
112 lines
No EOL
4 KiB
TypeScript
import ModelClient, { isUnexpected } from "@azure-rest/ai-inference";
|
|
import { AzureKeyCredential } from "@azure/core-auth";
|
|
|
|
const KEY = process.env.NEIS_API_KEY;
|
|
|
|
export function removeNutritionInfo(value: string): string {
|
|
const lines = value.trim().split('\n');
|
|
const cleanedLines = lines.map(line => line.replace(/\s*\([\d.,]+\)/g, '').trim());
|
|
const result = cleanedLines.join('\n');
|
|
return result;
|
|
}
|
|
|
|
const nutritionList = [
|
|
"난류", "우유", "메밀", "땅콩", "대두", "밀", "고등어", "게", "새우", "돼지고기",
|
|
"복숭아", "토마토", "아황산류", "호두", "닭고기", "쇠고기", "오징어", "조개류(굴, 전복, 홍합 포함)", "잣"
|
|
];
|
|
|
|
export function getNutritionInfo(value: string): string[][] {
|
|
const lines = value.trim().split('\n');
|
|
return lines.map(line => {
|
|
const indexes = line
|
|
.replace(/[()\s]/g, "")
|
|
.split(".")
|
|
.map(v => parseInt(v, 10) - 1)
|
|
.filter(i => i >= 0 && i < nutritionList.length);
|
|
return indexes
|
|
.map(i => nutritionList[i])
|
|
.filter((item): item is string => typeof item === "string");
|
|
});
|
|
}
|
|
|
|
|
|
export async function getMealInfo(MLSV_YMD: string): Promise<{ meal: string; date: string, kcal: string }> {
|
|
const url = `https://open.neis.go.kr/hub/mealServiceDietInfo?Type=json&ATPT_OFCDC_SC_CODE=E10&SD_SCHUL_CODE=7331071&MLSV_YMD=${MLSV_YMD}&KEY=${KEY}`;
|
|
const response = await fetch(url);
|
|
const data = await response.json();
|
|
// @ts-ignore
|
|
const DDISH_NM = data.mealServiceDietInfo[1].row[0].DDISH_NM;
|
|
return {
|
|
meal: DDISH_NM.replace(/<br\s*\/?>/gi, '\n'),
|
|
date: MLSV_YMD,
|
|
// @ts-ignore
|
|
|
|
kcal: data.mealServiceDietInfo[1].row[0].CAL_INFO,
|
|
};
|
|
|
|
}
|
|
|
|
export async function NameToEmoji(name: string): Promise<string> {
|
|
const token = process.env.GITHUB_TOKEN;
|
|
if (!token) {
|
|
throw new Error("GITHUB_TOKEN environment variable is not set.");
|
|
}
|
|
const endpoint = "https://models.github.ai/inference";
|
|
const model = "openai/gpt-4.1-mini";
|
|
|
|
const client = ModelClient(
|
|
endpoint,
|
|
new AzureKeyCredential(token),
|
|
);
|
|
|
|
const systemPrompt = `# **⚠️ IMPORTANT INSTRUCTIONS: You are an emoji-only responder. The following rules MUST be strictly adhered to, without exception. ⚠️**
|
|
|
|
1. **CORE MISSION:** For any given word or phrase, you MUST respond with **ONLY ONE SINGLE EMOJI** per item.
|
|
* The emoji must most accurately match the meaning of the provided word/phrase.
|
|
|
|
2. **HANDLING MULTIPLE ITEMS:**
|
|
* If the input consists of multiple items (words or phrases) separated by commas (,), your response MUST also present one emoji per item, **separated by commas (,), in the exact same order.**
|
|
|
|
3. **ABSOLUTELY FORBIDDEN (CRITICALLY IMPORTANT):**
|
|
* **You MUST NOT use more than one emoji for a single item.** (ONLY ONE!)
|
|
* Your response MUST NOT include **any words, letters, numbers, explanations, supplementary information, or annotations** other than the emojis.
|
|
* Only emojis in the requested format are permitted.
|
|
|
|
4. **RESPONSE FORMAT:** **[Emoji1], [Emoji2], ...** (The number of emojis must match the number of input items.)
|
|
|
|
**EXAMPLES (Adhering perfectly to these rules):**
|
|
* Q: 현미찹쌀밥
|
|
* A: 🍚
|
|
* Q: 개
|
|
* A: 🐶
|
|
* Q: 축구
|
|
* A: ⚽
|
|
* Q: 해넘이
|
|
* A: 🌇
|
|
* Q: 현미찹쌀밥,개,축구
|
|
* A: 🍚,🐶,⚽
|
|
* Q: 행복, 슬픔, 놀람
|
|
* A: 😊,😢,😮
|
|
`;
|
|
|
|
const response = await client.path("/chat/completions").post({
|
|
body: {
|
|
messages: [
|
|
{ role: "system", content: systemPrompt },
|
|
{ role: "user", content: name }
|
|
],
|
|
temperature: 1.0,
|
|
top_p: 1.0,
|
|
model: model
|
|
}
|
|
});
|
|
if (isUnexpected(response)) {
|
|
throw response.body.error;
|
|
}
|
|
|
|
const choices = response.body?.choices;
|
|
if (!choices || !choices[0]?.message?.content) {
|
|
throw new Error("No valid response from the model.");
|
|
}
|
|
return choices[0].message.content as string;
|
|
} |