Skip to content

Commit 8c8a398

Browse files
celestial-vaultElephant Lumps
andauthored
Migrate webviewDidLaunch protobus (RooCodeInc#4063)
* migrate openRouterModels * remove conversion functions and unused imports * migrate webviewDidLaunch --------- Co-authored-by: Elephant Lumps <[email protected]>
1 parent 742a72b commit 8c8a398

File tree

5 files changed

+85
-46
lines changed

5 files changed

+85
-46
lines changed

proto/ui.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,7 @@ service UiService {
249249

250250
// Subscribe to theme change events
251251
rpc subscribeToTheme(EmptyRequest) returns (stream String);
252+
253+
// Initialize webview when it launches
254+
rpc initializeWebview(EmptyRequest) returns (Empty);
252255
}

src/core/controller/index.ts

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -207,48 +207,6 @@ export class Controller {
207207
await this.setUserInfo(message.user || undefined)
208208
await this.postStateToWebview()
209209
break
210-
case "webviewDidLaunch":
211-
this.postStateToWebview()
212-
this.workspaceTracker?.populateFilePaths() // don't await
213-
// post last cached models in case the call to endpoint fails
214-
this.readOpenRouterModels().then((openRouterModels) => {
215-
if (openRouterModels) {
216-
sendOpenRouterModelsEvent(OpenRouterCompatibleModelInfo.create({ models: openRouterModels }))
217-
}
218-
})
219-
// gui relies on model info to be up-to-date to provide the most accurate pricing, so we need to fetch the latest details on launch.
220-
// we do this for all users since many users switch between api providers and if they were to switch back to openrouter it would be showing outdated model info if we hadn't retrieved the latest at this point
221-
// (see normalizeApiConfiguration > openrouter)
222-
// Prefetch marketplace and OpenRouter models
223-
224-
getGlobalState(this.context, "mcpMarketplaceCatalog").then((mcpMarketplaceCatalog) => {
225-
if (mcpMarketplaceCatalog) {
226-
sendMcpMarketplaceCatalogEvent(mcpMarketplaceCatalog as McpMarketplaceCatalog)
227-
}
228-
})
229-
this.silentlyRefreshMcpMarketplace()
230-
handleModelsServiceRequest(this, "refreshOpenRouterModels", EmptyRequest.create()).then(async (response) => {
231-
if (response && response.models) {
232-
// update model info in state (this needs to be done here since we don't want to update state while settings is open, and we may refresh models there)
233-
const { apiConfiguration } = await getAllExtensionState(this.context)
234-
if (apiConfiguration.openRouterModelId && response.models[apiConfiguration.openRouterModelId]) {
235-
await updateGlobalState(
236-
this.context,
237-
"openRouterModelInfo",
238-
response.models[apiConfiguration.openRouterModelId],
239-
)
240-
await this.postStateToWebview()
241-
}
242-
}
243-
})
244-
245-
// Initialize telemetry service with user's current setting
246-
this.getStateToPostToWebview().then((state) => {
247-
const { telemetrySetting } = state
248-
const isOptedIn = telemetrySetting !== "disabled"
249-
telemetryService.updateTelemetryState(isOptedIn)
250-
})
251-
break
252210
case "newTask":
253211
// Code that should run in response to the hello message command
254212
//vscode.window.showInformationMessage(message.text!)
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import type { Controller } from "../index"
2+
import { EmptyRequest, Empty } from "@shared/proto/common"
3+
import { handleModelsServiceRequest } from "../models"
4+
import { getAllExtensionState, getGlobalState, updateGlobalState } from "../../storage/state"
5+
import { sendOpenRouterModelsEvent } from "../models/subscribeToOpenRouterModels"
6+
import { sendMcpMarketplaceCatalogEvent } from "../mcp/subscribeToMcpMarketplaceCatalog"
7+
import { telemetryService } from "@/services/posthog/telemetry/TelemetryService"
8+
import { OpenRouterCompatibleModelInfo } from "@/shared/proto/models"
9+
import { McpMarketplaceCatalog } from "@shared/mcp"
10+
11+
/**
12+
* Initialize webview when it launches
13+
* @param controller The controller instance
14+
* @param request The empty request
15+
* @returns Empty response
16+
*/
17+
export async function initializeWebview(controller: Controller, request: EmptyRequest): Promise<Empty> {
18+
try {
19+
// Populate file paths for workspace tracker (don't await)
20+
controller.workspaceTracker?.populateFilePaths()
21+
22+
// Post last cached models in case the call to endpoint fails
23+
controller.readOpenRouterModels().then((openRouterModels) => {
24+
if (openRouterModels) {
25+
sendOpenRouterModelsEvent(OpenRouterCompatibleModelInfo.create({ models: openRouterModels }))
26+
}
27+
})
28+
29+
// Refresh OpenRouter models from API
30+
handleModelsServiceRequest(controller, "refreshOpenRouterModels", EmptyRequest.create()).then(async (response) => {
31+
if (response && response.models) {
32+
// Update model info in state (this needs to be done here since we don't want to update state while settings is open, and we may refresh models there)
33+
const { apiConfiguration } = await getAllExtensionState(controller.context)
34+
if (apiConfiguration.openRouterModelId && response.models[apiConfiguration.openRouterModelId]) {
35+
await updateGlobalState(
36+
controller.context,
37+
"openRouterModelInfo",
38+
response.models[apiConfiguration.openRouterModelId],
39+
)
40+
await controller.postStateToWebview()
41+
}
42+
}
43+
})
44+
45+
// GUI relies on model info to be up-to-date to provide the most accurate pricing, so we need to fetch the latest details on launch.
46+
// We do this for all users since many users switch between api providers and if they were to switch back to openrouter it would be showing outdated model info if we hadn't retrieved the latest at this point
47+
// (see normalizeApiConfiguration > openrouter)
48+
// Prefetch marketplace and OpenRouter models
49+
50+
// Send cached MCP marketplace catalog if available
51+
getGlobalState(controller.context, "mcpMarketplaceCatalog").then((mcpMarketplaceCatalog) => {
52+
if (mcpMarketplaceCatalog) {
53+
sendMcpMarketplaceCatalogEvent(mcpMarketplaceCatalog as McpMarketplaceCatalog)
54+
}
55+
})
56+
57+
// Silently refresh MCP marketplace catalog
58+
controller.silentlyRefreshMcpMarketplace()
59+
60+
// Initialize telemetry service with user's current setting
61+
controller.getStateToPostToWebview().then((state) => {
62+
const { telemetrySetting } = state
63+
const isOptedIn = telemetrySetting !== "disabled"
64+
telemetryService.updateTelemetryState(isOptedIn)
65+
})
66+
67+
return Empty.create({})
68+
} catch (error) {
69+
console.error("Failed to initialize webview:", error)
70+
// Return empty response even on error to not break the frontend
71+
return Empty.create({})
72+
}
73+
}

src/shared/WebviewMessage.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { McpViewTab } from "./mcp"
99
export interface WebviewMessage {
1010
type:
1111
| "apiConfiguration"
12-
| "webviewDidLaunch"
1312
| "newTask"
1413
| "condense"
1514
| "reportBug"

webview-ui/src/context/ExtensionStateContext.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
import { McpMarketplaceCatalog, McpServer, McpViewTab } from "../../../src/shared/mcp"
2121
import { ModelsServiceClient, StateServiceClient, UiServiceClient, McpServiceClient } from "../services/grpc-client"
2222
import { convertTextMateToHljs } from "../utils/textMateToHljs"
23-
import { convertOpenRouterCompatibleModelInfoToModelInfoRecord } from "../../../src/shared/proto-conversions/models/openrouter-models-conversion"
2423
import { vscode } from "../utils/vscode"
2524
import { OpenRouterCompatibleModelInfo } from "@shared/proto/models"
2625

@@ -459,6 +458,7 @@ export const ExtensionStateContextProvider: React.FC<{
459458
// Subscribe to OpenRouter models updates
460459
openRouterModelsUnsubscribeRef.current = ModelsServiceClient.subscribeToOpenRouterModels(EmptyRequest.create({}), {
461460
onResponse: (response: OpenRouterCompatibleModelInfo) => {
461+
console.log("[DEBUG] Received OpenRouter models update from gRPC stream")
462462
const models = response.models
463463
setOpenRouterModels({
464464
[openRouterDefaultModelId]: openRouterDefaultModelInfo, // in case the extension sent a model list without the default model
@@ -473,8 +473,14 @@ export const ExtensionStateContextProvider: React.FC<{
473473
},
474474
})
475475

476-
// Still send the webviewDidLaunch message for other initialization
477-
vscode.postMessage({ type: "webviewDidLaunch" })
476+
// Initialize webview using gRPC
477+
UiServiceClient.initializeWebview(EmptyRequest.create({}))
478+
.then(() => {
479+
console.log("[DEBUG] Webview initialization completed via gRPC")
480+
})
481+
.catch((error) => {
482+
console.error("Failed to initialize webview via gRPC:", error)
483+
})
478484

479485
// Set up account button clicked subscription
480486
accountButtonClickedSubscriptionRef.current = UiServiceClient.subscribeToAccountButtonClicked(EmptyRequest.create(), {

0 commit comments

Comments
 (0)