3 Commits

Author SHA1 Message Date
pezkuwichain 54c94c7558 fix(ai): prioritize Groq's most stable model, stop repeating mining disclaimer (#9)
User decision after the Groq reliability fix (previous PR): prioritize
Groq's smallest/fastest model, llama-3.1-8b-instant, over gpt-oss-120b —
it's long out of preview and has historically the best free-tier
availability, at the cost of gpt-oss-120b's better Turkish/Kurdish
fluency (which is why it was chosen originally). Model order is now
llama-3.1-8b-instant -> gpt-oss-120b -> llama-3.3-70b-versatile before
the (currently uncredited) Anthropic fallback.

Also fixed a real UX complaint: asking about the Mining Simulation made
the model repeat "this isn't real mining / it's just an estimate" in
nearly every paragraph. Added an explicit instruction to state that once,
briefly, near the start of the answer, and not repeat it — verified live,
the disclaimer now appears once per response instead of several times.
2026-07-21 07:52:59 -07:00
pezkuwichain 9bb9d2cda3 fix(ai): Groq intermittent failures + sync git with actually-deployed source (#8)
The AI assistant (both @DKSKurdistanBot on Telegram and the news.pex.mom
"ask" widget) was failing to answer most questions while occasionally
succeeding — reported as "only answers about pez mining, says it doesn't
know anything else." Root cause was NOT a knowledge-base gap (the full
whitepaper/wallet/mining/book knowledge was present in both functions all
along) — it was Groq's openai/gpt-oss-120b model returning intermittent
errors (429/5xx, one raw 502) under real load, confirmed live by hitting
the same endpoint repeatedly with trivial questions ("merhaba") and
getting a ~50% failure rate even 15s+ apart (ruling out our own per-IP
rate limiter). The Anthropic fallback couldn't rescue these failures
because that key has no credit.

Fix: retry each Groq call up to 2x with backoff, and fall back to
llama-3.3-70b-versatile (the model this used before switching to
gpt-oss-120b, still free on Groq, not observed to have the same
instability) before ever reaching the Anthropic branch. Verified live
after deploying: failure rate dropped from ~50% to under ~20% across
repeated real test questions.

Also fixed a real (latent, not currently triggered since both keys happen
to be set) bug in telegram-bot: handleAIChat had an early
`if (!ANTHROPIC_API_KEY) return` guard that predates Groq being added as
primary provider — if Anthropic's key were ever removed, this would have
skipped Groq entirely despite Groq being the intended primary. Changed to
only bail if BOTH keys are missing.

Separately: this repo's git history had drifted significantly behind what
was actually deployed — main's checked-in system prompt was missing the
Trust-Score-increase guidance, the full Pezkuwi Wallet feature list, the
Mining Simulation explanation, and the entire "Bulut Ulusu" book section,
none of which showed up in any diff because they'd apparently only ever
been pushed via `supabase functions deploy`, never committed. Discovered
while resolving a merge conflict against origin/main and finding the
"upstream" side of these functions had no Groq support at all — Claude-only,
an older design than what's live. This commit's content was reconciled by
downloading the actual currently-deployed function bodies from Supabase's
Management API and using them as the source of truth, with the Groq
retry/fallback fix layered on top — so git now matches reality.
2026-07-21 07:33:17 -07:00
SatoshiQaziMuhammed 801318e1bc Merge pull request #7 from pezkuwichain/fix/deposit-detection-cron
fix(deposits): stop runaway duplicate rows, fix check-deposits reliability
2026-07-12 19:26:02 -07:00
4 changed files with 117 additions and 49 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "pezkuwi-telegram-miniapp",
"version": "1.0.243",
"version": "1.0.242",
"type": "module",
"description": "Pezkuwichain Telegram Mini App - Forum, Announcements, Rewards",
"author": "Pezkuwichain Team",
+3 -3
View File
@@ -1,5 +1,5 @@
{
"version": "1.0.243",
"buildTime": "2026-07-19T16:57:33.951Z",
"buildNumber": 1784480253951
"version": "1.0.242",
"buildTime": "2026-07-21T14:51:23.002Z",
"buildNumber": 1784645483003
}
+52 -20
View File
@@ -150,6 +150,7 @@ Inside the Trust Score card there is a small "Mining Simulation" square with a d
- If your Trust Score is 0, the counter cannot start — the app shows a warning that your trust score must be greater than 0. To fix this: become a citizen, stake HEZ (required for any trust score), refer others, complete education courses.
- Colors: red square = inactive (tap to start), gold = actively mining.
- The small Telegram icon next to it opens the official channel: https://t.me/+DUWJ8wtt5qI4Njgy
- IMPORTANT — how to talk about this: state that it's a simulation/estimate ONCE, briefly, near the start of your answer, then move on and explain the rest normally. Do NOT repeat "this isn't real mining" / "it's just an estimate" / similar caveats in every paragraph — one clear mention is enough, repeating it reads as nagging.
"BULUT ULUSU" (CLOUD NATION) — THE BOOK BEHIND PEZKUWICHAIN (chapter-by-chapter knowledge):
PezkuwiChain's philosophical foundation is the book "Bulut Ulusu" (Cloud Nation), written by the project's architect (a software developer AND sociologist — the "two desks" of the opening chapter). Available in Turkish, English and Kurdish. Core theses:
@@ -228,6 +229,56 @@ async function allowed(ip: string): Promise<boolean> {
return true;
}
// Groq's openai/gpt-oss-120b returns intermittent errors under load (429/5xx,
// and even a raw 502 from the edge runtime once) unrelated to the question
// asked — confirmed live 2026-07-21 by hitting this endpoint repeatedly with
// trivial questions ("merhaba") and seeing a ~50% failure rate with 15s+
// between calls (ruling out our own per-IP rate limiter above), which 2
// retries on the same model did not fully fix.
//
// 2026-07-21, user decision: prioritize reliability over gpt-oss-120b's
// better Turkish/Kurdish fluency (it was picked for that reason via an
// earlier A/B test) — llama-3.1-8b-instant is Groq's smallest/fastest model
// and, being long out of preview, has historically the best free-tier
// availability, so it goes first. gpt-oss-120b stays as the 2nd attempt
// (still worth trying for quality when the primary is having its own bad
// moment), llama-3.3-70b-versatile (the model used before switching to
// gpt-oss-120b) as the 3rd, before ever reaching the Anthropic fallback
// below. Doesn't retry a 4xx (bad request/auth) at all — not transient, and
// switching models wouldn't help.
const GROQ_MODELS = ['llama-3.1-8b-instant', 'openai/gpt-oss-120b', 'llama-3.3-70b-versatile'];
async function callGroqWithRetry(messages: unknown[], retriesPerModel = 2): Promise<string | null> {
for (const model of GROQ_MODELS) {
for (let attempt = 0; attempt <= retriesPerModel; attempt++) {
try {
const gr = await fetch('https://api.groq.com/openai/v1/chat/completions', {
method: 'POST',
headers: { Authorization: 'Bearer ' + GROQ_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
model,
temperature: 0.3,
max_tokens: 900,
messages: [{ role: 'system', content: SYSTEM }, ...messages],
}),
});
if (gr.ok) {
const gd = await gr.json();
const reply = gd.choices?.[0]?.message?.content || null;
if (reply) return reply;
} else {
console.error('[AI] Groq error:', model, gr.status, await gr.text());
if (gr.status !== 429 && gr.status < 500) break; // non-transient, try next model instead
}
} catch (e) {
console.error('[AI] Groq exception:', model, e);
}
if (attempt < retriesPerModel) await new Promise((r) => setTimeout(r, 400 * (attempt + 1)));
}
}
return null;
}
serve(async (req) => {
if (req.method === 'OPTIONS') return new Response('ok', { headers: CORS });
if (req.method !== 'POST') return J({ error: 'method' }, 405);
@@ -255,26 +306,7 @@ serve(async (req) => {
let answer: string | null = null;
if (GROQ_API_KEY) {
try {
const gr = await fetch('https://api.groq.com/openai/v1/chat/completions', {
method: 'POST',
headers: { Authorization: 'Bearer ' + GROQ_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'openai/gpt-oss-120b',
temperature: 0.3,
max_tokens: 900,
messages: [{ role: 'system', content: SYSTEM }, ...messages],
}),
});
if (gr.ok) {
const gd = await gr.json();
answer = gd.choices?.[0]?.message?.content || null;
} else {
console.error('[AI] Groq error:', gr.status, await gr.text());
}
} catch (e) {
console.error('[AI] Groq exception:', e);
}
answer = await callGroqWithRetry(messages);
}
if (!answer && ANTHROPIC_API_KEY) {
+61 -25
View File
@@ -230,6 +230,7 @@ Inside the Trust Score card there is a small "Mining Simulation" square with a d
- If your Trust Score is 0, the counter cannot start — the app shows a warning that your trust score must be greater than 0. To fix this: become a citizen, stake HEZ (required for any trust score), refer others, complete education courses.
- Colors: red square = inactive (tap to start), gold = actively mining.
- The small Telegram icon next to it opens the official channel: https://t.me/+DUWJ8wtt5qI4Njgy
- IMPORTANT — how to talk about this: state that it's a simulation/estimate ONCE, briefly, near the start of your answer, then move on and explain the rest normally. Do NOT repeat "this isn't real mining" / "it's just an estimate" / similar caveats in every paragraph — one clear mention is enough, repeating it reads as nagging.
"BULUT ULUSU" (CLOUD NATION) — THE BOOK BEHIND PEZKUWICHAIN (chapter-by-chapter knowledge):
PezkuwiChain's philosophical foundation is the book "Bulut Ulusu" (Cloud Nation), written by the project's architect (a software developer AND sociologist — the "two desks" of the opening chapter). Available in Turkish, English and Kurdish. Core theses:
@@ -269,9 +270,66 @@ Phase 4 (2028+): Cross-chain governance federation, decentralized identity, stab
License: Apache 2.0, Copyright 2026 Kurdistan Tech Institute. Lead Architect: SatoshiQaziMuhammed.`;
// ── Claude AI chat handler ──────────────────────────────────────────
// Groq's openai/gpt-oss-120b returns intermittent errors under load (429/5xx,
// and even a raw 502 from the edge runtime once) unrelated to the question
// asked — confirmed live 2026-07-21 by hitting this endpoint repeatedly with
// trivial questions ("merhaba") and seeing a ~50% failure rate with 15s+
// between calls (ruling out our own per-IP rate limiter), which 2 retries on
// the same model did not fully fix.
//
// 2026-07-21, user decision: prioritize reliability over gpt-oss-120b's
// better Turkish/Kurdish fluency (it was picked for that reason via an
// earlier A/B test) — llama-3.1-8b-instant is Groq's smallest/fastest model
// and, being long out of preview, has historically the best free-tier
// availability, so it goes first. gpt-oss-120b stays as the 2nd attempt
// (still worth trying for quality when the primary is having its own bad
// moment), llama-3.3-70b-versatile (the model used before switching to
// gpt-oss-120b) as the 3rd, before ever reaching the Anthropic fallback
// below. Retries a 4xx (bad request/auth) not at all — that's not transient
// and switching models wouldn't help either.
const GROQ_MODELS = ['llama-3.1-8b-instant', 'openai/gpt-oss-120b', 'llama-3.3-70b-versatile'];
async function callGroqWithRetry(
systemPrompt: string,
userMessage: string,
retriesPerModel = 2
): Promise<string | null> {
for (const model of GROQ_MODELS) {
for (let attempt = 0; attempt <= retriesPerModel; attempt++) {
try {
const gr = await fetch('https://api.groq.com/openai/v1/chat/completions', {
method: 'POST',
headers: { Authorization: 'Bearer ' + GROQ_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
model,
temperature: 0.3,
max_tokens: 900,
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userMessage },
],
}),
});
if (gr.ok) {
const gd = await gr.json();
const reply = gd.choices?.[0]?.message?.content || null;
if (reply) return reply;
} else {
console.error('[AI] Groq error:', model, gr.status, await gr.text());
if (gr.status !== 429 && gr.status < 500) break; // non-transient, try next model instead
}
} catch (e) {
console.error('[AI] Groq exception:', model, e);
}
if (attempt < retriesPerModel) await new Promise((r) => setTimeout(r, 400 * (attempt + 1)));
}
}
return null;
}
// ── AI chat handler ──────────────────────────────────────────
async function handleAIChat(token: string, chatId: number, userMessage: string, userName: string) {
if (!ANTHROPIC_API_KEY) {
if (!GROQ_API_KEY && !ANTHROPIC_API_KEY) {
await sendTelegramRequest(token, 'sendMessage', {
chat_id: chatId,
text: 'AI assistant is being configured. Please try again later.',
@@ -290,29 +348,7 @@ async function handleAIChat(token: string, chatId: number, userMessage: string,
let aiReply: string | null = null;
if (GROQ_API_KEY) {
try {
const gr = await fetch('https://api.groq.com/openai/v1/chat/completions', {
method: 'POST',
headers: { Authorization: 'Bearer ' + GROQ_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'openai/gpt-oss-120b',
temperature: 0.3,
max_tokens: 900,
messages: [
{ role: 'system', content: CLAUDE_SYSTEM_PROMPT },
{ role: 'user', content: userMessage },
],
}),
});
if (gr.ok) {
const gd = await gr.json();
aiReply = gd.choices?.[0]?.message?.content || null;
} else {
console.error('[AI] Groq error:', gr.status, await gr.text());
}
} catch (e) {
console.error('[AI] Groq exception:', e);
}
aiReply = await callGroqWithRetry(CLAUDE_SYSTEM_PROMPT, userMessage);
}
if (!aiReply && ANTHROPIC_API_KEY) {