Skip to content

Commit 94fa33b

Browse files
authored
Add announcement for Sonic model (#7244)
1 parent 1f7ae54 commit 94fa33b

File tree

21 files changed

+207
-95
lines changed

21 files changed

+207
-95
lines changed

src/core/webview/ClineProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export class ClineProvider
120120

121121
public isViewLaunched = false
122122
public settingsImportedAt?: number
123-
public readonly latestAnnouncementId = "jul-29-2025-3-25-0" // Update for v3.25.0 announcement
123+
public readonly latestAnnouncementId = "aug-20-2025-stealth-model" // Update for stealth model announcement
124124
public readonly providerSettingsManager: ProviderSettingsManager
125125
public readonly customModesManager: CustomModesManager
126126

webview-ui/src/components/chat/Announcement.tsx

Lines changed: 47 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import { Trans } from "react-i18next"
33
import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"
44

55
import { Package } from "@roo/package"
6-
76
import { useAppTranslation } from "@src/i18n/TranslationContext"
8-
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@src/components/ui"
7+
import { useExtensionState } from "@src/context/ExtensionStateContext"
8+
import { vscode } from "@src/utils/vscode"
9+
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@src/components/ui"
10+
import { Button } from "@src/components/ui"
911

1012
interface AnnouncementProps {
1113
hideAnnouncement: () => void
@@ -23,6 +25,7 @@ interface AnnouncementProps {
2325
const Announcement = ({ hideAnnouncement }: AnnouncementProps) => {
2426
const { t } = useAppTranslation()
2527
const [open, setOpen] = useState(true)
28+
const { cloudIsAuthenticated } = useExtensionState()
2629

2730
return (
2831
<Dialog
@@ -37,98 +40,64 @@ const Announcement = ({ hideAnnouncement }: AnnouncementProps) => {
3740
<DialogContent className="max-w-96">
3841
<DialogHeader>
3942
<DialogTitle>{t("chat:announcement.title", { version: Package.version })}</DialogTitle>
40-
<DialogDescription>
41-
{t("chat:announcement.description", { version: Package.version })}
42-
</DialogDescription>
4343
</DialogHeader>
4444
<div>
45-
<h3>{t("chat:announcement.whatsNew")}</h3>
4645
<ul className="space-y-2">
4746
<li>
4847
{" "}
4948
<Trans
50-
i18nKey="chat:announcement.feature1"
51-
components={{
52-
bold: <b />,
53-
code: <code />,
54-
settingsLink: (
55-
<VSCodeLink
56-
href="#"
57-
onClick={(e) => {
58-
e.preventDefault()
59-
setOpen(false)
60-
hideAnnouncement()
61-
window.postMessage(
62-
{
63-
type: "action",
64-
action: "settingsButtonClicked",
65-
values: { section: "codebaseIndexing" },
66-
},
67-
"*",
68-
)
69-
}}
70-
/>
71-
),
72-
}}
73-
/>
74-
</li>
75-
<li>
76-
{" "}
77-
<Trans
78-
i18nKey="chat:announcement.feature2"
79-
components={{
80-
bold: <b />,
81-
code: <code />,
82-
}}
83-
/>
84-
</li>
85-
<li>
86-
{" "}
87-
<Trans
88-
i18nKey="chat:announcement.feature3"
49+
i18nKey="chat:announcement.stealthModel.feature"
8950
components={{
9051
bold: <b />,
91-
code: <code />,
9252
}}
9353
/>
9454
</li>
9555
</ul>
96-
<Trans
97-
i18nKey="chat:announcement.detailsDiscussLinks"
98-
components={{ discordLink: <DiscordLink />, redditLink: <RedditLink /> }}
99-
/>
56+
57+
<p className="text-xs text-muted-foreground mt-2">{t("chat:announcement.stealthModel.note")}</p>
58+
59+
<div className="mt-4">
60+
{!cloudIsAuthenticated ? (
61+
<Button
62+
onClick={() => {
63+
vscode.postMessage({ type: "rooCloudSignIn" })
64+
}}
65+
className="w-full">
66+
{t("chat:announcement.stealthModel.connectButton")}
67+
</Button>
68+
) : (
69+
<div className="text-sm w-full">
70+
<Trans
71+
i18nKey="chat:announcement.stealthModel.selectModel"
72+
components={{
73+
code: <code className="px-1 py-0.5 bg-gray-100 dark:bg-gray-800 rounded" />,
74+
settingsLink: (
75+
<VSCodeLink
76+
href="#"
77+
onClick={(e) => {
78+
e.preventDefault()
79+
setOpen(false)
80+
hideAnnouncement()
81+
window.postMessage(
82+
{
83+
type: "action",
84+
action: "settingsButtonClicked",
85+
values: { section: "provider" },
86+
},
87+
"*",
88+
)
89+
}}
90+
/>
91+
),
92+
}}
93+
/>
94+
</div>
95+
)}
96+
</div>
10097
</div>
10198
</DialogContent>
10299
</Dialog>
103100
)
104101
}
105102

106-
const DiscordLink = () => (
107-
<VSCodeLink
108-
href="https://discord.gg/roocode"
109-
onClick={(e) => {
110-
e.preventDefault()
111-
window.postMessage(
112-
{ type: "action", action: "openExternal", data: { url: "https://discord.gg/roocode" } },
113-
"*",
114-
)
115-
}}>
116-
Discord
117-
</VSCodeLink>
118-
)
119-
120-
const RedditLink = () => (
121-
<VSCodeLink
122-
href="https://reddit.com/r/RooCode"
123-
onClick={(e) => {
124-
e.preventDefault()
125-
window.postMessage(
126-
{ type: "action", action: "openExternal", data: { url: "https://reddit.com/r/RooCode" } },
127-
"*",
128-
)
129-
}}>
130-
Reddit
131-
</VSCodeLink>
132-
)
133-
134103
export default memo(Announcement)

webview-ui/src/components/chat/__tests__/Announcement.spec.tsx

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,37 +11,79 @@ vi.mock("@src/components/ui", () => ({
1111
DialogDescription: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
1212
DialogHeader: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
1313
DialogTitle: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
14+
DialogFooter: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
15+
Button: ({ children, onClick }: { children: React.ReactNode; onClick?: () => void }) => (
16+
<button onClick={onClick}>{children}</button>
17+
),
1418
}))
1519

16-
// Mock the useAppTranslation hook
20+
// Mock the useAppTranslation hook and Trans component
1721
vi.mock("@src/i18n/TranslationContext", () => ({
1822
useAppTranslation: () => ({
1923
t: (key: string, options?: { version: string }) => {
2024
if (key === "chat:announcement.title") {
2125
return `🎉 Roo Code ${options?.version} Released`
2226
}
23-
if (key === "chat:announcement.description") {
24-
return `Roo Code ${options?.version} brings powerful new features and improvements based on your feedback.`
27+
if (key === "chat:announcement.stealthModel.feature") {
28+
return "Stealth reasoning model with advanced capabilities"
29+
}
30+
if (key === "chat:announcement.stealthModel.note") {
31+
return "Note: This is an experimental feature"
32+
}
33+
if (key === "chat:announcement.stealthModel.connectButton") {
34+
return "Connect to Roo Code Cloud"
2535
}
2636
// Return key for other translations not relevant to this test
2737
return key
2838
},
2939
}),
3040
}))
3141

42+
// Mock react-i18next Trans component
43+
vi.mock("react-i18next", () => ({
44+
Trans: ({ i18nKey, children }: { i18nKey?: string; children: React.ReactNode }) => {
45+
if (i18nKey === "chat:announcement.stealthModel.feature") {
46+
return <>Stealth reasoning model with advanced capabilities</>
47+
}
48+
if (i18nKey === "chat:announcement.stealthModel.selectModel") {
49+
return <>Please select the roo/sonic model in settings</>
50+
}
51+
return <>{children}</>
52+
},
53+
}))
54+
55+
// Mock VSCodeLink
56+
vi.mock("@vscode/webview-ui-toolkit/react", () => ({
57+
VSCodeLink: ({ children, onClick }: { children: React.ReactNode; onClick?: () => void }) => (
58+
<a onClick={onClick}>{children}</a>
59+
),
60+
}))
61+
62+
// Mock the useExtensionState hook
63+
vi.mock("@src/context/ExtensionStateContext", () => ({
64+
useExtensionState: () => ({
65+
apiConfiguration: null,
66+
cloudIsAuthenticated: false,
67+
}),
68+
}))
69+
3270
describe("Announcement", () => {
3371
const mockHideAnnouncement = vi.fn()
3472
const expectedVersion = Package.version
3573

3674
it("renders the announcement with the version number from package.json", () => {
3775
render(<Announcement hideAnnouncement={mockHideAnnouncement} />)
3876

39-
// Check if the mocked version number is present in the title and description
77+
// Check if the mocked version number is present in the title
4078
expect(screen.getByText(`🎉 Roo Code ${expectedVersion} Released`)).toBeInTheDocument()
41-
expect(
42-
screen.getByText(
43-
`Roo Code ${expectedVersion} brings powerful new features and improvements based on your feedback.`,
44-
),
45-
).toBeInTheDocument()
79+
80+
// Check if the stealth model feature is displayed (using partial match due to bullet point)
81+
expect(screen.getByText(/Stealth reasoning model with advanced capabilities/)).toBeInTheDocument()
82+
83+
// Check if the note is displayed
84+
expect(screen.getByText("Note: This is an experimental feature")).toBeInTheDocument()
85+
86+
// Check if the connect button is displayed (since cloudIsAuthenticated is false in the mock)
87+
expect(screen.getByText("Connect to Roo Code Cloud")).toBeInTheDocument()
4688
})
4789
})

webview-ui/src/i18n/locales/ca/chat.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/de/chat.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/en/chat.json

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -274,13 +274,12 @@
274274
},
275275
"announcement": {
276276
"title": "🎉 Roo Code {{version}} Released",
277-
"description": "Roo Code {{version}} brings powerful new features and significant improvements to enhance your development workflow.",
278-
"whatsNew": "What's New",
279-
"feature1": "<bold>Message Queueing</bold>: Queue multiple messages while Roo is working, allowing you to continue planning your workflow without interruption.",
280-
"feature2": "<bold>Custom Slash Commands</bold>: Create personalized slash commands for quick access to frequently used prompts and workflows, with full UI management.",
281-
"feature3": "<bold>Enhanced Gemini Tools</bold>: New URL context and Google Search grounding capabilities provide Gemini models with real-time web information and enhanced research abilities.",
282-
"hideButton": "Hide announcement",
283-
"detailsDiscussLinks": "Get more details and discuss in <discordLink>Discord</discordLink> and <redditLink>Reddit</redditLink> 🚀"
277+
"stealthModel": {
278+
"feature": "<bold>Limited-time FREE stealth model</bold> - A blazing fast reasoning model that excels at agentic coding with a 262k context window, available through Roo Code Cloud.",
279+
"note": "(Note: prompts and completions are logged by the model creator to improve the model)",
280+
"connectButton": "Connect to Roo Code Cloud",
281+
"selectModel": "Select <code>roo/sonic</code> from the Roo Code Cloud provider in<br/><settingsLink>Settings</settingsLink> to get started"
282+
}
284283
},
285284
"reasoning": {
286285
"thinking": "Thinking",

webview-ui/src/i18n/locales/es/chat.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/fr/chat.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/hi/chat.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/id/chat.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)