Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 1x 1x 1x 1x 1x 62x 62x 62x 62x 62x 62x 62x 62x 62x 62x 62x 62x 62x | import { ApiConfiguration } from "@shared/api"
import { UpdateApiConfigurationRequest } from "@shared/proto/cline/models"
import { convertApiConfigurationToProto } from "@shared/proto-conversions/models/api-configuration-conversion"
import { Mode } from "@shared/storage/types"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { ModelsServiceClient } from "@/services/grpc-client"
export const useApiConfigurationHandlers = () => {
const { apiConfiguration, planActSeparateModelsSetting } = useExtensionState()
/**
* Updates a single field in the API configuration.
*
* **Warning**: If this function is called multiple times in rapid succession,
* it can lead to race conditions where later calls may overwrite changes from
* earlier calls. For updating multiple fields, use `handleFieldsChange` instead.
*
* @param field - The field key to update
* @param value - The new value for the field
*/
const handleFieldChange = async <K extends keyof ApiConfiguration>(field: K, value: ApiConfiguration[K]) => {
const updatedConfig = {
...apiConfiguration,
[field]: value,
}
const protoConfig = convertApiConfigurationToProto(updatedConfig)
await ModelsServiceClient.updateApiConfigurationProto(
UpdateApiConfigurationRequest.create({
apiConfiguration: protoConfig,
}),
)
}
/**
* Updates multiple fields in the API configuration at once.
*
* This function should be used when updating multiple fields to avoid race conditions
* that can occur when calling `handleFieldChange` multiple times in succession.
* All updates are applied together as a single operation.
*
* @param updates - An object containing the fields to update and their new values
*/
const handleFieldsChange = async (updates: Partial<ApiConfiguration>) => {
const updatedConfig = {
...apiConfiguration,
...updates,
}
const protoConfig = convertApiConfigurationToProto(updatedConfig)
await ModelsServiceClient.updateApiConfigurationProto(
UpdateApiConfigurationRequest.create({
apiConfiguration: protoConfig,
}),
)
}
const handleModeFieldChange = async <PlanK extends keyof ApiConfiguration, ActK extends keyof ApiConfiguration>(
fieldPair: { plan: PlanK; act: ActK },
value: ApiConfiguration[PlanK] & ApiConfiguration[ActK], // Intersection ensures value is compatible with both field types
currentMode: Mode,
) => {
if (planActSeparateModelsSetting) {
const targetField = fieldPair[currentMode]
await handleFieldChange(targetField, value)
} else {
await handleFieldsChange({
[fieldPair.plan]: value,
[fieldPair.act]: value,
})
}
}
/**
* Updates multiple mode-specific fields in a single atomic operation.
*
* This prevents race conditions that can occur when making multiple separate
* handleModeFieldChange calls in rapid succession.
*
* @param fieldPairs - Object mapping keys to plan/act field pairs
* @param values - Object with values for each key
* @param currentMode - The current mode being targeted
*/
const handleModeFieldsChange = async <T extends Record<string, any>>(
fieldPairs: { [K in keyof T]: { plan: keyof ApiConfiguration; act: keyof ApiConfiguration } },
values: T,
currentMode: Mode,
) => {
if (planActSeparateModelsSetting) {
// Update only the current mode's fields
const updates: Partial<ApiConfiguration> = {}
Object.entries(fieldPairs).forEach(([key, { plan, act }]) => {
const targetField = currentMode === "plan" ? plan : act
updates[targetField] = values[key]
})
await handleFieldsChange(updates)
} else {
// Update both modes' fields
const updates: Partial<ApiConfiguration> = {}
Object.entries(fieldPairs).forEach(([key, { plan, act }]) => {
updates[plan] = values[key]
updates[act] = values[key]
})
await handleFieldsChange(updates)
}
}
return { handleFieldChange, handleFieldsChange, handleModeFieldChange, handleModeFieldsChange }
}
|