Update Next.js configuration and package dependencies
All checks were successful
Deploy / deploy (push) Successful in 9m29s
All checks were successful
Deploy / deploy (push) Successful in 9m29s
- Modified redirects in next.config.ts to change the destination for "/sohbet" to "/listem". - Added new dependencies in package.json: marked, motion, react-markdown, remark-breaks, remark-gfm, shiki, and use-stick-to-bottom. - Updated pnpm-lock.yaml to reflect the new package versions and dependencies. - Removed obsolete stack files for Flutter, Nuxt, Nuxt.js, React Native, and Svelte from the UI/UX Pro Max skill data. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,11 +8,16 @@ import { listeOzetiCikar, type RaporSonuc } from "@/lib/ai/rapor";
|
||||
import type { RaporParams } from "@/lib/rapor-havuzu";
|
||||
import { secimOzeti } from "@/lib/sihirbaz";
|
||||
import { PUAN_TURLERI } from "@/lib/db";
|
||||
import { ACIK_SATIR } from "@/lib/rapor-maske";
|
||||
|
||||
const MAX_GECMIS = 12;
|
||||
const MAX_MESAJ_UZUNLUK = 2000;
|
||||
|
||||
function sistemPromptu(opts: { params: RaporParams; listeOzeti: string }): string {
|
||||
function sistemPromptu(opts: {
|
||||
params: RaporParams;
|
||||
listeOzeti: string;
|
||||
kilitli?: boolean;
|
||||
}): string {
|
||||
const { params } = opts;
|
||||
const secimVar =
|
||||
(params.kategoriler?.length ?? 0) > 0 ||
|
||||
@@ -29,6 +34,10 @@ iş imkânları, tercih sırası) net ve dürüst yanıtlamak.
|
||||
KURALLAR:
|
||||
- Cevaplarını adayın 24'lük listesi ve seçimleri bağlamında ver; listedeki
|
||||
programlara referans verebilirsin.
|
||||
- Listedeki her satırda dilim ve risk etiketi var: Güvenli (yeşil) = taban
|
||||
sıralaması adayın belirgin altında, Az riskli (sarı) = adayın sıralaması
|
||||
civarında, Riskli (kırmızı) = geçen yıl adayın sıralamasının üzerinde
|
||||
kapandı. Risk sorularında bu etiketleri ve taban sıralarını kullan.
|
||||
- ASLA yerleşme garantisi verme; "yüksek/orta/düşük ihtimal" dili kullan.
|
||||
- Bilmediğin güncel veriyi uydurma; emin değilsen YÖK Atlas'a bakmasını söyle.
|
||||
- Taban sıralamalarının her yıl değiştiğini gerektiğinde hatırlat.
|
||||
@@ -39,6 +48,15 @@ KURALLAR:
|
||||
`ADAY BİLGİSİ: başarı sıralaması ${params.sira.toLocaleString("tr-TR")}, puan türü ${PUAN_TURLERI[params.tur]}.`,
|
||||
`ADAYIN 24'LÜK LİSTESİ:\n${opts.listeOzeti}`,
|
||||
];
|
||||
if (opts.kilitli) {
|
||||
parcalar.push(
|
||||
`ÖNEMLİ: Adayın paketi yok; listenin yalnızca ilk ${ACIK_SATIR} tercihi açık.
|
||||
Sana da yalnızca bu satırlar verildi — kilitli tercihlerin içeriğini BİLMİYORSUN,
|
||||
asla tahmin edip söyleme. Kilitli satırlar sorulursa sempatik biçimde tam listenin
|
||||
Tercih Dönemi Paketi'yle (299 TL, /paket) açıldığını söyle; açık satırlar ve genel
|
||||
tercih soruları üzerinden yardımcı olmaya devam et.`,
|
||||
);
|
||||
}
|
||||
if (secimVar) {
|
||||
parcalar.push(
|
||||
`ADAYIN SİHİRBAZ SEÇİMLERİ:\n${secimOzeti({
|
||||
@@ -140,11 +158,67 @@ export async function POST(request: NextRequest) {
|
||||
}
|
||||
const kullaniciMesajId = harcama.messageId!;
|
||||
|
||||
// Paketsiz kullanıcının prompt'una yalnızca açık satırlar girer — aksi
|
||||
// halde danışman kilitli listeyi sözle sızdırabilir.
|
||||
const kullanici = await appDb.query.user.findFirst({
|
||||
where: eq(schema.user.id, session.user.id),
|
||||
columns: { hasPaket: true },
|
||||
});
|
||||
const kilitli = !kullanici?.hasPaket;
|
||||
const tamOzet = listeOzetiCikar(
|
||||
rapor.result as RaporSonuc,
|
||||
(rapor.params as RaporParams).sira,
|
||||
);
|
||||
const listeOzeti = kilitli
|
||||
? [
|
||||
...tamOzet.split("\n").slice(0, ACIK_SATIR),
|
||||
`… kalan ${24 - ACIK_SATIR} tercih kilitli.`,
|
||||
].join("\n")
|
||||
: tamOzet;
|
||||
|
||||
const system = sistemPromptu({
|
||||
params: rapor.params as RaporParams,
|
||||
listeOzeti: listeOzetiCikar(rapor.result as RaporSonuc),
|
||||
listeOzeti,
|
||||
kilitli,
|
||||
});
|
||||
|
||||
// Dev'de API key yoksa danışman mock cevap stream'ler (prod'da asla)
|
||||
if (
|
||||
process.env.NODE_ENV !== "production" &&
|
||||
!process.env.ANTHROPIC_API_KEY &&
|
||||
!process.env.ANTHROPIC_AUTH_TOKEN
|
||||
) {
|
||||
const mockEncoder = new TextEncoder();
|
||||
const mockUserId = session.user.id;
|
||||
const cevap =
|
||||
`(Dev mock — ANTHROPIC_API_KEY tanımlı değil.) Sorunu aldım: "${mesaj.slice(0, 120)}". ` +
|
||||
`Gerçek danışman burada listen ve seçimlerin bağlamında yanıt verecek. ` +
|
||||
`${SORUMLULUK_REDDI}`;
|
||||
const mockReadable = new ReadableStream({
|
||||
async start(controller) {
|
||||
for (const parca of cevap.split(/(?<= )/)) {
|
||||
controller.enqueue(mockEncoder.encode(parca));
|
||||
await new Promise((r) => setTimeout(r, 25));
|
||||
}
|
||||
await appDb.insert(schema.chatMessages).values({
|
||||
id: crypto.randomUUID(),
|
||||
userId: mockUserId,
|
||||
role: "assistant",
|
||||
content: cevap,
|
||||
createdAt: new Date(),
|
||||
});
|
||||
controller.close();
|
||||
},
|
||||
});
|
||||
return new Response(mockReadable, {
|
||||
headers: {
|
||||
"Content-Type": "text/plain; charset=utf-8",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"Cache-Control": "no-store",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
let client;
|
||||
try {
|
||||
client = getAnthropic();
|
||||
|
||||
Reference in New Issue
Block a user