Repository navigation
feat(tui): show free-limit notice, recall prompt, and skip failure toast - #57467
Conversation
3564c3b to
744d516
Compare
a6142e0 to
e1a4dd2
Compare
744d516 to
1a5abbf
Compare
e1a4dd2 to
c9c33dd
Compare
c9c33dd to
086051f
Compare
There was a problem hiding this comment.
I ran the TUI from source with the simulated model returning a FreeUsageLimitError. On dev you get the red Error: line, a "Session failed" toast and an empty composer. With this PR you get the muted notice with /connect · /models, no toast, and the composer shows the submitted prompt again. The changed tests and the packages/tui type check pass.
Public API is unchanged; this is TUI rendering and plugin behaviour only.
Two concerns, both inline: free-limit failures now send no notification at all, which leaves background and unfocused sessions silent, and the first new lifecycle test is hard to follow.
Related: #52894
| errored.add(sessionID) | ||
| notify(context, sessionID, event.data.error.message, "error") | ||
| context.ui.toast.show({ sessionID, title: "Session failed", message: event.data.error.message, variant: "error" }) | ||
| if (event.data.error.type !== "provider.free-limit") { |
There was a problem hiding this comment.
This skips the desktop notification and the toast. Because errored is still set, ended() also skips the "Session done" notification. So when the TUI is unfocused, or the free limit hits a session the user isn't viewing (another tab, a subagent), nothing tells them the work stopped. The inline notice and the prompt recall only help once they open that session. Could we drop just the red toast and keep a neutral notification, e.g. notify(..., "Free usage limit reached", "error"), or show the toast only when sessionID isn't the session on screen?
| expect(setup.captureCharFrame()).toContain("Open plugins") | ||
| }) | ||
|
|
||
| test("free usage limit lists next steps, recalls the delivered prompt once, and skips the failure toast", async () => { |
There was a problem hiding this comment.
This test runs four scenarios one after another: the first recall, clearing plus a duplicate event, delivering the queued message, then a second failure. It checks each step by counting matches with frame.split(...).length === N, which makes it hard to follow and hard to debug when it fails. Could you cut it down to the core case (notice renders, the delivered prompt is recalled rather than the queued one, no Error:) and maybe one short test for the duplicate event? The Session failed check is already covered in notifications.test.ts.


Stack (merge in order):
feat(core): typed free-limit error with reset time(basedev)fix(app): restore free-tier usage limit dialog, timeline line, and prompt recall(merged)feat(tui): show free-limit notice, recall prompt, and skip failure toast(this PR, base feat(core): typed free-limit error with reset time #57146)feat(tui): restore animated Go upsell modal on free usage limit(base feat(tui): show free-limit notice, recall prompt, and skip failure toast #57467)Size: +281/−5 (4 files)
Related: #50996, #52894
Today
When the free allowance runs out in the TUI, the transcript shows a red
Error: Rate limit exceeded. Please try again later.line, the notifications plugin fires a redundant red"Session failed"toast, and the composer loses the prompt the user just submitted.After
AssistantFooterrendersFreeLimitNotice("You've used today's free messages. They reset at 5:00 PM."and"Upgrade to OpenCode Go → /connect · Switch model → /models") in muted text instead of a redError:line."Session failed"toast and desktop notification forprovider.free-limit.dev)How
packages/tui/src/routes/session/index.tsx: renderFreeLimitNoticewithfreeLimitResetonprovider.free-limitassistant messages, and recall the failed step's delivered user message once when the composer is empty.packages/tui/src/feature-plugins/system/notifications.ts: skip the error toast and notification whenevent.data.error.type === "provider.free-limit"while still marking the session execution as ended.Proof
packages/tui/test/app-lifecycle.test.tsx: verifiesFreeLimitNoticerenders the reset time and/connect·/modelsnext steps, recalls the delivered user prompt (not a queued one) once, does not re-restore on duplicate events, recalls the next turn's prompt on subsequent hits, and preserves an in-progress typing draft.packages/tui/test/cli/cmd/tui/notifications.test.ts: verifiessession.execution.failedwithprovider.free-limitdoes not emit a"Session failed"toast or system notification.Risk
Low. Only affects
provider.free-limitfailures in the TUI; all other session errors keep their red error line and"Session failed"toast.Added by the opencode bot (AI-generated).
Related: #52894