From 1d4aa366025dcad99bb54718b39b0b445430782c Mon Sep 17 00:00:00 2001 From: Fahri Can Date: Mon, 18 May 2026 00:08:50 +0300 Subject: [PATCH] gg --- src/common/utils/ollama-client.ts | 4 +- src/common/utils/ollama-commentary.ts | 93 +++++++------------ .../predictions/predictions.controller.ts | 1 - 3 files changed, 34 insertions(+), 64 deletions(-) diff --git a/src/common/utils/ollama-client.ts b/src/common/utils/ollama-client.ts index 2c00132..4e3e605 100644 --- a/src/common/utils/ollama-client.ts +++ b/src/common/utils/ollama-client.ts @@ -4,7 +4,7 @@ const logger = new Logger("OllamaClient"); const OLLAMA_BASE_URL = process.env.OLLAMA_URL ?? "http://172.22.0.1:11434"; const OLLAMA_MODEL = process.env.OLLAMA_MODEL ?? "llama3.2:3b"; -const TIMEOUT_MS = 30_000; +const TIMEOUT_MS = 90_000; export async function generateOllamaText(prompt: string): Promise { try { @@ -21,7 +21,7 @@ export async function generateOllamaText(prompt: string): Promise stream: false, options: { temperature: 0.6, - num_predict: 250, + num_predict: 150, repeat_penalty: 1.1, }, }), diff --git a/src/common/utils/ollama-commentary.ts b/src/common/utils/ollama-commentary.ts index d92d03d..f40d011 100644 --- a/src/common/utils/ollama-commentary.ts +++ b/src/common/utils/ollama-commentary.ts @@ -18,84 +18,55 @@ function buildPrompt(p: PredictionData): string { const risk = (p.risk ?? {}) as Record; const ba = (p.bet_advice ?? {}) as Record; const dq = (p.data_quality ?? {}) as Record; + const v27 = (p.v27_engine ?? {}) as Record; const home = String(mi.home_team ?? "Ev Sahibi"); const away = String(mi.away_team ?? "Deplasman"); const league = String(mi.league ?? ""); + // Market board - ham olasılıklar const ms = (mb.MS ?? {}) as Record; - const msProbs = (ms.probs ?? {}) as Record; const ou15 = (mb.OU15 ?? {}) as Record; const ou25 = (mb.OU25 ?? {}) as Record; const ou35 = (mb.OU35 ?? {}) as Record; const btts = (mb.BTTS ?? {}) as Record; - const homeWin = Math.round((msProbs["1"] ?? 0) * 100); - const draw = Math.round((msProbs["X"] ?? 0) * 100); - const awayWin = Math.round((msProbs["2"] ?? 0) * 100); + // V27 predictions + const v27preds = (v27.predictions ?? {}) as Record; + const v27ms = (v27preds.ms ?? {}) as Record; - const ou15Probs = (ou15.probs ?? {}) as Record; - const ou25Probs = (ou25.probs ?? {}) as Record; - const ou35Probs = (ou35.probs ?? {}) as Record; - const bttsProbs = (btts.probs ?? {}) as Record; + // Risk breakdown + const surpriseReasons = (risk.surprise_reasons as string[] | undefined) ?? []; + const warnings = (risk.warnings as string[] | undefined) ?? []; - const xgHome = Number(sp.xg_home ?? 0).toFixed(2); - const xgAway = Number(sp.xg_away ?? 0).toFixed(2); - const ftScore = String(sp.ft ?? ""); + // Top 5 scenarios + const top5 = (p.scenario_top5 ?? []).slice(0, 5); - const ou15Over = Math.round((ou15Probs.over ?? 0) * 100); - const ou25Over = Math.round((ou25Probs.over ?? 0) * 100); - const ou35Under = Math.round((ou35Probs.under ?? 0) * 100); - const bttsYes = Math.round((bttsProbs.yes ?? 0) * 100); + const analysisData = { + mac: `${home} - ${away} (${league})`, + ms_olasilik: { + ev_sahibi_kazanir: ms.probs ? (mb.MS as Record)?.probs : null, + v27_ev_sahibi: v27ms.home ? Math.round(v27ms.home * 100) : null, + }, + xg: { ev_sahibi: sp.xg_home, deplasman: sp.xg_away, toplam: sp.xg_total }, + gol_marketleri: { + "1_5_ust": (ou15.probs as Record | undefined)?.over, + "2_5_ust": (ou25.probs as Record | undefined)?.over, + "3_5_alt": (ou35.probs as Record | undefined)?.under, + kg_var: (btts.probs as Record | undefined)?.yes, + }, + skor_tahmini: sp.ft, + en_olasilar: top5.map((s) => `${s.score}: %${Math.round(s.prob * 100)}`), + risk: { seviye: risk.level, surpriz_skoru: risk.surprise_score, uyarilar: [...surpriseReasons, ...warnings].slice(0, 3) }, + bahis_tavsiyesi: { oynanabilir: ba.playable, karar: ba.decision, neden: ba.reason }, + kadro: { kaynak: dq.lineup_source, kalite: dq.score }, + }; - const riskLevel = String(risk.level ?? ""); - const surpriseScore = Number(risk.surprise_score ?? 0); - const playable = Boolean(ba.playable); - const lineupSource = String(dq.lineup_source ?? ""); + return `Sen bir futbol bahis analistisin. Aşağıdaki maç analizini okuyup SADECE TÜRKÇE 2-3 cümle yorum yaz. Sayıları tekrar etme, anlam çıkar. - const top5 = (p.scenario_top5 ?? []) - .slice(0, 3) - .map((s) => `${s.score} (%${Math.round(s.prob * 100)})`) - .join(", "); - - // V27 MS probs if available - const v27 = (p.v27_engine ?? {}) as Record; - const v27ms = (v27.predictions as Record)?.ms as Record | undefined; - const v27Home = v27ms ? Math.round(v27ms.home * 100) : null; - - const nobet = !playable - ? "Tüm oranlar çok düşük, bahis yapmak mantıklı değil." - : "Bahis açılabilir."; - - const xgComment = - Number(xgHome) > Number(xgAway) * 2 - ? `${home} xG açısından çok üstün (${xgHome} - ${xgAway}), ${away} gol atacak alan bulamıyor.` - : Number(xgAway) > Number(xgHome) * 2 - ? `${away} xG açısından çok üstün (${xgAway} - ${xgHome}), ${home} etkisiz kalıyor.` - : `İki takım xG açısından yakın (${xgHome} - ${xgAway}).`; - - const goalComment = - ou15Over >= 80 - ? "Maçta kesinlikle gol bekleniyor." - : ou15Over >= 65 - ? "Gol ihtimali yüksek." - : "Golsüz geçebilir."; - - const highSurprise = surpriseScore >= 60; - - return `Aşağıdaki futbol maçı için Türkçe uzman yorum yaz. Sadece Türkçe kullan, İngilizce kelime yasak. 3 cümle yaz, kısa tut. - -Maç: ${home} - ${away} -${home} kazanma ihtimali: %${homeWin}${v27Home ? `, güçlü model: %${v27Home}` : ""} -Beraberlik: %${draw}, ${away} kazanır: %${awayWin} -${xgComment} -${goalComment} (1.5 üst: %${ou15Over}, 2.5 üst: %${ou25Over}) -En olası skor: ${ftScore}. İkili bahis olasılığı: %${bttsYes}. -Risk: ${riskLevel}${highSurprise ? ", sürpriz olabilir" : ""}. -${nobet} - -Yorum:`; +${JSON.stringify(analysisData, null, 2)} +Türkçe yorum:`; } export async function generateExpertCommentary( diff --git a/src/modules/predictions/predictions.controller.ts b/src/modules/predictions/predictions.controller.ts index eb151bd..2c4e001 100755 --- a/src/modules/predictions/predictions.controller.ts +++ b/src/modules/predictions/predictions.controller.ts @@ -150,7 +150,6 @@ export class PredictionsController { @Get(":matchId/commentary") async getCommentary( @Param("matchId") matchId: string, - @CurrentUser() user: any, ): Promise<{ commentary: string | null }> { const commentary = await this.predictionsService.getAiCommentary(matchId); return { commentary };