Skip to content

Commit cb7f209

Browse files
authored
Merge pull request #27 from trypear/images
Fixed images
2 parents ecc9643 + 7c38e00 commit cb7f209

File tree

6 files changed

+54
-33
lines changed

6 files changed

+54
-33
lines changed

src/shared/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ export const pearAiModels = {
821821
contextWindow: 64000,
822822
// Default values for required fields, but actual values will be inherited from underlying model
823823
supportsPromptCache: true,
824-
supportsImages: true,
824+
supportsImages: false,
825825
supportsComputerUse: false,
826826
// Base pricing
827827
inputPrice: 0.014,

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ import {
1414
import { McpServer, McpTool } from "../../../../src/shared/mcp"
1515
import { findLast } from "../../../../src/shared/array"
1616
import { combineApiRequests } from "../../../../src/shared/combineApiRequests"
17+
import { ModelInfo, pearAiDefaultModelId, pearAiDefaultModelInfo, PEARAI_URL } from "../../../../src/shared/api"
1718
import { combineCommandSequences } from "../../../../src/shared/combineCommandSequences"
1819
import { getApiMetrics } from "../../../../src/shared/getApiMetrics"
1920
import { useExtensionState } from "../../context/ExtensionStateContext"
2021
import { vscode } from "../../utils/vscode"
2122
import HistoryPreview from "../history/HistoryPreview"
2223
import { normalizeApiConfiguration } from "../settings/ApiOptions"
24+
import { usePearAiModels } from "../../hooks/usePearAiModels"
2325
import Announcement from "./Announcement"
2426
import BrowserSessionRow from "./BrowserSessionRow"
2527
import ChatRow from "./ChatRow"
@@ -463,9 +465,11 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
463465
startNewTask()
464466
}, [startNewTask])
465467

468+
const pearAiModels = usePearAiModels(apiConfiguration)
469+
466470
const { selectedModelInfo } = useMemo(() => {
467-
return normalizeApiConfiguration(apiConfiguration)
468-
}, [apiConfiguration])
471+
return normalizeApiConfiguration(apiConfiguration, pearAiModels)
472+
}, [apiConfiguration, pearAiModels])
469473

470474
const selectImages = useCallback(() => {
471475
vscode.postMessage({ type: "selectImages" })

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { formatLargeNumber } from "../../utils/format"
1212
import { normalizeApiConfiguration } from "../settings/ApiOptions"
1313
import { Button } from "../ui"
1414
import { HistoryItem } from "../../../../src/shared/HistoryItem"
15+
import { usePearAiModels } from "../../hooks/usePearAiModels"
1516
import { BackspaceIcon, ChatBubbleOvalLeftIcon } from "@heroicons/react/24/outline"
1617
import { vscBadgeBackground, vscEditorBackground, vscInputBackground } from "../ui"
1718
import { DownloadIcon } from "@radix-ui/react-icons"
@@ -42,7 +43,11 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
4243
onClose,
4344
}) => {
4445
const { apiConfiguration, currentTaskItem } = useExtensionState()
45-
const { selectedModelInfo } = useMemo(() => normalizeApiConfiguration(apiConfiguration), [apiConfiguration])
46+
const pearAiModels = usePearAiModels(apiConfiguration)
47+
const { selectedModelInfo } = useMemo(
48+
() => normalizeApiConfiguration(apiConfiguration, pearAiModels),
49+
[apiConfiguration, pearAiModels],
50+
)
4651
const [isTaskExpanded, setIsTaskExpanded] = useState(true)
4752
const [isTextExpanded, setIsTextExpanded] = useState(false)
4853
const [showSeeMore, setShowSeeMore] = useState(false)
@@ -51,15 +56,15 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
5156
const contextWindow = selectedModelInfo?.contextWindow || 1
5257

5358
/*
54-
When dealing with event listeners in React components that depend on state variables, we face a challenge. We want our listener to always use the most up-to-date version of a callback function that relies on current state, but we don't want to constantly add and remove event listeners as that function updates. This scenario often arises with resize listeners or other window events. Simply adding the listener in a useEffect with an empty dependency array risks using stale state, while including the callback in the dependencies can lead to unnecessary re-registrations of the listener. There are react hook libraries that provide a elegant solution to this problem by utilizing the useRef hook to maintain a reference to the latest callback function without triggering re-renders or effect re-runs. This approach ensures that our event listener always has access to the most current state while minimizing performance overhead and potential memory leaks from multiple listener registrations.
59+
When dealing with event listeners in React components that depend on state variables, we face a challenge. We want our listener to always use the most up-to-date version of a callback function that relies on current state, but we don't want to constantly add and remove event listeners as that function updates. This scenario often arises with resize listeners or other window events. Simply adding the listener in a useEffect with an empty dependency array risks using stale state, while including the callback in the dependencies can lead to unnecessary re-registrations of the listener. There are react hook libraries that provide a elegant solution to this problem by utilizing the useRef hook to maintain a reference to the latest callback function without triggering re-renders or effect re-runs. This approach ensures that our event listener always has access to the most current state while minimizing performance overhead and potential memory leaks from multiple listener registrations.
5560
Sources
5661
- https://usehooks-ts.com/react-hook/use-event-listener
5762
- https://streamich.github.io/react-use/?path=/story/sensors-useevent--docs
5863
- https://github.com/streamich/react-use/blob/master/src/useEvent.ts
5964
- https://stackoverflow.com/questions/55565444/how-to-register-event-with-useeffect-hooks
6065
6166
Before:
62-
67+
6368
const updateMaxHeight = useCallback(() => {
6469
if (isExpanded && textContainerRef.current) {
6570
const maxHeight = window.innerHeight * (3 / 5)

webview-ui/src/components/settings/ApiOptions.tsx

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage"
4848
import { vscode } from "../../utils/vscode"
4949
import VSCodeButtonLink from "../common/VSCodeButtonLink"
5050
import { ModelInfoView } from "./ModelInfoView"
51+
import { usePearAiModels } from "../../hooks/usePearAiModels"
5152
import { DROPDOWN_Z_INDEX } from "./styles"
5253
import { ModelPicker } from "./ModelPicker"
5354
import { validateApiConfiguration, validateModelId } from "@/utils/validate"
@@ -92,9 +93,7 @@ const ApiOptions = ({
9293
})
9394

9495
const [openAiModels, setOpenAiModels] = useState<Record<string, ModelInfo> | null>(null)
95-
const [pearAiModels, setPearAiModels] = useState<Record<string, ModelInfo>>({
96-
[pearAiDefaultModelId]: pearAiDefaultModelInfo,
97-
})
96+
const pearAiModels = usePearAiModels(apiConfiguration)
9897

9998
const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl)
10099
const [azureApiVersionSelected, setAzureApiVersionSelected] = useState(!!apiConfiguration?.azureApiVersion)
@@ -167,28 +166,6 @@ const ApiOptions = ({
167166
],
168167
)
169168

170-
// Fetch PearAI models when provider is selected
171-
useEffect(() => {
172-
if (selectedProvider === "pearai") {
173-
const fetchPearAiModels = async () => {
174-
try {
175-
const res = await fetch(`${PEARAI_URL}/getPearAIAgentModels`)
176-
if (!res.ok) throw new Error("Failed to fetch models")
177-
const config = await res.json()
178-
179-
if (config.models && Object.keys(config.models).length > 0) {
180-
console.log("Models successfully loaded from server")
181-
setPearAiModels(config.models)
182-
}
183-
} catch (error) {
184-
console.error("Error fetching PearAI models:", error)
185-
}
186-
}
187-
188-
fetchPearAiModels()
189-
}
190-
}, [selectedProvider, setPearAiModels])
191-
192169
useEffect(() => {
193170
const apiValidationResult =
194171
validateApiConfiguration(apiConfiguration) ||

webview-ui/src/components/settings/ModelPicker.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem }
66
import { ApiConfiguration, ModelInfo } from "../../../../src/shared/api"
77

88
import { normalizeApiConfiguration } from "./ApiOptions"
9+
import { usePearAiModels } from "../../hooks/usePearAiModels"
910
import { ThinkingBudget } from "./ThinkingBudget"
1011
import { ModelInfoView } from "./ModelInfoView"
1112

@@ -45,9 +46,11 @@ export const ModelPicker = ({
4546

4647
const modelIds = useMemo(() => Object.keys(models ?? {}).sort((a, b) => a.localeCompare(b)), [models])
4748

49+
const pearAiModels = usePearAiModels(apiConfiguration)
50+
4851
const { selectedModelId, selectedModelInfo } = useMemo(
49-
() => normalizeApiConfiguration(apiConfiguration),
50-
[apiConfiguration],
52+
() => normalizeApiConfiguration(apiConfiguration, pearAiModels),
53+
[apiConfiguration, pearAiModels],
5154
)
5255

5356
const onSelect = useCallback(
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useState, useEffect } from "react"
2+
import { ModelInfo, pearAiDefaultModelId, pearAiDefaultModelInfo, PEARAI_URL } from "../../../src/shared/api"
3+
import type { ApiConfiguration } from "../../../src/shared/api"
4+
5+
export const usePearAiModels = (apiConfiguration?: ApiConfiguration) => {
6+
const [pearAiModels, setPearAiModels] = useState<Record<string, ModelInfo>>({
7+
[pearAiDefaultModelId]: pearAiDefaultModelInfo,
8+
})
9+
10+
useEffect(() => {
11+
if (apiConfiguration?.apiProvider === "pearai") {
12+
const fetchPearAiModels = async () => {
13+
try {
14+
const res = await fetch(`${PEARAI_URL}/getPearAIAgentModels`)
15+
if (!res.ok) throw new Error("Failed to fetch models")
16+
const config = await res.json()
17+
18+
if (config.models && Object.keys(config.models).length > 0) {
19+
console.log("Models successfully loaded from server")
20+
setPearAiModels(config.models)
21+
}
22+
} catch (error) {
23+
console.error("Error fetching PearAI models:", error)
24+
}
25+
}
26+
27+
fetchPearAiModels()
28+
}
29+
}, [apiConfiguration?.apiProvider])
30+
31+
return pearAiModels
32+
}

0 commit comments

Comments
 (0)