provider-context.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. 'use client'
  2. import { createContext, useContext } from 'use-context-selector'
  3. import useSWR from 'swr'
  4. import { useEffect, useMemo, useState } from 'react'
  5. import {
  6. fetchModelList,
  7. fetchModelProviders,
  8. fetchSupportRetrievalMethods,
  9. operationUtm,
  10. } from '@/service/common'
  11. import {
  12. ModelFeatureEnum,
  13. ModelStatusEnum,
  14. ModelTypeEnum,
  15. } from '@/app/components/header/account-setting/model-provider-page/declarations'
  16. import type { Model, ModelProvider } from '@/app/components/header/account-setting/model-provider-page/declarations'
  17. import type { RETRIEVE_METHOD } from '@/types/app'
  18. import { Plan, type UsagePlanInfo } from '@/app/components/billing/type'
  19. import { fetchCurrentPlanInfo } from '@/service/billing'
  20. import { parseCurrentPlan } from '@/app/components/billing/utils'
  21. import { defaultPlan } from '@/app/components/billing/config'
  22. const ProviderContext = createContext<{
  23. modelProviders: ModelProvider[]
  24. textGenerationModelList: Model[]
  25. agentThoughtModelList: Model[]
  26. supportRetrievalMethods: RETRIEVE_METHOD[]
  27. hasSettedApiKey: boolean
  28. plan: {
  29. type: Plan
  30. usage: UsagePlanInfo
  31. total: UsagePlanInfo
  32. }
  33. isFetchedPlan: boolean
  34. enableBilling: boolean
  35. onPlanInfoChanged: () => void
  36. enableReplaceWebAppLogo: boolean
  37. }>({
  38. modelProviders: [],
  39. textGenerationModelList: [],
  40. agentThoughtModelList: [],
  41. supportRetrievalMethods: [],
  42. hasSettedApiKey: true,
  43. plan: {
  44. type: Plan.sandbox,
  45. usage: {
  46. vectorSpace: 32,
  47. buildApps: 12,
  48. teamMembers: 1,
  49. annotatedResponse: 1,
  50. },
  51. total: {
  52. vectorSpace: 200,
  53. buildApps: 50,
  54. teamMembers: 1,
  55. annotatedResponse: 10,
  56. },
  57. },
  58. isFetchedPlan: false,
  59. enableBilling: false,
  60. onPlanInfoChanged: () => { },
  61. enableReplaceWebAppLogo: false,
  62. })
  63. export const useProviderContext = () => useContext(ProviderContext)
  64. type ProviderContextProviderProps = {
  65. children: React.ReactNode
  66. }
  67. export const ProviderContextProvider = ({
  68. children,
  69. }: ProviderContextProviderProps) => {
  70. const { data: providersData } = useSWR('/workspaces/current/model-providers', fetchModelProviders)
  71. const fetchModelListUrlPrefix = '/workspaces/current/models/model-types/'
  72. const { data: textGenerationModelList } = useSWR(`${fetchModelListUrlPrefix}${ModelTypeEnum.textGeneration}`, fetchModelList)
  73. const { data: supportRetrievalMethods } = useSWR('/datasets/retrieval-setting', fetchSupportRetrievalMethods)
  74. const agentThoughtModelList = useMemo(() => {
  75. const result: Model[] = []
  76. if (textGenerationModelList?.data) {
  77. textGenerationModelList?.data.forEach((item) => {
  78. const agentThoughtModels = item.models.filter(model => model.features?.includes(ModelFeatureEnum.agentThought))
  79. if (agentThoughtModels.length) {
  80. result.push({
  81. ...item,
  82. models: agentThoughtModels,
  83. })
  84. }
  85. })
  86. return result
  87. }
  88. return []
  89. }, [textGenerationModelList])
  90. const [plan, setPlan] = useState(defaultPlan)
  91. const [isFetchedPlan, setIsFetchedPlan] = useState(false)
  92. const [enableBilling, setEnableBilling] = useState(true)
  93. const [enableReplaceWebAppLogo, setEnableReplaceWebAppLogo] = useState(false)
  94. const handleOperateUtm = () => {
  95. let utm
  96. try {
  97. utm = JSON.parse(localStorage?.getItem('utm') || '{}')
  98. }
  99. catch (e) {
  100. utm = {
  101. utm_source: '',
  102. utm_medium: '',
  103. utm_campaign: '',
  104. utm_content: '',
  105. utm_term: '',
  106. }
  107. }
  108. if (utm.utm_source || utm.utm_medium || utm.utm_campaign || utm.utm_content || utm.utm_term)
  109. operationUtm({ url: '/operation/utm', body: utm })
  110. }
  111. const fetchPlan = async () => {
  112. const data = await fetchCurrentPlanInfo()
  113. const enabled = data.billing.enabled
  114. setEnableBilling(enabled)
  115. setEnableReplaceWebAppLogo(data.can_replace_logo)
  116. if (enabled) {
  117. setPlan(parseCurrentPlan(data))
  118. handleOperateUtm()
  119. setIsFetchedPlan(true)
  120. }
  121. }
  122. useEffect(() => {
  123. fetchPlan()
  124. }, [])
  125. return (
  126. <ProviderContext.Provider value={{
  127. modelProviders: providersData?.data || [],
  128. textGenerationModelList: textGenerationModelList?.data || [],
  129. agentThoughtModelList,
  130. hasSettedApiKey: !!textGenerationModelList?.data.some(model => model.status === ModelStatusEnum.active),
  131. supportRetrievalMethods: supportRetrievalMethods?.retrieval_method || [],
  132. plan,
  133. isFetchedPlan,
  134. enableBilling,
  135. onPlanInfoChanged: fetchPlan,
  136. enableReplaceWebAppLogo,
  137. }}>
  138. {children}
  139. </ProviderContext.Provider>
  140. )
  141. }
  142. export default ProviderContext