mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-30 05:43:55 +00:00
fix(app): show proper usage limit errors (#15496)
This commit is contained in:
parent
c4c0b23bff
commit
438610aa64
74
packages/ui/src/components/session-retry.tsx
Normal file
74
packages/ui/src/components/session-retry.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
import { createEffect, createMemo, createSignal, on, onCleanup, Show } from "solid-js"
|
||||
import type { SessionStatus } from "@opencode-ai/sdk/v2/client"
|
||||
import { useI18n } from "../context/i18n"
|
||||
import { Card } from "./card"
|
||||
import { Tooltip } from "./tooltip"
|
||||
import { Spinner } from "./spinner"
|
||||
|
||||
export function SessionRetry(props: { status: SessionStatus; show?: boolean }) {
|
||||
const i18n = useI18n()
|
||||
const retry = createMemo(() => {
|
||||
if (props.status.type !== "retry") return
|
||||
return props.status
|
||||
})
|
||||
const [seconds, setSeconds] = createSignal(0)
|
||||
createEffect(
|
||||
on(retry, (current) => {
|
||||
if (!current) return
|
||||
const update = () => {
|
||||
const next = retry()?.next
|
||||
if (!next) return
|
||||
setSeconds(Math.round((next - Date.now()) / 1000))
|
||||
}
|
||||
update()
|
||||
const timer = setInterval(update, 1000)
|
||||
onCleanup(() => clearInterval(timer))
|
||||
}),
|
||||
)
|
||||
const message = createMemo(() => {
|
||||
const current = retry()
|
||||
if (!current) return ""
|
||||
if (current.message.includes("exceeded your current quota") && current.message.includes("gemini")) {
|
||||
return i18n.t("ui.sessionTurn.retry.geminiHot")
|
||||
}
|
||||
if (current.message.length > 80) return current.message.slice(0, 80) + "..."
|
||||
return current.message
|
||||
})
|
||||
const truncated = createMemo(() => {
|
||||
const current = retry()
|
||||
if (!current) return false
|
||||
return current.message.length > 80
|
||||
})
|
||||
const info = createMemo(() => {
|
||||
const current = retry()
|
||||
if (!current) return ""
|
||||
const count = Math.max(0, seconds())
|
||||
const delay = count > 0 ? i18n.t("ui.sessionTurn.retry.inSeconds", { seconds: count }) : ""
|
||||
const retrying = i18n.t("ui.sessionTurn.retry.retrying")
|
||||
const line = [retrying, delay].filter(Boolean).join(" ")
|
||||
if (!line) return i18n.t("ui.sessionTurn.retry.attempt", { attempt: current.attempt })
|
||||
return i18n.t("ui.sessionTurn.retry.attemptLine", { line, attempt: current.attempt })
|
||||
})
|
||||
|
||||
return (
|
||||
<Show when={retry() && (props.show ?? true)}>
|
||||
<div data-slot="session-turn-retry">
|
||||
<Card variant="error" class="error-card">
|
||||
<div class="flex items-start gap-2">
|
||||
<Spinner class="size-4 mt-0.5" />
|
||||
<div class="min-w-0">
|
||||
<Show when={truncated()} fallback={<div data-slot="session-turn-retry-message">{message()}</div>}>
|
||||
<Tooltip value={retry()?.message ?? ""} placement="top">
|
||||
<div data-slot="session-turn-retry-message" class="cursor-help truncate">
|
||||
{message()}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Show>
|
||||
<Show when={info()}>{(line) => <div data-slot="session-turn-retry-info">{line()}</div>}</Show>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</Show>
|
||||
)
|
||||
}
|
||||
@ -14,6 +14,7 @@ import { Collapsible } from "./collapsible"
|
||||
import { DiffChanges } from "./diff-changes"
|
||||
import { Icon } from "./icon"
|
||||
import { TextShimmer } from "./text-shimmer"
|
||||
import { SessionRetry } from "./session-retry"
|
||||
import { createAutoScroll } from "../hooks"
|
||||
import { useI18n } from "../context/i18n"
|
||||
|
||||
@ -332,6 +333,7 @@ export function SessionTurn(
|
||||
)
|
||||
const showThinking = createMemo(() => {
|
||||
if (!working() || !!error()) return false
|
||||
if (status().type === "retry") return false
|
||||
if (showReasoningSummaries()) return assistantVisible() === 0
|
||||
if (assistantTailVisible() === "text") return false
|
||||
return true
|
||||
@ -384,6 +386,7 @@ export function SessionTurn(
|
||||
</Show>
|
||||
</div>
|
||||
</Show>
|
||||
<SessionRetry status={status()} show={isLastUserMessage()} />
|
||||
<Show when={edited() > 0 && !working()}>
|
||||
<div data-slot="session-turn-diffs">
|
||||
<Collapsible open={open()} onOpenChange={setOpen} variant="ghost">
|
||||
|
||||
@ -40,6 +40,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "إعادة المحاولة",
|
||||
"ui.sessionTurn.retry.inSeconds": "خلال {{seconds}} ثواني",
|
||||
"ui.sessionTurn.retry.attempt": "المحاولة رقم {{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - المحاولة رقم {{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini مزدحم حاليا",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "تم تجاوز حد الاستخدام المجاني",
|
||||
"ui.sessionTurn.error.addCredits": "إضافة رصيد",
|
||||
|
||||
|
||||
@ -40,6 +40,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "tentando novamente",
|
||||
"ui.sessionTurn.retry.inSeconds": "em {{seconds}}s",
|
||||
"ui.sessionTurn.retry.attempt": "tentativa #{{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - tentativa #{{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini está muito sobrecarregado agora",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "Limite de uso gratuito excedido",
|
||||
"ui.sessionTurn.error.addCredits": "Adicionar créditos",
|
||||
|
||||
|
||||
@ -44,6 +44,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "ponovni pokušaj",
|
||||
"ui.sessionTurn.retry.inSeconds": "za {{seconds}}s",
|
||||
"ui.sessionTurn.retry.attempt": "pokušaj #{{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - pokušaj #{{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini je trenutno preopterećen",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "Besplatna upotreba premašena",
|
||||
"ui.sessionTurn.error.addCredits": "Dodaj kredite",
|
||||
|
||||
|
||||
@ -39,6 +39,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "prøver igen",
|
||||
"ui.sessionTurn.retry.inSeconds": "om {{seconds}}s",
|
||||
"ui.sessionTurn.retry.attempt": "forsøg #{{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - forsøg #{{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini er meget overbelastet lige nu",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "Gratis forbrug overskredet",
|
||||
"ui.sessionTurn.error.addCredits": "Tilføj kreditter",
|
||||
|
||||
|
||||
@ -45,6 +45,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "erneuter Versuch",
|
||||
"ui.sessionTurn.retry.inSeconds": "in {{seconds}}s",
|
||||
"ui.sessionTurn.retry.attempt": "Versuch #{{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - Versuch #{{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini ist gerade sehr überlastet",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "Kostenloses Nutzungslimit überschritten",
|
||||
"ui.sessionTurn.error.addCredits": "Guthaben aufladen",
|
||||
|
||||
|
||||
@ -41,6 +41,9 @@ export const dict: Record<string, string> = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "retrying",
|
||||
"ui.sessionTurn.retry.inSeconds": "in {{seconds}}s",
|
||||
"ui.sessionTurn.retry.attempt": "attempt #{{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - attempt #{{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini is way too hot right now",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "Free usage exceeded",
|
||||
"ui.sessionTurn.error.addCredits": "Add credits",
|
||||
|
||||
|
||||
@ -40,6 +40,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "reintentando",
|
||||
"ui.sessionTurn.retry.inSeconds": "en {{seconds}}s",
|
||||
"ui.sessionTurn.retry.attempt": "intento #{{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - intento #{{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini está demasiado saturado",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "Límite de uso gratuito excedido",
|
||||
"ui.sessionTurn.error.addCredits": "Añadir créditos",
|
||||
|
||||
|
||||
@ -40,6 +40,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "nouvelle tentative",
|
||||
"ui.sessionTurn.retry.inSeconds": "dans {{seconds}}s",
|
||||
"ui.sessionTurn.retry.attempt": "tentative n°{{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - tentative n°{{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini est en surchauffe",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "Limite d'utilisation gratuite dépassée",
|
||||
"ui.sessionTurn.error.addCredits": "Ajouter des crédits",
|
||||
|
||||
|
||||
@ -39,6 +39,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "再試行中",
|
||||
"ui.sessionTurn.retry.inSeconds": "{{seconds}}秒後",
|
||||
"ui.sessionTurn.retry.attempt": "{{attempt}}回目",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - {{attempt}}回目",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini が混雑しています",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "無料使用制限に達しました",
|
||||
"ui.sessionTurn.error.addCredits": "クレジットを追加",
|
||||
|
||||
|
||||
@ -40,6 +40,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "재시도 중",
|
||||
"ui.sessionTurn.retry.inSeconds": "{{seconds}}초 후",
|
||||
"ui.sessionTurn.retry.attempt": "{{attempt}}번째",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - {{attempt}}번째",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini가 현재 과부하 상태입니다",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "무료 사용량 초과",
|
||||
"ui.sessionTurn.error.addCredits": "크레딧 추가",
|
||||
|
||||
|
||||
@ -43,6 +43,9 @@ export const dict: Record<Keys, string> = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "Prøver igjen",
|
||||
"ui.sessionTurn.retry.inSeconds": "om {{seconds}}s",
|
||||
"ui.sessionTurn.retry.attempt": "forsøk #{{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - forsøk #{{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini er veldig overbelastet nå",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "Gratis bruk overskredet",
|
||||
"ui.sessionTurn.error.addCredits": "Legg til kreditt",
|
||||
|
||||
|
||||
@ -39,6 +39,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "ponawianie",
|
||||
"ui.sessionTurn.retry.inSeconds": "za {{seconds}}s",
|
||||
"ui.sessionTurn.retry.attempt": "próba #{{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - próba #{{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini jest teraz mocno przeciążony",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "Przekroczono limit darmowego użytkowania",
|
||||
"ui.sessionTurn.error.addCredits": "Dodaj kredyty",
|
||||
|
||||
|
||||
@ -39,6 +39,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "повтор",
|
||||
"ui.sessionTurn.retry.inSeconds": "через {{seconds}}с",
|
||||
"ui.sessionTurn.retry.attempt": "попытка №{{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - попытка №{{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini сейчас перегружен",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "Лимит бесплатного использования превышен",
|
||||
"ui.sessionTurn.error.addCredits": "Добавить кредиты",
|
||||
|
||||
|
||||
@ -41,6 +41,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "กำลังลองใหม่",
|
||||
"ui.sessionTurn.retry.inSeconds": "ใน {{seconds}}วิ",
|
||||
"ui.sessionTurn.retry.attempt": "ครั้งที่ {{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - ครั้งที่ {{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini กำลังใช้งานหนาแน่นมาก",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "เกินขีดจำกัดการใช้งานฟรี",
|
||||
"ui.sessionTurn.error.addCredits": "เพิ่มเครดิต",
|
||||
|
||||
|
||||
@ -36,6 +36,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "yeniden deneniyor",
|
||||
"ui.sessionTurn.retry.inSeconds": "{{seconds}}sn içinde",
|
||||
"ui.sessionTurn.retry.attempt": "deneme #{{attempt}}",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - deneme #{{attempt}}",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini şu anda aşırı yoğun",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "Ücretsiz kullanım aşıldı",
|
||||
"ui.sessionTurn.error.addCredits": "Kredi ekle",
|
||||
|
||||
|
||||
@ -44,6 +44,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "重试中",
|
||||
"ui.sessionTurn.retry.inSeconds": "{{seconds}} 秒后",
|
||||
"ui.sessionTurn.retry.attempt": "第 {{attempt}} 次",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - 第 {{attempt}} 次",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini 当前过载",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "免费使用额度已用完",
|
||||
"ui.sessionTurn.error.addCredits": "添加积分",
|
||||
|
||||
|
||||
@ -44,6 +44,9 @@ export const dict = {
|
||||
|
||||
"ui.sessionTurn.retry.retrying": "重試中",
|
||||
"ui.sessionTurn.retry.inSeconds": "{{seconds}} 秒後",
|
||||
"ui.sessionTurn.retry.attempt": "第 {{attempt}} 次",
|
||||
"ui.sessionTurn.retry.attemptLine": "{{line}} - 第 {{attempt}} 次",
|
||||
"ui.sessionTurn.retry.geminiHot": "gemini 目前過載",
|
||||
"ui.sessionTurn.error.freeUsageExceeded": "免費使用額度已用完",
|
||||
"ui.sessionTurn.error.addCredits": "新增點數",
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user