model-config.tsx 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import { ServiceProvider } from "@/app/constant";
  2. import { ModalConfigValidator, ModelConfig } from "../store";
  3. import Locale from "../locales";
  4. import { InputRange } from "./input-range";
  5. import { ListItem, Select } from "./ui-lib";
  6. import { useAllModels } from "../utils/hooks";
  7. import { groupBy } from "lodash-es";
  8. import styles from "./model-config.module.scss";
  9. export function ModelConfigList(props: {
  10. modelConfig: ModelConfig;
  11. updateConfig: (updater: (config: ModelConfig) => void) => void;
  12. }) {
  13. const allModels = useAllModels();
  14. const groupModels = groupBy(
  15. allModels.filter((v) => v.available),
  16. "provider.providerName",
  17. );
  18. const value = `${props.modelConfig.model}@${props.modelConfig?.providerName}`;
  19. const compressModelValue = `${props.modelConfig.compressModel}@${props.modelConfig?.compressProviderName}`;
  20. return (
  21. <>
  22. <ListItem title={Locale.Settings.Model}>
  23. <Select
  24. aria-label={Locale.Settings.Model}
  25. value={value}
  26. align="left"
  27. onChange={(e) => {
  28. const [model, providerName] =
  29. e.currentTarget.value.split(/@(?!.*@)/);
  30. props.updateConfig((config) => {
  31. config.model = ModalConfigValidator.model(model);
  32. config.providerName = providerName as ServiceProvider;
  33. });
  34. }}
  35. >
  36. {Object.keys(groupModels).map((providerName, index) => (
  37. <optgroup label={providerName} key={index}>
  38. {groupModels[providerName].map((v, i) => (
  39. <option value={`${v.name}@${v.provider?.providerName}`} key={i}>
  40. {v.displayName}
  41. </option>
  42. ))}
  43. </optgroup>
  44. ))}
  45. </Select>
  46. </ListItem>
  47. <ListItem
  48. title={Locale.Settings.Temperature.Title}
  49. subTitle={Locale.Settings.Temperature.SubTitle}
  50. >
  51. <InputRange
  52. aria={Locale.Settings.Temperature.Title}
  53. value={props.modelConfig.temperature?.toFixed(1)}
  54. min="0"
  55. max="1" // lets limit it to 0-1
  56. step="0.1"
  57. onChange={(e) => {
  58. props.updateConfig(
  59. (config) =>
  60. (config.temperature = ModalConfigValidator.temperature(
  61. e.currentTarget.valueAsNumber,
  62. )),
  63. );
  64. }}
  65. ></InputRange>
  66. </ListItem>
  67. <ListItem
  68. title={Locale.Settings.TopP.Title}
  69. subTitle={Locale.Settings.TopP.SubTitle}
  70. >
  71. <InputRange
  72. aria={Locale.Settings.TopP.Title}
  73. value={(props.modelConfig.top_p ?? 1).toFixed(1)}
  74. min="0"
  75. max="1"
  76. step="0.1"
  77. onChange={(e) => {
  78. props.updateConfig(
  79. (config) =>
  80. (config.top_p = ModalConfigValidator.top_p(
  81. e.currentTarget.valueAsNumber,
  82. )),
  83. );
  84. }}
  85. ></InputRange>
  86. </ListItem>
  87. <ListItem
  88. title={Locale.Settings.MaxTokens.Title}
  89. subTitle={Locale.Settings.MaxTokens.SubTitle}
  90. >
  91. <input
  92. aria-label={Locale.Settings.MaxTokens.Title}
  93. type="number"
  94. min={1024}
  95. max={512000}
  96. value={props.modelConfig.max_tokens}
  97. onChange={(e) =>
  98. props.updateConfig(
  99. (config) =>
  100. (config.max_tokens = ModalConfigValidator.max_tokens(
  101. e.currentTarget.valueAsNumber,
  102. )),
  103. )
  104. }
  105. ></input>
  106. </ListItem>
  107. {props.modelConfig?.providerName == ServiceProvider.Google ? null : (
  108. <>
  109. <ListItem
  110. title={Locale.Settings.PresencePenalty.Title}
  111. subTitle={Locale.Settings.PresencePenalty.SubTitle}
  112. >
  113. <InputRange
  114. aria={Locale.Settings.PresencePenalty.Title}
  115. value={props.modelConfig.presence_penalty?.toFixed(1)}
  116. min="-2"
  117. max="2"
  118. step="0.1"
  119. onChange={(e) => {
  120. props.updateConfig(
  121. (config) =>
  122. (config.presence_penalty =
  123. ModalConfigValidator.presence_penalty(
  124. e.currentTarget.valueAsNumber,
  125. )),
  126. );
  127. }}
  128. ></InputRange>
  129. </ListItem>
  130. <ListItem
  131. title={Locale.Settings.FrequencyPenalty.Title}
  132. subTitle={Locale.Settings.FrequencyPenalty.SubTitle}
  133. >
  134. <InputRange
  135. aria={Locale.Settings.FrequencyPenalty.Title}
  136. value={props.modelConfig.frequency_penalty?.toFixed(1)}
  137. min="-2"
  138. max="2"
  139. step="0.1"
  140. onChange={(e) => {
  141. props.updateConfig(
  142. (config) =>
  143. (config.frequency_penalty =
  144. ModalConfigValidator.frequency_penalty(
  145. e.currentTarget.valueAsNumber,
  146. )),
  147. );
  148. }}
  149. ></InputRange>
  150. </ListItem>
  151. <ListItem
  152. title={Locale.Settings.InjectSystemPrompts.Title}
  153. subTitle={Locale.Settings.InjectSystemPrompts.SubTitle}
  154. >
  155. <input
  156. aria-label={Locale.Settings.InjectSystemPrompts.Title}
  157. type="checkbox"
  158. checked={props.modelConfig.enableInjectSystemPrompts}
  159. onChange={(e) =>
  160. props.updateConfig(
  161. (config) =>
  162. (config.enableInjectSystemPrompts =
  163. e.currentTarget.checked),
  164. )
  165. }
  166. ></input>
  167. </ListItem>
  168. <ListItem
  169. title={Locale.Settings.InputTemplate.Title}
  170. subTitle={Locale.Settings.InputTemplate.SubTitle}
  171. >
  172. <input
  173. aria-label={Locale.Settings.InputTemplate.Title}
  174. type="text"
  175. value={props.modelConfig.template}
  176. onChange={(e) =>
  177. props.updateConfig(
  178. (config) => (config.template = e.currentTarget.value),
  179. )
  180. }
  181. ></input>
  182. </ListItem>
  183. </>
  184. )}
  185. <ListItem
  186. title={Locale.Settings.HistoryCount.Title}
  187. subTitle={Locale.Settings.HistoryCount.SubTitle}
  188. >
  189. <InputRange
  190. aria={Locale.Settings.HistoryCount.Title}
  191. title={props.modelConfig.historyMessageCount.toString()}
  192. value={props.modelConfig.historyMessageCount}
  193. min="0"
  194. max="64"
  195. step="1"
  196. onChange={(e) =>
  197. props.updateConfig(
  198. (config) => (config.historyMessageCount = e.target.valueAsNumber),
  199. )
  200. }
  201. ></InputRange>
  202. </ListItem>
  203. <ListItem
  204. title={Locale.Settings.CompressThreshold.Title}
  205. subTitle={Locale.Settings.CompressThreshold.SubTitle}
  206. >
  207. <input
  208. aria-label={Locale.Settings.CompressThreshold.Title}
  209. type="number"
  210. min={500}
  211. max={4000}
  212. value={props.modelConfig.compressMessageLengthThreshold}
  213. onChange={(e) =>
  214. props.updateConfig(
  215. (config) =>
  216. (config.compressMessageLengthThreshold =
  217. e.currentTarget.valueAsNumber),
  218. )
  219. }
  220. ></input>
  221. </ListItem>
  222. <ListItem title={Locale.Memory.Title} subTitle={Locale.Memory.Send}>
  223. <input
  224. aria-label={Locale.Memory.Title}
  225. type="checkbox"
  226. checked={props.modelConfig.sendMemory}
  227. onChange={(e) =>
  228. props.updateConfig(
  229. (config) => (config.sendMemory = e.currentTarget.checked),
  230. )
  231. }
  232. ></input>
  233. </ListItem>
  234. <ListItem
  235. title={Locale.Settings.CompressModel.Title}
  236. subTitle={Locale.Settings.CompressModel.SubTitle}
  237. >
  238. <Select
  239. className={styles["select-compress-model"]}
  240. aria-label={Locale.Settings.CompressModel.Title}
  241. value={compressModelValue}
  242. onChange={(e) => {
  243. const [model, providerName] =
  244. e.currentTarget.value.split(/@(?!.*@)/);
  245. props.updateConfig((config) => {
  246. config.compressModel = ModalConfigValidator.model(model);
  247. config.compressProviderName = providerName as ServiceProvider;
  248. });
  249. }}
  250. >
  251. {allModels
  252. .filter((v) => v.available)
  253. .map((v, i) => (
  254. <option value={`${v.name}@${v.provider?.providerName}`} key={i}>
  255. {v.displayName}({v.provider?.providerName})
  256. </option>
  257. ))}
  258. </Select>
  259. </ListItem>
  260. </>
  261. );
  262. }