model-config.tsx 8.7 KB

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