Refactor ApiOptions and LiteLLM components to use useEvent for message handling

- Replaced traditional event listeners with useEvent for improved performance and cleaner code.
- Updated message handling logic in both components to ensure proper response processing for provider models.
- Enhanced type safety by utilizing specific message types from ExtensionMessage.
This commit is contained in:
slytechnical 2025-05-19 13:29:47 -05:00
parent caea66f340
commit cbed162462
2 changed files with 27 additions and 42 deletions

View file

@ -1,6 +1,6 @@
import React, { memo, useCallback, useEffect, useMemo, useState } from "react"
import { convertHeadersToObject } from "./utils/headers"
import { useDebounce } from "react-use"
import { useDebounce, useEvent } from "react-use"
import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import {
@ -55,6 +55,7 @@ import { TemperatureControl } from "./TemperatureControl"
import { RateLimitSecondsControl } from "./RateLimitSecondsControl"
import { BedrockCustomArn } from "./providers/BedrockCustomArn"
import { buildDocLink } from "@src/utils/docLinks"
import { ExtensionMessage } from "@roo/shared/ExtensionMessage"
export interface ApiOptionsProps {
uriScheme: string | undefined
@ -152,27 +153,19 @@ const ApiOptions = ({
}
}, [initialRouterModels, defaultRouterModels])
// Listen for specific provider model updates
useEffect(() => {
const handler = (event: MessageEvent<any>) => {
const message = event.data
if (message.type === "providerModelsResponse" && message.payload) {
const { provider, models, error } = message.payload as {
provider: keyof RouterModels
models?: ModelRecord
error?: string
}
if (provider && models && !error) {
setCurrentRouterModels((prevModels) => ({
...prevModels, // prevModels is now guaranteed to be RouterModels
[provider]: models,
}))
}
// Listen for specific provider model updates using useEvent
useEvent("message", (event: MessageEvent<ExtensionMessage>) => {
const message = event.data
if (message.type === "providerModelsResponse" && message.payload) {
const { provider, models, error } = message.payload
if (provider && models && !error) {
setCurrentRouterModels((prevModels) => ({
...prevModels,
[provider]: models,
}))
}
}
window.addEventListener("message", handler)
return () => window.removeEventListener("message", handler)
}, [])
})
// Update `apiModelId` whenever `selectedModelId` changes.
useEffect(() => {

View file

@ -1,5 +1,6 @@
import { useCallback, useState, useEffect } from "react"
import { useCallback, useState } from "react"
import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import { useEvent } from "react-use"
import { ProviderSettings, RouterModels, litellmDefaultModelId } from "@roo/shared/api"
import { vscode } from "@src/utils/vscode"
@ -9,7 +10,7 @@ import { useAppTranslation } from "@src/i18n/TranslationContext"
import { inputEventTransform } from "../transforms"
import { ModelPicker } from "../ModelPicker"
import { WebviewMessage } from "@roo/shared/WebviewMessage"
import { ExtensionMessage, ProviderModelsResponsePayload } from "@roo/shared/ExtensionMessage"
import { ExtensionMessage } from "@roo/shared/ExtensionMessage"
type LiteLLMProps = {
apiConfiguration: ProviderSettings
@ -49,28 +50,19 @@ export const LiteLLM = ({ apiConfiguration, setApiConfigurationField, routerMode
vscode.postMessage(message)
}
// Effect to listen for model refresh responses
useEffect(() => {
const handler = (event: MessageEvent<ExtensionMessage>) => {
const message = event.data
if (
message.type === "providerModelsResponse" &&
message.payload &&
message.payload.provider === "litellm"
) {
const payload = message.payload as ProviderModelsResponsePayload
if (payload.error) {
setRefreshStatus("error")
setRefreshError(payload.error)
} else {
setRefreshStatus("success")
// Parent (ApiOptions.tsx) will handle updating the routerModels prop for ModelPicker
}
// Listen for model refresh responses using useEvent
useEvent("message", (event: MessageEvent<ExtensionMessage>) => {
const message = event.data
if (message.type === "providerModelsResponse" && message.payload && message.payload.provider === "litellm") {
if (message.payload.error) {
setRefreshStatus("error")
setRefreshError(message.payload.error)
} else {
setRefreshStatus("success")
// Parent (ApiOptions.tsx) will handle updating the routerModels prop for ModelPicker
}
}
window.addEventListener("message", handler)
return () => window.removeEventListener("message", handler)
}, [])
})
return (
<>