Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions packages/ui/src/components/session-retry.tsx
Original file line number Diff line number Diff line change
@@ -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>
)
}
3 changes: 3 additions & 0 deletions packages/ui/src/components/session-turn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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">
Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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": "إضافة رصيد",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/br.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/bs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/da.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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": "クレジットを追加",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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": "크레딧 추가",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/no.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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": "Добавить кредиты",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/th.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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": "เพิ่มเครดิต",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/tr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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": "添加积分",

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/i18n/zht.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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": "新增點數",

Expand Down
Loading