summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpolwex <polwex@sortug.com>2025-08-17 02:20:42 +0700
committerpolwex <polwex@sortug.com>2025-08-17 02:20:42 +0700
commit9be51e192fca8901d47328875d9e0c690d4b2b99 (patch)
tree926151e075c539019c5eb65e2140678acb383c5f
parentc505750ab36f8164256a91830fc83a807a9d6984 (diff)
this was me. local LLM!HEADmaster
-rw-r--r--src/components/tones/ToneSelectorClient.tsx14
-rw-r--r--src/lib/services/aitranslation.ts14
-rw-r--r--src/lib/services/llm.ts16
-rw-r--r--src/pages/tones.tsx4
-rw-r--r--src/styles.css19
5 files changed, 55 insertions, 12 deletions
diff --git a/src/components/tones/ToneSelectorClient.tsx b/src/components/tones/ToneSelectorClient.tsx
index 438fc8a..3335015 100644
--- a/src/components/tones/ToneSelectorClient.tsx
+++ b/src/components/tones/ToneSelectorClient.tsx
@@ -29,6 +29,7 @@ import { Skeleton } from "@/components/ui/skeleton"; // For loading state
import { MutationOrder, PhoneticData, ToneQuery } from "@/lib/types/phonetics";
import { ProsodySyllable } from "@/lib/types/cards";
import { ArrowLeft, ArrowRight, Volume2, FlipHorizontal2 } from "lucide-react";
+import { LLM } from "@/lib/services/llm";
function getColorByTone(tone: string): string {
if (tone === "mid") return "blue";
@@ -96,6 +97,18 @@ const ProminentToneDisplay = ({ word }: { word: any }) => {
return () => window.removeEventListener("keydown", onKeyDown);
}, [playAudio]);
+ async function testLM() {
+ const lm = new LLM({
+ openai: {
+ url: "http://localhost:1234/v1",
+ apiKey: "",
+ model: "openai/gpt-oss-20b",
+ allowBrowser: true,
+ },
+ });
+ const res = await lm.chat("hey man something great happened to me today");
+ console.log("llm res", res);
+ }
return (
<div className="flex flex-col items-center mb-4">
<h1 className="text-6xl font-bold mb-2">
@@ -123,6 +136,7 @@ const ProminentToneDisplay = ({ word }: { word: any }) => {
<audio ref={audioRef} />
<p className="ipa text-xl text-gray-700 mt-2">{word.frequency}</p>
<p className="ipa text-xl text-gray-700 mt-2">{word.word_id}</p>
+ <button onClick={testLM}>Test</button>
</div>
</div>
);
diff --git a/src/lib/services/aitranslation.ts b/src/lib/services/aitranslation.ts
index 331e10e..fb88323 100644
--- a/src/lib/services/aitranslation.ts
+++ b/src/lib/services/aitranslation.ts
@@ -1,12 +1,12 @@
import { z } from "zod";
import type { Language, TranslationService } from "../types";
-import AIModelAPI, { type AIModelChoice } from "sortug-ai";
+import AIModelAPI, { type LLMChoice } from "sortug-ai";
import type { AsyncRes } from "@/lib/types";
export class AiTranslator implements TranslationService {
endpoint = ""; // doesn't apply here
api;
- constructor(model: AIModelChoice) {
+ constructor(model: LLMChoice) {
const api = AIModelAPI(model);
this.api = api;
}
@@ -24,12 +24,11 @@ export class AiTranslator implements TranslationService {
},
];
const res = await this.api.send(
- `You are a professional, state of the art excellent translation service. Please translate the text given by the user. The prompts will be sent as JSON, in the format "{'text': string, 'sourceLang': string, 'targetLang': string}". You are to translate the 'text' from 'fromLang' to 'targetLang'. Output the desired translation and nothing else. Pause to think the translations as much as you need.`,
input,
+ `You are a professional, state of the art excellent translation service. Please translate the text given by the user. The prompts will be sent as JSON, in the format "{'text': string, 'sourceLang': string, 'targetLang': string}". You are to translate the 'text' from 'fromLang' to 'targetLang'. Output the desired translation and nothing else. Pause to think the translations as much as you need.`,
);
console.log({ res });
- if ("error" in res) return res;
- else return { ok: res.ok.join(", ") };
+ return res;
}
async getSupportedLanguages() {
@@ -49,10 +48,9 @@ export class AiTranslator implements TranslationService {
},
];
const res = await this.api.send(
- `You are a professional, state of the art excellent translation service. Please transliterate, the text given by the user. The prompts will be sent as JSON, in the format "{'text': string, 'language': string, 'fromScript': string, 'toScript': string}". You are to transliterate the 'text' belongng to language 'language' from 'fromScript' to 'toScript' to the best of your ability. Output the desired transiteration and nothing else. Pause to think the output as much as you need.`,
input,
+ `You are a professional, state of the art excellent translation service. Please transliterate, the text given by the user. The prompts will be sent as JSON, in the format "{'text': string, 'language': string, 'fromScript': string, 'toScript': string}". You are to transliterate the 'text' belongng to language 'language' from 'fromScript' to 'toScript' to the best of your ability. Output the desired transiteration and nothing else. Pause to think the output as much as you need.`,
);
- if ("error" in res) return res;
- else return { ok: res.ok.join(", ") };
+ return res;
}
}
diff --git a/src/lib/services/llm.ts b/src/lib/services/llm.ts
new file mode 100644
index 0000000..508423f
--- /dev/null
+++ b/src/lib/services/llm.ts
@@ -0,0 +1,16 @@
+import AIModelAPI, { type LLMChoice } from "sortug-ai";
+import type { AsyncRes } from "@/lib/types";
+
+export class LLM {
+ private api;
+ constructor(model: LLMChoice) {
+ const api = AIModelAPI(model);
+ this.api = api;
+ }
+
+ async chat(text: string): AsyncRes<string> {
+ const res = await this.api.send(text);
+ console.log({ res });
+ return res;
+ }
+}
diff --git a/src/pages/tones.tsx b/src/pages/tones.tsx
index 20c1237..066f3cb 100644
--- a/src/pages/tones.tsx
+++ b/src/pages/tones.tsx
@@ -20,13 +20,13 @@ async function randomTones(tries = 0) {
console.log({ tones, toneStrings });
const initialWords = await fetchWordsByToneAndSyllables(tones);
if (!initialWords || initialWords.length === 0) return randomTones(tries + 1);
- else return {initialWords, tones};
+ else return { initialWords, tones };
}
// Function to fetch the initial word on the server
async function InitialWordLoader() {
// Fetch a random 1-syllable Thai word with any tone initially
- const {initialWords, tones]} = await randomTones();
+ const { initialWords, tones } = await randomTones();
return <ToneSelectorClient initialData={initialWords} initialTones={tones} />;
}
diff --git a/src/styles.css b/src/styles.css
index f1d3c37..71b058c 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -1,3 +1,18 @@
-@import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,400;0,700;1,400;1,700&display=swap')
-layer(base);
+@import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,400;0,700;1,400;1,700&display=swap') layer(base);
@import 'tailwindcss';
+
+@font-face {
+ font-family: 'ThaiCustom';
+ src: local('Noto Sans Thai');
+ /* Specify a clear Thai font installed on your system */
+ size-adjust: 200%;
+ unicode-range: U+0E00-0E7F;
+}
+
+@font-face {
+ font-family: 'Lolmao';
+ src: local('Fira');
+ /* Specify a clear Thai font installed on your system */
+ size-adjust: 200%;
+ unicode-range: U+0000-007F;
+} \ No newline at end of file