Skip to content

Commit 05e36dd

Browse files
feat: low level balance error improvements
feat: low level balance error improvements
2 parents d17b93f + 512f58a commit 05e36dd

File tree

7 files changed

+104
-18
lines changed

7 files changed

+104
-18
lines changed

.changeset/fine-bars-sleep.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@kilocode/cli": patch
3+
---
4+
5+
Improve low balance message and added a retry action

cli/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"i18next": "^25.0.0",
7171
"ignore": "^7.0.3",
7272
"ink": "^6.3.1",
73+
"ink-link": "^5.0.0",
7374
"ink-select-input": "^6.2.0",
7475
"ink-spinner": "^5.0.0",
7576
"ink-table": "^3.1.0",

cli/src/state/atoms/approval.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ export const approvalOptionsAtom = atom<ApprovalOption[]>((get) => {
187187

188188
return options
189189
}
190+
} else if (pendingMessage.ask === "payment_required_prompt") {
191+
approveLabel = "Retry"
190192
}
191193

192194
return [

cli/src/state/atoms/ui.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ export const lastAskMessageAtom = atom<ExtensionChatMessage | null>((get) => {
266266
const messages = get(chatMessagesAtom)
267267

268268
// Ask types that require user approval
269-
const approvalAskTypes = ["tool", "command", "browser_action_launch", "use_mcp_server"]
269+
const approvalAskTypes = ["tool", "command", "browser_action_launch", "use_mcp_server", "payment_required_prompt"]
270270

271271
const lastMessage = messages[messages.length - 1]
272272
if (

cli/src/state/hooks/useApprovalHandler.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,20 @@ export function useApprovalHandler(): UseApprovalHandlerReturn {
154154
}
155155
store.set(updateChatMessageByTsAtom, answeredMessage)
156156

157+
// Determine response type based on ask type
158+
// payment_required_prompt needs special "retry_clicked" response
159+
const responseType =
160+
currentPendingApproval.ask === "payment_required_prompt" ? "retry_clicked" : "yesButtonClicked"
161+
157162
await sendAskResponse({
158-
response: "yesButtonClicked",
163+
response: responseType,
159164
...(text && { text }),
160165
...(images && { images }),
161166
})
162167

163168
logs.debug("Approval response sent successfully", "useApprovalHandler", {
164169
ts: currentPendingApproval.ts,
170+
responseType,
165171
})
166172

167173
// Track manual approval

cli/src/ui/messages/extension/ask/AskPaymentRequiredMessage.tsx

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,39 @@
11
import React from "react"
22
import { Box, Text } from "ink"
3+
import Link from "ink-link"
34
import type { MessageComponentProps } from "../types.js"
4-
import { getMessageIcon } from "../utils.js"
5-
import { MarkdownText } from "../../../components/MarkdownText.js"
65
import { useTheme } from "../../../../state/hooks/useTheme.js"
76
import { getBoxWidth } from "../../../utils/width.js"
7+
import { logs } from "../../../../services/logs.js"
8+
9+
interface PaymentRequiredData {
10+
title: string
11+
message: string
12+
balance: number
13+
buyCreditsUrl: string
14+
}
815

916
/**
10-
* Display low credit warning with payment icon
17+
* Display payment required message with parsed JSON data
18+
* Shows title, message, balance, and URL for adding credits
1119
*/
1220
export const AskPaymentRequiredMessage: React.FC<MessageComponentProps> = ({ message }) => {
1321
const theme = useTheme()
14-
const icon = getMessageIcon("ask", "payment_required_prompt")
22+
23+
// Parse JSON data with error handling and fallback values
24+
let data: PaymentRequiredData = {
25+
title: "Payment Required",
26+
message: "Credits are required to continue.",
27+
balance: 0,
28+
buyCreditsUrl: "",
29+
}
30+
31+
try {
32+
const parsed = JSON.parse(message.text ?? "{}")
33+
data = { ...data, ...parsed }
34+
} catch (e) {
35+
logs.error("Failed to parse payment_required_prompt data", "AskPaymentRequiredMessage", { error: e })
36+
}
1537

1638
return (
1739
<Box
@@ -21,29 +43,34 @@ export const AskPaymentRequiredMessage: React.FC<MessageComponentProps> = ({ mes
2143
borderColor={theme.semantic.warning}
2244
paddingX={1}
2345
marginY={1}>
46+
{/* Header with $ icon and dynamic title */}
2447
<Box>
2548
<Text color={theme.semantic.warning} bold>
26-
{icon} Low Credit Warning
49+
$ {data.title}
2750
</Text>
2851
</Box>
2952

30-
{message.text && (
53+
{/* Main message content */}
54+
{data.message && (
3155
<Box marginTop={1}>
32-
<MarkdownText>{message.text}</MarkdownText>
56+
<Text color={theme.ui.text.primary}>{data.message}</Text>
3357
</Box>
3458
)}
3559

36-
<Box marginTop={1}>
37-
<Text color={theme.ui.text.dimmed} dimColor>
38-
Your account is running low on credits. Please add more credits to continue.
60+
{/* Balance display in bordered box */}
61+
<Box marginTop={1} borderStyle="single" borderColor={theme.semantic.info} paddingX={1} paddingY={0}>
62+
<Text color={theme.semantic.info} bold>
63+
Current Balance: ${data.balance.toFixed(2)}
3964
</Text>
4065
</Box>
4166

42-
{message.isAnswered && (
43-
<Box marginTop={1}>
44-
<Text color={theme.ui.text.dimmed} dimColor>
45-
✓ Answered
46-
</Text>
67+
{/* URL section for adding credits */}
68+
{data.buyCreditsUrl && (
69+
<Box flexDirection="column" marginTop={1}>
70+
<Link url={data.buyCreditsUrl}>
71+
<Text color={theme.ui.text.primary}>Add Credits:</Text>
72+
<Text color={theme.semantic.info}> {data.buyCreditsUrl}</Text>
73+
</Link>
4774
</Box>
4875
)}
4976
</Box>

pnpm-lock.yaml

Lines changed: 46 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)