Compare commits

...

5 Commits

Author SHA1 Message Date
Elephant Lumps 8d783e7ebc merge conflicts 2025-06-05 16:04:40 -07:00
Elephant Lumps 2a360aabf5 migrate webviewDidLaunch 2025-06-05 15:58:33 -07:00
Elephant Lumps ffd1f62621 remove conversion functions and unused imports 2025-06-05 14:35:52 -07:00
Elephant Lumps f9b2d19f40 merge conflicts 2025-06-05 13:14:16 -07:00
Elephant Lumps bb1208c87b migrate openRouterModels 2025-06-05 10:41:18 -07:00
5 changed files with 85 additions and 46 deletions
+3
View File
@@ -249,4 +249,7 @@ service UiService {
// Subscribe to theme change events
rpc subscribeToTheme(EmptyRequest) returns (stream String);
// Initialize webview when it launches
rpc initializeWebview(EmptyRequest) returns (Empty);
}
-42
View File
@@ -207,48 +207,6 @@ export class Controller {
await this.setUserInfo(message.user || undefined)
await this.postStateToWebview()
break
case "webviewDidLaunch":
this.postStateToWebview()
this.workspaceTracker?.populateFilePaths() // don't await
// post last cached models in case the call to endpoint fails
this.readOpenRouterModels().then((openRouterModels) => {
if (openRouterModels) {
sendOpenRouterModelsEvent(OpenRouterCompatibleModelInfo.create({ models: openRouterModels }))
}
})
// 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.
// 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
// (see normalizeApiConfiguration > openrouter)
// Prefetch marketplace and OpenRouter models
getGlobalState(this.context, "mcpMarketplaceCatalog").then((mcpMarketplaceCatalog) => {
if (mcpMarketplaceCatalog) {
sendMcpMarketplaceCatalogEvent(mcpMarketplaceCatalog as McpMarketplaceCatalog)
}
})
this.silentlyRefreshMcpMarketplace()
handleModelsServiceRequest(this, "refreshOpenRouterModels", EmptyRequest.create()).then(async (response) => {
if (response && response.models) {
// 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)
const { apiConfiguration } = await getAllExtensionState(this.context)
if (apiConfiguration.openRouterModelId && response.models[apiConfiguration.openRouterModelId]) {
await updateGlobalState(
this.context,
"openRouterModelInfo",
response.models[apiConfiguration.openRouterModelId],
)
await this.postStateToWebview()
}
}
})
// Initialize telemetry service with user's current setting
this.getStateToPostToWebview().then((state) => {
const { telemetrySetting } = state
const isOptedIn = telemetrySetting !== "disabled"
telemetryService.updateTelemetryState(isOptedIn)
})
break
case "newTask":
// Code that should run in response to the hello message command
//vscode.window.showInformationMessage(message.text!)
@@ -0,0 +1,73 @@
import type { Controller } from "../index"
import { EmptyRequest, Empty } from "@shared/proto/common"
import { handleModelsServiceRequest } from "../models"
import { getAllExtensionState, getGlobalState, updateGlobalState } from "../../storage/state"
import { sendOpenRouterModelsEvent } from "../models/subscribeToOpenRouterModels"
import { sendMcpMarketplaceCatalogEvent } from "../mcp/subscribeToMcpMarketplaceCatalog"
import { telemetryService } from "@/services/posthog/telemetry/TelemetryService"
import { OpenRouterCompatibleModelInfo } from "@/shared/proto/models"
import { McpMarketplaceCatalog } from "@shared/mcp"
/**
* Initialize webview when it launches
* @param controller The controller instance
* @param request The empty request
* @returns Empty response
*/
export async function initializeWebview(controller: Controller, request: EmptyRequest): Promise<Empty> {
try {
// Populate file paths for workspace tracker (don't await)
controller.workspaceTracker?.populateFilePaths()
// Post last cached models in case the call to endpoint fails
controller.readOpenRouterModels().then((openRouterModels) => {
if (openRouterModels) {
sendOpenRouterModelsEvent(OpenRouterCompatibleModelInfo.create({ models: openRouterModels }))
}
})
// Refresh OpenRouter models from API
handleModelsServiceRequest(controller, "refreshOpenRouterModels", EmptyRequest.create()).then(async (response) => {
if (response && response.models) {
// 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)
const { apiConfiguration } = await getAllExtensionState(controller.context)
if (apiConfiguration.openRouterModelId && response.models[apiConfiguration.openRouterModelId]) {
await updateGlobalState(
controller.context,
"openRouterModelInfo",
response.models[apiConfiguration.openRouterModelId],
)
await controller.postStateToWebview()
}
}
})
// 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.
// 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
// (see normalizeApiConfiguration > openrouter)
// Prefetch marketplace and OpenRouter models
// Send cached MCP marketplace catalog if available
getGlobalState(controller.context, "mcpMarketplaceCatalog").then((mcpMarketplaceCatalog) => {
if (mcpMarketplaceCatalog) {
sendMcpMarketplaceCatalogEvent(mcpMarketplaceCatalog as McpMarketplaceCatalog)
}
})
// Silently refresh MCP marketplace catalog
controller.silentlyRefreshMcpMarketplace()
// Initialize telemetry service with user's current setting
controller.getStateToPostToWebview().then((state) => {
const { telemetrySetting } = state
const isOptedIn = telemetrySetting !== "disabled"
telemetryService.updateTelemetryState(isOptedIn)
})
return Empty.create({})
} catch (error) {
console.error("Failed to initialize webview:", error)
// Return empty response even on error to not break the frontend
return Empty.create({})
}
}
-1
View File
@@ -9,7 +9,6 @@ import { McpViewTab } from "./mcp"
export interface WebviewMessage {
type:
| "apiConfiguration"
| "webviewDidLaunch"
| "newTask"
| "condense"
| "reportBug"
@@ -20,7 +20,6 @@ import {
import { McpMarketplaceCatalog, McpServer, McpViewTab } from "../../../src/shared/mcp"
import { ModelsServiceClient, StateServiceClient, UiServiceClient, McpServiceClient } from "../services/grpc-client"
import { convertTextMateToHljs } from "../utils/textMateToHljs"
import { convertOpenRouterCompatibleModelInfoToModelInfoRecord } from "../../../src/shared/proto-conversions/models/openrouter-models-conversion"
import { vscode } from "../utils/vscode"
import { OpenRouterCompatibleModelInfo } from "@shared/proto/models"
@@ -459,6 +458,7 @@ export const ExtensionStateContextProvider: React.FC<{
// Subscribe to OpenRouter models updates
openRouterModelsUnsubscribeRef.current = ModelsServiceClient.subscribeToOpenRouterModels(EmptyRequest.create({}), {
onResponse: (response: OpenRouterCompatibleModelInfo) => {
console.log("[DEBUG] Received OpenRouter models update from gRPC stream")
const models = response.models
setOpenRouterModels({
[openRouterDefaultModelId]: openRouterDefaultModelInfo, // in case the extension sent a model list without the default model
@@ -473,8 +473,14 @@ export const ExtensionStateContextProvider: React.FC<{
},
})
// Still send the webviewDidLaunch message for other initialization
vscode.postMessage({ type: "webviewDidLaunch" })
// Initialize webview using gRPC
UiServiceClient.initializeWebview(EmptyRequest.create({}))
.then(() => {
console.log("[DEBUG] Webview initialization completed via gRPC")
})
.catch((error) => {
console.error("Failed to initialize webview via gRPC:", error)
})
// Set up account button clicked subscription
accountButtonClickedSubscriptionRef.current = UiServiceClient.subscribeToAccountButtonClicked(EmptyRequest.create(), {