model-info.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React from 'react'
  4. import { useTranslation } from 'react-i18next'
  5. import {
  6. RiInformation2Line,
  7. } from '@remixicon/react'
  8. import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon'
  9. import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name'
  10. import {
  11. PortalToFollowElem,
  12. PortalToFollowElemContent,
  13. PortalToFollowElemTrigger,
  14. } from '@/app/components/base/portal-to-follow-elem'
  15. import { useTextGenerationCurrentProviderAndModelAndModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
  16. import cn from '@/utils/classnames'
  17. const PARAM_MAP = {
  18. temperature: 'Temperature',
  19. top_p: 'Top P',
  20. presence_penalty: 'Presence Penalty',
  21. max_tokens: 'Max Token',
  22. stop: 'Stop',
  23. frequency_penalty: 'Frequency Penalty',
  24. }
  25. type Props = {
  26. model: any
  27. }
  28. const ModelInfo: FC<Props> = ({
  29. model,
  30. }) => {
  31. const { t } = useTranslation()
  32. const modelName = model.name
  33. const provideName = model.provider as any
  34. const {
  35. currentModel,
  36. currentProvider,
  37. } = useTextGenerationCurrentProviderAndModelAndModelList(
  38. { provider: provideName, model: modelName },
  39. )
  40. const [open, setOpen] = React.useState(false)
  41. const getParamValue = (param: string) => {
  42. const value = model.completion_params?.[param] || '-'
  43. if (param === 'stop') {
  44. if (Array.isArray(value))
  45. return value.join(',')
  46. else
  47. return '-'
  48. }
  49. return value
  50. }
  51. return (
  52. <div className={cn('flex items-center rounded-lg')}>
  53. <div className='shrink-0 flex items-center gap-1 mr-px h-8 pl-1.5 pr-2 rounded-l-lg bg-components-input-bg-normal'>
  54. <ModelIcon
  55. className='!w-5 !h-5'
  56. provider={currentProvider}
  57. modelName={currentModel?.model}
  58. />
  59. <ModelName
  60. modelItem={currentModel!}
  61. showMode
  62. />
  63. </div>
  64. <PortalToFollowElem
  65. open={open}
  66. onOpenChange={setOpen}
  67. placement='bottom-end'
  68. offset={4}
  69. >
  70. <div className='relative'>
  71. <PortalToFollowElemTrigger
  72. onClick={() => setOpen(v => !v)}
  73. className='block'
  74. >
  75. <div className={cn(
  76. 'p-2 rounded-r-lg bg-components-button-tertiary-bg hover:bg-components-button-tertiary-bg-hover cursor-pointer',
  77. open && 'bg-components-button-tertiary-bg-hover',
  78. )}>
  79. <RiInformation2Line className='h-4 w-4 text-text-tertiary' />
  80. </div>
  81. </PortalToFollowElemTrigger>
  82. <PortalToFollowElemContent className='z-[1002]'>
  83. <div className='relative w-[280px] pt-3 px-4 pb-2 bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl overflow-hidden'>
  84. <div className='mb-1 h-6 text-text-secondary system-sm-semibold-uppercase'>{t('appLog.detail.modelParams')}</div>
  85. <div className='py-1'>
  86. {['temperature', 'top_p', 'presence_penalty', 'max_tokens', 'stop'].map((param: string, index: number) => {
  87. return <div className='flex justify-between py-1.5' key={index}>
  88. <span className='text-text-tertiary system-xs-medium-uppercase'>{PARAM_MAP[param as keyof typeof PARAM_MAP]}</span>
  89. <span className='text-text-secondary system-xs-medium-uppercase'>{getParamValue(param)}</span>
  90. </div>
  91. })}
  92. </div>
  93. </div>
  94. </PortalToFollowElemContent>
  95. </div>
  96. </PortalToFollowElem>
  97. </div>
  98. )
  99. }
  100. export default React.memo(ModelInfo)