├── .nvmrc
├── docs
├── usage
│ ├── tools-calling
│ │ ├── groq.mdx
│ │ ├── moonshot.mdx
│ │ └── moonshot.zh-CN.mdx
│ ├── tools-calling.mdx
│ ├── features
│ │ ├── mobile.zh-CN.mdx
│ │ └── mobile.mdx
│ ├── plugins
│ │ └── store.zh-CN.mdx
│ └── agents
│ │ └── topics.zh-CN.mdx
└── self-hosting
│ ├── server-database
│ ├── sealos.zh-CN.mdx
│ ├── repocloud.zh-CN.mdx
│ ├── railway.zh-CN.mdx
│ ├── sealos.mdx
│ ├── netlify.zh-CN.mdx
│ ├── netlify.mdx
│ ├── railway.mdx
│ └── repocloud.mdx
│ └── environment-variables.zh-CN.mdx
├── src
├── store
│ ├── user
│ │ ├── index.ts
│ │ ├── slices
│ │ │ ├── settings
│ │ │ │ ├── selectors
│ │ │ │ │ └── index.ts
│ │ │ │ └── initialState.ts
│ │ │ ├── modelList
│ │ │ │ ├── selectors
│ │ │ │ │ └── index.ts
│ │ │ │ └── initialState.ts
│ │ │ ├── sync
│ │ │ │ └── initialState.ts
│ │ │ ├── preference
│ │ │ │ ├── initialState.ts
│ │ │ │ └── selectors.ts
│ │ │ └── common
│ │ │ │ └── initialState.ts
│ │ ├── helpers.ts
│ │ └── selectors.ts
│ ├── global
│ │ └── index.ts
│ ├── session
│ │ ├── helpers.ts
│ │ ├── slices
│ │ │ ├── session
│ │ │ │ ├── selectors
│ │ │ │ │ └── index.ts
│ │ │ │ └── helpers.ts
│ │ │ └── sessionGroup
│ │ │ │ ├── selectors.ts
│ │ │ │ └── initialState.ts
│ │ ├── index.ts
│ │ ├── selectors.ts
│ │ └── initialState.ts
│ ├── agent
│ │ ├── selectors.ts
│ │ ├── slices
│ │ │ └── chat
│ │ │ │ └── index.ts
│ │ ├── index.ts
│ │ └── initialState.ts
│ ├── file
│ │ ├── slices
│ │ │ ├── tts
│ │ │ │ ├── index.ts
│ │ │ │ └── selectors.ts
│ │ │ └── images
│ │ │ │ ├── index.ts
│ │ │ │ └── initialState.ts
│ │ ├── index.ts
│ │ ├── initialState.ts
│ │ └── selectors.ts
│ ├── tool
│ │ ├── index.ts
│ │ ├── slices
│ │ │ ├── builtin
│ │ │ │ ├── index.ts
│ │ │ │ ├── initialState.ts
│ │ │ │ └── selectors.ts
│ │ │ ├── store
│ │ │ │ ├── index.ts
│ │ │ │ └── initialState.ts
│ │ │ ├── plugin
│ │ │ │ ├── index.ts
│ │ │ │ ├── initialState.ts
│ │ │ │ └── __snapshots__
│ │ │ │ │ └── action.test.ts.snap
│ │ │ └── customPlugin
│ │ │ │ ├── index.ts
│ │ │ │ ├── selectors.ts
│ │ │ │ └── initialState.ts
│ │ ├── selectors
│ │ │ └── index.ts
│ │ └── initialState.ts
│ ├── chat
│ │ ├── index.ts
│ │ ├── slices
│ │ │ ├── share
│ │ │ │ └── initialState.ts
│ │ │ ├── builtinTool
│ │ │ │ ├── initialState.ts
│ │ │ │ └── selectors.ts
│ │ │ ├── message
│ │ │ │ └── utils.ts
│ │ │ └── portal
│ │ │ │ ├── initialState.ts
│ │ │ │ └── selectors.ts
│ │ ├── selectors.ts
│ │ └── utils
│ │ │ └── index.ts
│ ├── market
│ │ ├── index.ts
│ │ └── initialState.ts
│ └── serverConfig
│ │ └── index.ts
├── types
│ ├── trace
│ │ └── index.ts
│ ├── message
│ │ └── translate.ts
│ ├── user
│ │ └── settings
│ │ │ ├── tool.ts
│ │ │ ├── tts.ts
│ │ │ ├── sync.ts
│ │ │ ├── systemAgent.ts
│ │ │ └── general.ts
│ ├── locale.ts
│ ├── service.ts
│ ├── share.ts
│ ├── i18next.d.ts
│ ├── openai
│ │ └── functionCall.ts
│ ├── tool
│ │ ├── tool.ts
│ │ ├── dalle.ts
│ │ └── index.ts
│ ├── topic.ts
│ ├── session
│ │ ├── index.ts
│ │ └── sessionGroup.ts
│ ├── market.ts
│ └── global.d.ts
├── const
│ ├── message.ts
│ ├── settings
│ │ ├── tool.ts
│ │ ├── sync.ts
│ │ ├── common.ts
│ │ ├── tts.ts
│ │ └── systemAgent.ts
│ ├── plugin.ts
│ ├── hotkeys.ts
│ ├── theme.ts
│ ├── version.ts
│ ├── user.ts
│ ├── layoutTokens.test.ts
│ ├── meta.ts
│ ├── locale.ts
│ └── market.ts
├── components
│ ├── FileList
│ │ ├── style.ts
│ │ └── index.tsx
│ ├── BrowserIcon
│ │ ├── types.ts
│ │ └── components
│ │ │ ├── Chrome.tsx
│ │ │ └── Chromium.tsx
│ ├── Analytics
│ │ ├── Google.tsx
│ │ ├── Vercel.tsx
│ │ ├── Umami.tsx
│ │ ├── Plausible.tsx
│ │ └── Posthog.tsx
│ ├── PageTitle
│ │ └── index.tsx
│ ├── StructuredData
│ │ └── index.tsx
│ ├── ModelTag
│ │ └── index.tsx
│ ├── Error
│ │ └── sentryCaptureException.ts
│ ├── FetchErrorNotification
│ │ └── index.tsx
│ ├── server
│ │ └── ServerLayout.tsx
│ ├── Cell
│ │ └── Divider.tsx
│ └── SkeletonLoading
│ │ └── index.tsx
├── database
│ ├── server
│ │ ├── index.ts
│ │ └── schemas
│ │ │ └── lobechat
│ │ │ ├── index.ts
│ │ │ └── _helpers.ts
│ └── client
│ │ ├── core
│ │ ├── index.ts
│ │ ├── types
│ │ │ └── db.ts
│ │ └── migrations
│ │ │ └── migrateSettingsToUser
│ │ │ ├── index.test.ts
│ │ │ └── index.ts
│ │ └── schemas
│ │ ├── sessionGroup.ts
│ │ ├── topic.ts
│ │ └── plugin.ts
├── features
│ ├── User
│ │ ├── UserLoginOrSignup
│ │ │ └── index.tsx
│ │ └── UserPanel
│ │ │ ├── useNewVersion.tsx
│ │ │ └── UpgradeBadge.tsx
│ ├── Conversation
│ │ ├── Extras
│ │ │ ├── type.ts
│ │ │ ├── index.ts
│ │ │ └── ExtraContainer.tsx
│ │ ├── Error
│ │ │ └── InvalidAPIKey.tsx
│ │ ├── Actions
│ │ │ ├── Fallback.tsx
│ │ │ └── Error.tsx
│ │ ├── Messages
│ │ │ ├── components
│ │ │ │ └── Arguments.tsx
│ │ │ ├── Default.tsx
│ │ │ └── Tool
│ │ │ │ └── Inspector
│ │ │ │ └── PluginResultJSON.tsx
│ │ └── components
│ │ │ └── ChatList
│ │ │ └── index.tsx
│ ├── AgentSetting
│ │ ├── index.tsx
│ │ ├── AgentTTS
│ │ │ └── options.ts
│ │ ├── store
│ │ │ ├── selectors.ts
│ │ │ └── index.ts
│ │ ├── AgentSettingsStore.tsx
│ │ ├── useSyncAgemtSettings.ts
│ │ └── AgentModal
│ │ │ └── ModelSelect.tsx
│ ├── PluginStore
│ │ └── Loading.tsx
│ ├── PluginsUI
│ │ └── Render
│ │ │ ├── useParseContent.ts
│ │ │ └── utils
│ │ │ ├── pluginSettings.ts
│ │ │ └── pluginState.ts
│ ├── MobileSwitchLoading
│ │ └── index.tsx
│ ├── DataImporter
│ │ └── style.ts
│ └── ChatInput
│ │ └── ActionBar
│ │ └── ModelSwitch.tsx
├── libs
│ ├── trpc
│ │ ├── client
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ └── edge.ts
│ │ └── middleware
│ │ │ └── userAuth.ts
│ ├── agent-runtime
│ │ ├── types
│ │ │ └── index.ts
│ │ ├── utils
│ │ │ ├── streams
│ │ │ │ ├── bedrock
│ │ │ │ │ └── index.ts
│ │ │ │ └── index.ts
│ │ │ ├── response.ts
│ │ │ └── createError.ts
│ │ ├── ollama
│ │ │ └── type.ts
│ │ ├── novita
│ │ │ └── type.ts
│ │ ├── ai360
│ │ │ └── index.ts
│ │ ├── openai
│ │ │ └── index.ts
│ │ ├── stepfun
│ │ │ └── index.ts
│ │ ├── deepseek
│ │ │ └── index.ts
│ │ ├── moonshot
│ │ │ └── index.ts
│ │ ├── taichu
│ │ │ └── index.ts
│ │ ├── zeroone
│ │ │ └── index.ts
│ │ └── siliconcloud
│ │ │ └── index.ts
│ ├── logger
│ │ └── index.ts
│ └── next-auth
│ │ └── sso-providers
│ │ ├── index.ts
│ │ └── sso.config.ts
├── app
│ ├── not-found.tsx
│ ├── (main)
│ │ ├── not-found.tsx
│ │ ├── chat
│ │ │ ├── loading.tsx
│ │ │ ├── not-found.tsx
│ │ │ ├── settings
│ │ │ │ ├── not-found.tsx
│ │ │ │ ├── error.tsx
│ │ │ │ ├── loading.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ └── _layout
│ │ │ │ │ └── Mobile
│ │ │ │ │ └── index.tsx
│ │ │ ├── error.tsx
│ │ │ ├── _layout
│ │ │ │ └── type.ts
│ │ │ ├── (workspace)
│ │ │ │ ├── _layout
│ │ │ │ │ ├── type.ts
│ │ │ │ │ ├── Desktop
│ │ │ │ │ │ └── ChatHeader
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ └── useInitAgentConfig.ts
│ │ │ │ ├── features
│ │ │ │ │ └── ShareButton
│ │ │ │ │ │ └── type.ts
│ │ │ │ ├── layout.ts
│ │ │ │ ├── @conversation
│ │ │ │ │ └── features
│ │ │ │ │ │ └── ChatInput
│ │ │ │ │ │ └── Desktop
│ │ │ │ │ │ ├── Footer
│ │ │ │ │ │ └── LocalFiles.tsx
│ │ │ │ │ │ └── useAutoFocus.ts
│ │ │ │ ├── @portal
│ │ │ │ │ ├── _layout
│ │ │ │ │ │ ├── Desktop.tsx
│ │ │ │ │ │ └── Mobile.tsx
│ │ │ │ │ ├── features
│ │ │ │ │ │ └── Artifacts
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ └── @topic
│ │ │ │ │ └── _layout
│ │ │ │ │ └── Desktop.tsx
│ │ │ ├── features
│ │ │ │ ├── Migration
│ │ │ │ │ └── const.ts
│ │ │ │ └── PageTitle
│ │ │ │ │ └── index.tsx
│ │ │ ├── layout.ts
│ │ │ └── @session
│ │ │ │ ├── _layout
│ │ │ │ └── Desktop
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── PanelBody.tsx
│ │ │ │ └── features
│ │ │ │ └── SessionListContent
│ │ │ │ └── index.tsx
│ │ ├── settings
│ │ │ ├── not-found.tsx
│ │ │ ├── error.tsx
│ │ │ ├── _layout
│ │ │ │ ├── type.ts
│ │ │ │ └── Mobile
│ │ │ │ │ └── index.tsx
│ │ │ ├── llm
│ │ │ │ ├── type.ts
│ │ │ │ ├── const.ts
│ │ │ │ └── index.tsx
│ │ │ ├── common
│ │ │ │ ├── features
│ │ │ │ │ └── Theme
│ │ │ │ │ │ └── ThemeSwatches
│ │ │ │ │ │ └── index.ts
│ │ │ │ ├── index.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── sync
│ │ │ │ ├── features
│ │ │ │ │ └── WebRTC
│ │ │ │ │ │ └── generateRandomRoomName.ts
│ │ │ │ └── index.tsx
│ │ │ ├── loading.tsx
│ │ │ ├── tts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ └── features
│ │ │ │ │ └── const.ts
│ │ │ ├── @category
│ │ │ │ └── default.tsx
│ │ │ ├── layout.ts
│ │ │ ├── system-agent
│ │ │ │ ├── index.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── agent
│ │ │ │ └── page.tsx
│ │ │ ├── about
│ │ │ │ └── page.tsx
│ │ │ └── hooks
│ │ │ │ └── useSyncSettings.ts
│ │ ├── error.tsx
│ │ ├── _layout
│ │ │ └── type.ts
│ │ ├── market
│ │ │ ├── _layout
│ │ │ │ ├── type.ts
│ │ │ │ └── Mobile
│ │ │ │ │ └── Header.tsx
│ │ │ ├── @detail
│ │ │ │ ├── default.tsx
│ │ │ │ └── features
│ │ │ │ │ └── Comment.tsx
│ │ │ ├── layout.tsx
│ │ │ └── loading.tsx
│ │ ├── (mobile)
│ │ │ └── me
│ │ │ │ ├── data
│ │ │ │ ├── loading.tsx
│ │ │ │ └── layout.tsx
│ │ │ │ ├── profile
│ │ │ │ ├── loading.tsx
│ │ │ │ └── layout.tsx
│ │ │ │ ├── settings
│ │ │ │ ├── loading.tsx
│ │ │ │ ├── features
│ │ │ │ │ └── Category.tsx
│ │ │ │ └── layout.tsx
│ │ │ │ └── (home)
│ │ │ │ ├── features
│ │ │ │ └── Category.tsx
│ │ │ │ └── layout.tsx
│ │ ├── @nav
│ │ │ └── default.tsx
│ │ ├── welcome
│ │ │ ├── layout.tsx
│ │ │ └── _layout
│ │ │ │ └── Mobile.tsx
│ │ ├── profile
│ │ │ ├── _layout
│ │ │ │ └── Mobile
│ │ │ │ │ └── index.tsx
│ │ │ ├── layout.tsx
│ │ │ └── [[...slugs]]
│ │ │ │ └── page.tsx
│ │ └── layout.tsx
│ ├── @modal
│ │ ├── default.tsx
│ │ ├── error.tsx
│ │ ├── loading.tsx
│ │ ├── (.)settings
│ │ │ └── modal
│ │ │ │ ├── loading.tsx
│ │ │ │ └── page.tsx
│ │ └── chat
│ │ │ └── (.)settings
│ │ │ └── modal
│ │ │ └── loading.tsx
│ ├── api
│ │ ├── auth
│ │ │ ├── [...nextauth]
│ │ │ │ └── route.ts
│ │ │ └── error
│ │ │ │ └── page.tsx
│ │ ├── chat
│ │ │ ├── minimax
│ │ │ │ └── route.ts
│ │ │ └── openai
│ │ │ │ └── route.ts
│ │ ├── tts
│ │ │ ├── edge-speech
│ │ │ │ └── route.ts
│ │ │ └── microsoft-speech
│ │ │ │ └── route.ts
│ │ ├── market
│ │ │ ├── route.ts
│ │ │ └── [id]
│ │ │ │ └── route.ts
│ │ ├── plugin
│ │ │ └── store
│ │ │ │ ├── Store.ts
│ │ │ │ └── route.ts
│ │ └── openai
│ │ │ └── createBizOpenAI
│ │ │ └── createOpenai.ts
│ ├── error.tsx
│ ├── (loading)
│ │ └── Client.tsx
│ ├── page.tsx
│ ├── (auth)
│ │ ├── layout.tsx
│ │ └── login
│ │ │ └── [[...login]]
│ │ │ └── page.tsx
│ └── global-error.tsx
├── tools
│ ├── portals.ts
│ ├── index.ts
│ └── renders.ts
├── utils
│ ├── env.ts
│ ├── basePath.ts
│ ├── tokenizer.ts
│ ├── safeParseJSON.ts
│ ├── uploadFIle.ts
│ ├── zustand.ts
│ ├── storeDebug.ts
│ ├── parseMarkdown.ts
│ ├── client
│ │ └── switchLang.ts
│ ├── merge.ts
│ ├── keyboard.ts
│ ├── cookie.ts
│ ├── uuid.ts
│ ├── url.ts
│ └── locale.ts
├── locales
│ └── default
│ │ ├── auth.ts
│ │ ├── tool.ts
│ │ ├── portal.ts
│ │ ├── metadata.ts
│ │ └── components.ts
├── server
│ ├── routers
│ │ ├── tools
│ │ │ └── index.ts
│ │ └── edge
│ │ │ ├── config
│ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ └── upload.ts
│ └── mock.ts
├── hooks
│ ├── useIsMobile.ts
│ ├── useQuery.ts
│ ├── useProviderName.ts
│ ├── useIsSubSlug.ts
│ ├── useActiveTabKey.ts
│ ├── useYamlArguments.ts
│ ├── useGreeting
│ │ ├── greetingTime.ts
│ │ └── index.ts
│ ├── useTokenCount.ts
│ ├── useQuery.test.ts
│ └── useActiveSettingsKey.ts
├── services
│ ├── import
│ │ └── index.ts
│ ├── plugin
│ │ └── index.ts
│ ├── topic
│ │ └── index.ts
│ ├── user
│ │ ├── index.ts
│ │ └── type.ts
│ ├── session
│ │ └── index.ts
│ ├── message
│ │ └── index.ts
│ ├── file
│ │ ├── type.ts
│ │ └── index.ts
│ └── sync.ts
├── migrations
│ ├── FromV0ToV1.ts
│ ├── FromV4ToV5
│ │ └── types
│ │ │ └── v4.ts
│ └── FromV2ToV3
│ │ └── types
│ │ └── v3.ts
├── styles
│ ├── index.ts
│ ├── mobileHeader.ts
│ └── antdOverride.ts
├── chains
│ └── translate.ts
├── layout
│ ├── AuthProvider
│ │ ├── NoAuth
│ │ │ └── index.tsx
│ │ ├── NextAuth
│ │ │ └── index.tsx
│ │ └── index.tsx
│ └── GlobalProvider
│ │ └── Query.tsx
├── config
│ └── modelProviders
│ │ └── taichu.ts
└── helpers
│ └── url.ts
├── .bunfig.toml
├── vercel.json
├── .changelogrc.js
├── .husky
└── pre-commit
├── .prettierrc.js
├── .remarkrc.js
├── .commitlintrc.js
├── .releaserc.js
├── public
├── favicon.ico
├── og
│ └── cover.png
├── images
│ ├── logo.png
│ ├── updateFile.jpg
│ ├── theme_auto.webp
│ ├── theme_dark.webp
│ ├── theme_light.webp
│ ├── empty_topic_dark.webp
│ ├── banner_market_modal.webp
│ ├── chatmode_chat_dark.webp
│ ├── chatmode_chat_light.webp
│ ├── chatmode_docs_dark.webp
│ ├── chatmode_docs_light.webp
│ ├── empty_topic_light.webp
│ └── screenshot_background.webp
├── videos
│ ├── star.mp4
│ └── feedback.mp4
├── favicon-32x32.ico
├── apple-touch-icon.png
├── icons
│ ├── icon-192x192.png
│ ├── icon-512x512.png
│ ├── icon-192x192.maskable.png
│ └── icon-512x512.maskable.png
└── screenshots
│ ├── shot-1.desktop.png
│ ├── shot-1.mobile.png
│ ├── shot-2.desktop.png
│ ├── shot-2.mobile.png
│ ├── shot-3.desktop.png
│ ├── shot-3.mobile.png
│ ├── shot-4.desktop.png
│ ├── shot-4.mobile.png
│ ├── shot-5.desktop.png
│ └── shot-5.mobile.png
├── contributing
└── _Footer.md
├── .dockerignore
├── locales
├── zh-TW
│ ├── auth.json
│ ├── portal.json
│ ├── tool.json
│ ├── metadata.json
│ └── components.json
├── ko-KR
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── zh-CN
│ ├── auth.json
│ ├── tool.json
│ ├── portal.json
│ ├── metadata.json
│ └── components.json
├── ja-JP
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── bg-BG
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── en-US
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── pt-BR
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── it-IT
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── tr-TR
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── vi-VN
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── ar
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── de-DE
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── fr-FR
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── nl-NL
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── ru-RU
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── es-ES
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
└── pl-PL
│ ├── auth.json
│ ├── tool.json
│ └── portal.json
├── tests
├── setup-db.ts
└── utils.tsx
├── .stylelintrc.js
├── codecov.yml
├── .github
├── ISSUE_TEMPLATE
│ ├── config.yml
│ └── 2_feature_request_cn.yml
├── workflows
│ ├── issues-translate.yml
│ └── wiki-sync.yml
└── PULL_REQUEST_TEMPLATE.md
├── .seorc.cjs
├── netlify.toml
├── scripts
├── i18nWorkflow
│ └── index.ts
├── readmeWorkflow
│ └── index.ts
└── docsWorkflow
│ └── const.ts
├── .editorconfig
├── renovate.json
├── .eslintignore
└── .npmrc
/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/hydrogen
2 |
--------------------------------------------------------------------------------
/docs/usage/tools-calling/groq.mdx:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/docs/usage/tools-calling/moonshot.mdx:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/src/store/user/index.ts:
--------------------------------------------------------------------------------
1 | export * from './store';
2 |
--------------------------------------------------------------------------------
/.bunfig.toml:
--------------------------------------------------------------------------------
1 | [install.lockfile]
2 |
3 | save = false
4 |
--------------------------------------------------------------------------------
/src/store/global/index.ts:
--------------------------------------------------------------------------------
1 | export * from './store';
2 |
--------------------------------------------------------------------------------
/src/types/trace/index.ts:
--------------------------------------------------------------------------------
1 | export * from './action';
2 |
--------------------------------------------------------------------------------
/docs/usage/tools-calling.mdx:
--------------------------------------------------------------------------------
1 | # Tools Calling
2 |
3 | TODO
4 |
--------------------------------------------------------------------------------
/src/const/message.ts:
--------------------------------------------------------------------------------
1 | export const LOADING_FLAT = '...';
2 |
--------------------------------------------------------------------------------
/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "installCommand": "bun install"
3 | }
4 |
--------------------------------------------------------------------------------
/.changelogrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@lobehub/lint').changelog;
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | npm run type-check
2 | npx --no-install lint-staged
3 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@lobehub/lint').prettier;
2 |
--------------------------------------------------------------------------------
/.remarkrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@lobehub/lint').remarklint;
2 |
--------------------------------------------------------------------------------
/src/components/FileList/style.ts:
--------------------------------------------------------------------------------
1 | export const MIN_IMAGE_SIZE = 70;
2 |
--------------------------------------------------------------------------------
/src/database/server/index.ts:
--------------------------------------------------------------------------------
1 | export { serverDB } from './core/db';
2 |
--------------------------------------------------------------------------------
/.commitlintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@lobehub/lint').commitlint;
2 |
--------------------------------------------------------------------------------
/.releaserc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@lobehub/lint').semanticRelease;
2 |
--------------------------------------------------------------------------------
/src/store/session/helpers.ts:
--------------------------------------------------------------------------------
1 | export * from './slices/session/helpers';
2 |
--------------------------------------------------------------------------------
/src/features/User/UserLoginOrSignup/index.tsx:
--------------------------------------------------------------------------------
1 | export { default } from './Community';
2 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/store/agent/selectors.ts:
--------------------------------------------------------------------------------
1 | export { agentSelectors } from './slices/chat/selectors';
2 |
--------------------------------------------------------------------------------
/public/og/cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/og/cover.png
--------------------------------------------------------------------------------
/src/store/file/slices/tts/index.ts:
--------------------------------------------------------------------------------
1 | export * from './action';
2 | export * from './selectors';
3 |
--------------------------------------------------------------------------------
/src/store/tool/index.ts:
--------------------------------------------------------------------------------
1 | export * from './helpers';
2 | export { useToolStore } from './store';
3 |
--------------------------------------------------------------------------------
/public/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/logo.png
--------------------------------------------------------------------------------
/public/videos/star.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/videos/star.mp4
--------------------------------------------------------------------------------
/src/libs/trpc/client/index.ts:
--------------------------------------------------------------------------------
1 | export { edgeClient } from './edge';
2 | export * from './lambda';
3 |
--------------------------------------------------------------------------------
/src/store/agent/slices/chat/index.ts:
--------------------------------------------------------------------------------
1 | export * from './action';
2 | export * from './selectors';
3 |
--------------------------------------------------------------------------------
/src/store/file/index.ts:
--------------------------------------------------------------------------------
1 | export * from './selectors';
2 | export { useFileStore } from './store';
3 |
--------------------------------------------------------------------------------
/public/favicon-32x32.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/favicon-32x32.ico
--------------------------------------------------------------------------------
/src/store/session/slices/session/selectors/index.ts:
--------------------------------------------------------------------------------
1 | export * from './list';
2 | export * from './meta';
3 |
--------------------------------------------------------------------------------
/src/store/tool/slices/builtin/index.ts:
--------------------------------------------------------------------------------
1 | export * from './action';
2 | export * from './initialState';
3 |
--------------------------------------------------------------------------------
/src/types/message/translate.ts:
--------------------------------------------------------------------------------
1 | export interface Translate {
2 | from?: string;
3 | to: string;
4 | }
5 |
--------------------------------------------------------------------------------
/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/images/updateFile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/updateFile.jpg
--------------------------------------------------------------------------------
/public/videos/feedback.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/videos/feedback.mp4
--------------------------------------------------------------------------------
/public/icons/icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/icons/icon-192x192.png
--------------------------------------------------------------------------------
/public/icons/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/icons/icon-512x512.png
--------------------------------------------------------------------------------
/public/images/theme_auto.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/theme_auto.webp
--------------------------------------------------------------------------------
/public/images/theme_dark.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/theme_dark.webp
--------------------------------------------------------------------------------
/public/images/theme_light.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/theme_light.webp
--------------------------------------------------------------------------------
/src/store/agent/index.ts:
--------------------------------------------------------------------------------
1 | export type { AgentStore } from './store';
2 | export { useAgentStore } from './store';
3 |
--------------------------------------------------------------------------------
/contributing/_Footer.md:
--------------------------------------------------------------------------------
1 | This is the **🤯 / 🤖 Lobe Chat** wiki. [Wiki Home](https://github.com/lobehub/lobe-chat/wiki)
2 |
--------------------------------------------------------------------------------
/src/store/session/index.ts:
--------------------------------------------------------------------------------
1 | export type { SessionStore } from './store';
2 | export { useSessionStore } from './store';
3 |
--------------------------------------------------------------------------------
/public/images/empty_topic_dark.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/empty_topic_dark.webp
--------------------------------------------------------------------------------
/src/app/not-found.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic';
2 |
3 | export default dynamic(() => import('@/components/404'));
4 |
--------------------------------------------------------------------------------
/src/const/settings/tool.ts:
--------------------------------------------------------------------------------
1 | export const DEFAULT_TOOL_CONFIG = {
2 | dalle: {
3 | autoGenerate: false,
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/types/index.ts:
--------------------------------------------------------------------------------
1 | export * from './chat';
2 | export * from './textToImage';
3 | export * from './type';
4 |
--------------------------------------------------------------------------------
/public/icons/icon-192x192.maskable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/icons/icon-192x192.maskable.png
--------------------------------------------------------------------------------
/public/icons/icon-512x512.maskable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/icons/icon-512x512.maskable.png
--------------------------------------------------------------------------------
/public/images/banner_market_modal.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/banner_market_modal.webp
--------------------------------------------------------------------------------
/public/images/chatmode_chat_dark.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/chatmode_chat_dark.webp
--------------------------------------------------------------------------------
/public/images/chatmode_chat_light.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/chatmode_chat_light.webp
--------------------------------------------------------------------------------
/public/images/chatmode_docs_dark.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/chatmode_docs_dark.webp
--------------------------------------------------------------------------------
/public/images/chatmode_docs_light.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/chatmode_docs_light.webp
--------------------------------------------------------------------------------
/public/images/empty_topic_light.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/empty_topic_light.webp
--------------------------------------------------------------------------------
/public/screenshots/shot-1.desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/screenshots/shot-1.desktop.png
--------------------------------------------------------------------------------
/public/screenshots/shot-1.mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/screenshots/shot-1.mobile.png
--------------------------------------------------------------------------------
/public/screenshots/shot-2.desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/screenshots/shot-2.desktop.png
--------------------------------------------------------------------------------
/public/screenshots/shot-2.mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/screenshots/shot-2.mobile.png
--------------------------------------------------------------------------------
/public/screenshots/shot-3.desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/screenshots/shot-3.desktop.png
--------------------------------------------------------------------------------
/public/screenshots/shot-3.mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/screenshots/shot-3.mobile.png
--------------------------------------------------------------------------------
/public/screenshots/shot-4.desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/screenshots/shot-4.desktop.png
--------------------------------------------------------------------------------
/public/screenshots/shot-4.mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/screenshots/shot-4.mobile.png
--------------------------------------------------------------------------------
/public/screenshots/shot-5.desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/screenshots/shot-5.desktop.png
--------------------------------------------------------------------------------
/public/screenshots/shot-5.mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/screenshots/shot-5.mobile.png
--------------------------------------------------------------------------------
/src/const/plugin.ts:
--------------------------------------------------------------------------------
1 | export const PLUGIN_SCHEMA_SEPARATOR = '____';
2 | export const PLUGIN_SCHEMA_API_MD5_PREFIX = 'MD5HASH_';
3 |
--------------------------------------------------------------------------------
/src/store/file/slices/tts/selectors.ts:
--------------------------------------------------------------------------------
1 | // import { FileStore } from '../../store';
2 |
3 | export const ttsFilesSelectors = {};
4 |
--------------------------------------------------------------------------------
/src/types/user/settings/tool.ts:
--------------------------------------------------------------------------------
1 | export interface UserToolConfig {
2 | dalle: {
3 | autoGenerate: boolean;
4 | };
5 | }
6 |
--------------------------------------------------------------------------------
/public/images/screenshot_background.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yanyutin753/lobe-chat/HEAD/public/images/screenshot_background.webp
--------------------------------------------------------------------------------
/src/app/(main)/not-found.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic';
2 |
3 | export default dynamic(() => import('@/components/404'));
4 |
--------------------------------------------------------------------------------
/src/app/@modal/default.tsx:
--------------------------------------------------------------------------------
1 | // This ensures that the modal is not rendered when it's not active.
2 |
3 | export default () => null;
4 |
--------------------------------------------------------------------------------
/src/store/file/slices/images/index.ts:
--------------------------------------------------------------------------------
1 | export * from './action';
2 | export * from './initialState';
3 | export * from './selectors';
4 |
--------------------------------------------------------------------------------
/src/store/tool/slices/store/index.ts:
--------------------------------------------------------------------------------
1 | export * from './action';
2 | export * from './initialState';
3 | // export * from './selectors';
4 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/loading.tsx:
--------------------------------------------------------------------------------
1 | import CircleLoading from '@/components/CircleLoading';
2 |
3 | export default () => ;
4 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/not-found.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic';
2 |
3 | export default dynamic(() => import('@/components/404'));
4 |
--------------------------------------------------------------------------------
/src/database/client/core/index.ts:
--------------------------------------------------------------------------------
1 | export { browserDB } from './db';
2 | export * from './model';
3 | export { dataSync } from './sync';
4 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/utils/streams/bedrock/index.ts:
--------------------------------------------------------------------------------
1 | export * from './claude';
2 | export * from './common';
3 | export * from './llama';
4 |
--------------------------------------------------------------------------------
/src/store/tool/slices/plugin/index.ts:
--------------------------------------------------------------------------------
1 | export * from './action';
2 | export * from './initialState';
3 | // export * from './selectors';
4 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/not-found.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic';
2 |
3 | export default dynamic(() => import('@/components/404'));
4 |
--------------------------------------------------------------------------------
/src/store/tool/slices/customPlugin/index.ts:
--------------------------------------------------------------------------------
1 | export * from './action';
2 | export * from './initialState';
3 | // export * from './selectors';
4 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/settings/not-found.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic';
2 |
3 | export default dynamic(() => import('@/components/404'));
4 |
--------------------------------------------------------------------------------
/src/app/api/auth/[...nextauth]/route.ts:
--------------------------------------------------------------------------------
1 | import NextAuthNode from '@/libs/next-auth';
2 |
3 | export const { GET, POST } = NextAuthNode.handlers;
4 |
--------------------------------------------------------------------------------
/src/app/error.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import dynamic from 'next/dynamic';
4 |
5 | export default dynamic(() => import('@/components/Error'));
6 |
--------------------------------------------------------------------------------
/src/tools/portals.ts:
--------------------------------------------------------------------------------
1 | import { BuiltinPortal } from '@/types/tool';
2 |
3 | export const BuiltinToolsPortals: Record = {};
4 |
--------------------------------------------------------------------------------
/src/utils/env.ts:
--------------------------------------------------------------------------------
1 | export const isDev = process.env.NODE_ENV === 'development';
2 |
3 | export const isOnServerSide = typeof window === 'undefined';
4 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 | .dockerignore
3 | node_modules
4 | npm-debug.log
5 | .next
6 | .git
7 | docs
8 | .github
9 | *.md
10 | .env.example
11 |
--------------------------------------------------------------------------------
/src/app/(main)/error.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import dynamic from 'next/dynamic';
4 |
5 | export default dynamic(() => import('@/components/Error'));
6 |
--------------------------------------------------------------------------------
/src/app/@modal/error.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import dynamic from 'next/dynamic';
4 |
5 | export default dynamic(() => import('@/components/Error'));
6 |
--------------------------------------------------------------------------------
/src/utils/basePath.ts:
--------------------------------------------------------------------------------
1 | import { appEnv } from '@/config/app';
2 |
3 | export const withBasePath = (path: string) => appEnv.NEXT_PUBLIC_BASE_PATH + path;
4 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/error.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import dynamic from 'next/dynamic';
4 |
5 | export default dynamic(() => import('@/components/Error'));
6 |
--------------------------------------------------------------------------------
/src/app/api/auth/error/page.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import dynamic from 'next/dynamic';
4 |
5 | export default dynamic(() => import('./AuthErrorPage'));
6 |
--------------------------------------------------------------------------------
/src/app/(main)/_layout/type.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 |
3 | export interface LayoutProps {
4 | children: ReactNode;
5 | nav: ReactNode;
6 | }
7 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/error.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import dynamic from 'next/dynamic';
4 |
5 | export default dynamic(() => import('@/components/Error'));
6 |
--------------------------------------------------------------------------------
/src/libs/logger/index.ts:
--------------------------------------------------------------------------------
1 | import Pino from 'pino';
2 |
3 | export const pino = Pino({
4 | level: process.env.LOG_LEVEL ? process.env.LOG_LEVEL : 'info',
5 | });
6 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/_layout/type.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 |
3 | export interface LayoutProps {
4 | children: ReactNode;
5 | session: ReactNode;
6 | }
7 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/settings/error.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import dynamic from 'next/dynamic';
4 |
5 | export default dynamic(() => import('@/components/Error'));
6 |
--------------------------------------------------------------------------------
/src/store/chat/index.ts:
--------------------------------------------------------------------------------
1 | export type { ChatStoreState } from './initialState';
2 | export type { ChatStore } from './store';
3 | export { useChatStore } from './store';
4 |
--------------------------------------------------------------------------------
/src/store/market/index.ts:
--------------------------------------------------------------------------------
1 | export { agentMarketSelectors } from './selectors';
2 | export { useMarketStore } from './store';
3 | export { type Store } from './store';
4 |
--------------------------------------------------------------------------------
/src/types/locale.ts:
--------------------------------------------------------------------------------
1 | import { Locales } from '@/locales/resources';
2 |
3 | export type * from '@/locales/resources';
4 |
5 | export type LocaleMode = Locales | 'auto';
6 |
--------------------------------------------------------------------------------
/src/app/(main)/market/_layout/type.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 |
3 | export interface LayoutProps {
4 | children: ReactNode;
5 | detail: ReactNode;
6 | }
7 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/_layout/type.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 |
3 | export interface LayoutProps {
4 | category: ReactNode;
5 | children: ReactNode;
6 | }
7 |
--------------------------------------------------------------------------------
/src/app/@modal/loading.tsx:
--------------------------------------------------------------------------------
1 | import { Skeleton } from 'antd';
2 |
3 | export default () => {
4 | return ;
5 | };
6 |
--------------------------------------------------------------------------------
/src/types/service.ts:
--------------------------------------------------------------------------------
1 | export interface BatchTaskResult {
2 | added: number;
3 | errors?: Error[];
4 | ids: string[];
5 | skips: string[];
6 | success: boolean;
7 | }
8 |
--------------------------------------------------------------------------------
/locales/zh-TW/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "登入",
3 | "loginOrSignup": "登入 / 註冊",
4 | "profile": "個人檔案",
5 | "security": "安全",
6 | "signout": "登出",
7 | "signup": "註冊"
8 | }
9 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/settings/loading.tsx:
--------------------------------------------------------------------------------
1 | import SkeletonLoading from '@/components/SkeletonLoading';
2 |
3 | export default () => ;
4 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/settings/page.tsx:
--------------------------------------------------------------------------------
1 | import EditPage from './features/EditPage';
2 |
3 | const Page = () => {
4 | return ;
5 | };
6 |
7 | export default Page;
8 |
--------------------------------------------------------------------------------
/src/types/share.ts:
--------------------------------------------------------------------------------
1 | export interface ShareGPTConversation {
2 | avatarUrl?: string | null;
3 | items: Array<{
4 | from: 'human' | 'gpt';
5 | value: any;
6 | }>;
7 | }
8 |
--------------------------------------------------------------------------------
/src/utils/tokenizer.ts:
--------------------------------------------------------------------------------
1 | export const encodeAsync = async (str: string) => {
2 | const { encode } = await import('gpt-tokenizer');
3 |
4 | return encode(str).length;
5 | };
6 |
--------------------------------------------------------------------------------
/locales/ko-KR/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "로그인",
3 | "loginOrSignup": "로그인 / 가입",
4 | "profile": "프로필",
5 | "security": "보안",
6 | "signout": "로그아웃",
7 | "signup": "가입"
8 | }
9 |
--------------------------------------------------------------------------------
/locales/zh-CN/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "登录",
3 | "loginOrSignup": "登录 / 注册",
4 | "profile": "个人资料",
5 | "security": "安全",
6 | "signout": "退出登录",
7 | "signup": "注册"
8 | }
9 |
--------------------------------------------------------------------------------
/src/features/Conversation/Extras/type.ts:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 |
3 | import { ChatMessage } from '@/types/message';
4 |
5 | export type RenderMessageExtra = FC;
6 |
--------------------------------------------------------------------------------
/tests/setup-db.ts:
--------------------------------------------------------------------------------
1 | // import env
2 | import { Crypto } from '@peculiar/webcrypto';
3 | import * as dotenv from 'dotenv';
4 |
5 | dotenv.config();
6 |
7 | global.crypto = new Crypto();
8 |
--------------------------------------------------------------------------------
/src/const/settings/sync.ts:
--------------------------------------------------------------------------------
1 | import { UserSyncSettings } from '@/types/user/settings';
2 |
3 | export const DEFAULT_SYNC_CONFIG: UserSyncSettings = {
4 | webrtc: { enabled: false },
5 | };
6 |
--------------------------------------------------------------------------------
/src/locales/default/auth.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | login: '登录',
3 | loginOrSignup: '登录 / 注册',
4 | profile: '个人资料',
5 | security: '安全',
6 | signout: '退出登录',
7 | signup: '注册',
8 | };
9 |
--------------------------------------------------------------------------------
/src/store/session/selectors.ts:
--------------------------------------------------------------------------------
1 | export { sessionMetaSelectors, sessionSelectors } from './slices/session/selectors';
2 | export { sessionGroupSelectors } from './slices/sessionGroup/selectors';
3 |
--------------------------------------------------------------------------------
/locales/ja-JP/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "ログイン",
3 | "loginOrSignup": "ログイン / 登録",
4 | "profile": "プロフィール",
5 | "security": "セキュリティ",
6 | "signout": "ログアウト",
7 | "signup": "サインアップ"
8 | }
9 |
--------------------------------------------------------------------------------
/src/app/@modal/(.)settings/modal/loading.tsx:
--------------------------------------------------------------------------------
1 | import { Skeleton } from 'antd';
2 |
3 | export default () => {
4 | return ;
5 | };
6 |
--------------------------------------------------------------------------------
/src/store/serverConfig/index.ts:
--------------------------------------------------------------------------------
1 | export { ServerConfigStoreProvider } from './Provider';
2 | export { featureFlagsSelectors } from './selectors';
3 | export { useServerConfigStore } from './store';
4 |
--------------------------------------------------------------------------------
/src/app/(main)/(mobile)/me/data/loading.tsx:
--------------------------------------------------------------------------------
1 | import SkeletonLoading from '@/components/SkeletonLoading';
2 |
3 | export default () => {
4 | return ;
5 | };
6 |
--------------------------------------------------------------------------------
/src/app/(main)/(mobile)/me/profile/loading.tsx:
--------------------------------------------------------------------------------
1 | import SkeletonLoading from '@/components/SkeletonLoading';
2 |
3 | export default () => {
4 | return ;
5 | };
6 |
--------------------------------------------------------------------------------
/src/app/(main)/(mobile)/me/settings/loading.tsx:
--------------------------------------------------------------------------------
1 | import SkeletonLoading from '@/components/SkeletonLoading';
2 |
3 | export default () => {
4 | return ;
5 | };
6 |
--------------------------------------------------------------------------------
/src/app/@modal/chat/(.)settings/modal/loading.tsx:
--------------------------------------------------------------------------------
1 | import { Skeleton } from 'antd';
2 |
3 | export default () => {
4 | return ;
5 | };
6 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/llm/type.ts:
--------------------------------------------------------------------------------
1 | import { ProviderConfigProps } from './components/ProviderConfig';
2 |
3 | export interface ProviderItem extends Omit {
4 | id: string;
5 | }
6 |
--------------------------------------------------------------------------------
/src/store/chat/slices/share/initialState.ts:
--------------------------------------------------------------------------------
1 | export interface ChatShareState {
2 | shareLoading?: boolean;
3 | }
4 |
5 | export const initialShareState: ChatShareState = {
6 | shareLoading: false,
7 | };
8 |
--------------------------------------------------------------------------------
/.stylelintrc.js:
--------------------------------------------------------------------------------
1 | const config = require('@lobehub/lint').stylelint;
2 |
3 | module.exports = {
4 | ...config,
5 | rules: {
6 | 'selector-id-pattern': null,
7 | ...config.rules,
8 | },
9 | };
10 |
--------------------------------------------------------------------------------
/locales/bg-BG/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "Вход",
3 | "loginOrSignup": "Вход / Регистрация",
4 | "profile": "Профил",
5 | "security": "Сигурност",
6 | "signout": "Изход",
7 | "signup": "Регистрация"
8 | }
9 |
--------------------------------------------------------------------------------
/locales/en-US/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "Login",
3 | "loginOrSignup": "Log in / Sign up",
4 | "profile": "Profile",
5 | "security": "Security",
6 | "signout": "Sign out",
7 | "signup": "Sign up"
8 | }
9 |
--------------------------------------------------------------------------------
/locales/pt-BR/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "Entrar",
3 | "loginOrSignup": "Entrar / Registrar",
4 | "profile": "Perfil",
5 | "security": "Segurança",
6 | "signout": "Sair",
7 | "signup": "Cadastre-se"
8 | }
9 |
--------------------------------------------------------------------------------
/src/const/hotkeys.ts:
--------------------------------------------------------------------------------
1 | export const ALT_KEY = 'alt';
2 | export const META_KEY = 'mod';
3 | export const SAVE_TOPIC_KEY = 'n';
4 | export const CLEAN_MESSAGE_KEY = 'backspace';
5 | export const REGENERATE_KEY = 'r';
6 |
--------------------------------------------------------------------------------
/locales/it-IT/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "Accedi",
3 | "loginOrSignup": "Accedi / Registrati",
4 | "profile": "Profilo",
5 | "security": "Sicurezza",
6 | "signout": "Esci",
7 | "signup": "Registrati"
8 | }
9 |
--------------------------------------------------------------------------------
/locales/tr-TR/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "Giriş Yap",
3 | "loginOrSignup": "Giriş Yap / Kayıt Ol",
4 | "profile": "Profil",
5 | "security": "Güvenlik",
6 | "signout": "Çıkış Yap",
7 | "signup": "Kaydol"
8 | }
9 |
--------------------------------------------------------------------------------
/src/store/user/slices/settings/selectors/index.ts:
--------------------------------------------------------------------------------
1 | export { userGeneralSettingsSelectors } from './general';
2 | export { settingsSelectors } from './settings';
3 | export { systemAgentSelectors } from './systemAgent';
4 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | coverage:
2 | status:
3 | project:
4 | default: off
5 | server:
6 | flags:
7 | - server
8 | app:
9 | flags:
10 | - app
11 | patch: off
12 |
--------------------------------------------------------------------------------
/locales/vi-VN/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "Đăng nhập",
3 | "loginOrSignup": "Đăng nhập / Đăng ký",
4 | "profile": "Hồ sơ cá nhân",
5 | "security": "Bảo mật",
6 | "signout": "Đăng xuất",
7 | "signup": "Đăng ký"
8 | }
9 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/common/features/Theme/ThemeSwatches/index.ts:
--------------------------------------------------------------------------------
1 | export { default as ThemeSwatchesNeutral } from './ThemeSwatchesNeutral';
2 | export { default as ThemeSwatchesPrimary } from './ThemeSwatchesPrimary';
3 |
--------------------------------------------------------------------------------
/src/database/server/schemas/lobechat/index.ts:
--------------------------------------------------------------------------------
1 | export * from './chat';
2 | export * from './discover';
3 | export * from './file';
4 | export * from './nextauth';
5 | export * from './relations';
6 | export * from './user';
7 |
--------------------------------------------------------------------------------
/src/features/AgentSetting/index.tsx:
--------------------------------------------------------------------------------
1 | export { AgentSettings } from './AgentSettings';
2 | export { AgentSettingsStore } from './AgentSettingsStore';
3 | export type { AgentSettingsInstance } from './hooks/useAgentSettings';
4 |
--------------------------------------------------------------------------------
/locales/ar/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "تسجيل الدخول",
3 | "loginOrSignup": "تسجيل الدخول / التسجيل",
4 | "profile": "الملف الشخصي",
5 | "security": "الأمان",
6 | "signout": "تسجيل الخروج",
7 | "signup": "التسجيل"
8 | }
9 |
--------------------------------------------------------------------------------
/locales/de-DE/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "Anmelden",
3 | "loginOrSignup": "Anmelden / Registrieren",
4 | "profile": "Profil",
5 | "security": "Sicherheit",
6 | "signout": "Abmelden",
7 | "signup": "Registrieren"
8 | }
9 |
--------------------------------------------------------------------------------
/locales/fr-FR/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "Connexion",
3 | "loginOrSignup": "Connexion / Inscription",
4 | "profile": "Profil",
5 | "security": "Sécurité",
6 | "signout": "Déconnexion",
7 | "signup": "Inscription"
8 | }
9 |
--------------------------------------------------------------------------------
/locales/nl-NL/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "Inloggen",
3 | "loginOrSignup": "Inloggen / Registreren",
4 | "profile": "Profiel",
5 | "security": "Veiligheid",
6 | "signout": "Uitloggen",
7 | "signup": "Registreren"
8 | }
9 |
--------------------------------------------------------------------------------
/src/store/user/slices/modelList/selectors/index.ts:
--------------------------------------------------------------------------------
1 | export { keyVaultsConfigSelectors } from './keyVaults';
2 | export { modelConfigSelectors } from './modelConfig';
3 | export { modelProviderSelectors } from './modelProvider';
4 |
--------------------------------------------------------------------------------
/locales/ru-RU/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "Войти",
3 | "loginOrSignup": "Войти / Зарегистрироваться",
4 | "profile": "Профиль",
5 | "security": "Безопасность",
6 | "signout": "Выйти",
7 | "signup": "Зарегистрироваться"
8 | }
9 |
--------------------------------------------------------------------------------
/src/const/settings/common.ts:
--------------------------------------------------------------------------------
1 | import { UserGeneralConfig } from '@/types/user/settings';
2 |
3 | export const DEFAULT_COMMON_SETTINGS: UserGeneralConfig = {
4 | fontSize: 14,
5 | language: 'auto',
6 | themeMode: 'auto',
7 | };
8 |
--------------------------------------------------------------------------------
/src/const/theme.ts:
--------------------------------------------------------------------------------
1 | export const LOBE_THEME_APPEARANCE = 'LOBE_THEME_APPEARANCE';
2 |
3 | export const LOBE_THEME_PRIMARY_COLOR = 'LOBE_THEME_PRIMARY_COLOR';
4 |
5 | export const LOBE_THEME_NEUTRAL_COLOR = 'LOBE_THEME_NEUTRAL_COLOR';
6 |
--------------------------------------------------------------------------------
/src/store/chat/slices/builtinTool/initialState.ts:
--------------------------------------------------------------------------------
1 | export interface ChatToolState {
2 | dalleImageLoading: Record;
3 | }
4 |
5 | export const initialToolState: ChatToolState = {
6 | dalleImageLoading: {},
7 | };
8 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/(workspace)/_layout/type.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 |
3 | export interface LayoutProps {
4 | children: ReactNode;
5 | conversation: ReactNode;
6 | portal: ReactNode;
7 | topic: ReactNode;
8 | }
9 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/sync/features/WebRTC/generateRandomRoomName.ts:
--------------------------------------------------------------------------------
1 | export const generateRandomRoomName = async () => {
2 | const { generate } = await import('random-words');
3 | return (generate(3) as string[]).join('-');
4 | };
5 |
--------------------------------------------------------------------------------
/src/components/BrowserIcon/types.ts:
--------------------------------------------------------------------------------
1 | import { CSSProperties } from 'react';
2 |
3 | export interface SVGComponent {
4 | className?: string;
5 | height?: number | string;
6 | style?: CSSProperties;
7 | width?: number | string;
8 | }
9 |
--------------------------------------------------------------------------------
/src/types/i18next.d.ts:
--------------------------------------------------------------------------------
1 | import { DefaultResources } from '@/types/locale';
2 |
3 | declare module 'i18next' {
4 | interface CustomTypeOptions {
5 | defaultNS: ['common', 'setting'];
6 | resources: DefaultResources;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | contact_links:
2 | - name: Questions and ideas | 问题和想法
3 | url: https://github.com/lobehub/lobe-chat/discussions/new/choose
4 | about: Please post questions, and ideas in discussions. | 请在讨论区发布问题和想法。
5 |
--------------------------------------------------------------------------------
/.seorc.cjs:
--------------------------------------------------------------------------------
1 | const { defineConfig } = require('@lobehub/seo-cli');
2 |
3 | module.exports = defineConfig({
4 | entry: ['./docs/**/*.mdx'],
5 | modelName: 'gpt-4o-mini',
6 | experimental: {
7 | jsonMode: true,
8 | },
9 | });
10 |
--------------------------------------------------------------------------------
/locales/es-ES/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "Iniciar sesión",
3 | "loginOrSignup": "Iniciar sesión / Registrarse",
4 | "profile": "Perfil",
5 | "security": "Seguridad",
6 | "signout": "Cerrar sesión",
7 | "signup": "Registrarse"
8 | }
9 |
--------------------------------------------------------------------------------
/src/app/api/chat/minimax/route.ts:
--------------------------------------------------------------------------------
1 | import { POST as UniverseRoute } from '../[provider]/route';
2 |
3 | export const runtime = 'nodejs';
4 |
5 | export const POST = async (req: Request) => UniverseRoute(req, { params: { provider: 'minimax' } });
6 |
--------------------------------------------------------------------------------
/locales/pl-PL/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "login": "Zaloguj się",
3 | "loginOrSignup": "Zaloguj się / Zarejestruj się",
4 | "profile": "Profil użytkownika",
5 | "security": "Bezpieczeństwo",
6 | "signout": "Wyloguj",
7 | "signup": "Zarejestruj się"
8 | }
9 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/ollama/type.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @description images for ollama vision models (https://ollama.com/blog/vision-models)
3 | */
4 | export interface OllamaMessage {
5 | content: string;
6 | images?: string[];
7 | role: string;
8 | }
9 |
--------------------------------------------------------------------------------
/src/store/file/initialState.ts:
--------------------------------------------------------------------------------
1 | import { ImageFileState, initialImageFileState } from './slices/images';
2 |
3 | export type FilesStoreState = ImageFileState;
4 |
5 | export const initialState: FilesStoreState = {
6 | ...initialImageFileState,
7 | };
8 |
--------------------------------------------------------------------------------
/src/const/version.ts:
--------------------------------------------------------------------------------
1 | import pkg from '@/../package.json';
2 | import { getServerDBConfig } from '@/config/db';
3 |
4 | export const CURRENT_VERSION = pkg.version;
5 |
6 | export const isServerMode = getServerDBConfig().NEXT_PUBLIC_ENABLED_SERVER_SERVICE;
7 |
--------------------------------------------------------------------------------
/src/server/routers/tools/index.ts:
--------------------------------------------------------------------------------
1 | import { publicProcedure, router } from '@/libs/trpc';
2 |
3 | export const toolsRouter = router({
4 | healthcheck: publicProcedure.query(() => "i'm live!"),
5 | });
6 |
7 | export type ToolsRouter = typeof toolsRouter;
8 |
--------------------------------------------------------------------------------
/src/store/chat/slices/message/utils.ts:
--------------------------------------------------------------------------------
1 | export const messageMapKey = (sessionId: string, topicId?: string | null) => {
2 | let topic = topicId;
3 |
4 | if (typeof topicId === 'undefined') topic = null;
5 |
6 | return `${sessionId}_${topic}`;
7 | };
8 |
--------------------------------------------------------------------------------
/src/types/openai/functionCall.ts:
--------------------------------------------------------------------------------
1 | export interface OpenAIFunctionCall {
2 | arguments: string;
3 | name: string;
4 | }
5 |
6 | export interface OpenAIToolCall {
7 | function: OpenAIFunctionCall;
8 | id: string;
9 | type: 'function';
10 | }
11 |
--------------------------------------------------------------------------------
/src/hooks/useIsMobile.ts:
--------------------------------------------------------------------------------
1 | import { useResponsive } from 'antd-style';
2 | import { useMemo } from 'react';
3 |
4 | export const useIsMobile = (): boolean => {
5 | const { mobile } = useResponsive();
6 |
7 | return useMemo(() => !!mobile, [mobile]);
8 | };
9 |
--------------------------------------------------------------------------------
/src/store/agent/initialState.ts:
--------------------------------------------------------------------------------
1 | import { AgentState, initialAgentChatState } from './slices/chat/initialState';
2 |
3 | export type SessionStoreState = AgentState;
4 |
5 | export const initialState: SessionStoreState = {
6 | ...initialAgentChatState,
7 | };
8 |
--------------------------------------------------------------------------------
/src/store/file/selectors.ts:
--------------------------------------------------------------------------------
1 | import { filesSelectors as imageFilesSelectors } from './slices/images';
2 | import { ttsFilesSelectors } from './slices/tts';
3 |
4 | export const filesSelectors = {
5 | ...imageFilesSelectors,
6 | ...ttsFilesSelectors,
7 | };
8 |
--------------------------------------------------------------------------------
/locales/zh-CN/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "自动生成",
4 | "downloading": "DallE3 生成的图片链接有效期仅1小时,正在缓存图片到本地...",
5 | "generate": "生成",
6 | "generating": "生成中...",
7 | "images": "图片:",
8 | "prompt": "提示词"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/locales/zh-TW/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "文物",
3 | "actions": {
4 | "genAiMessage": "生成助手訊息",
5 | "summary": "摘要",
6 | "summaryTooltip": "總結目前內容"
7 | },
8 | "emptyArtifactList": "當前文物列表為空,請在會話中按需使用插件後再查看",
9 | "title": "擴展視窗"
10 | }
11 |
--------------------------------------------------------------------------------
/locales/zh-TW/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "自動生成",
4 | "downloading": "DallE3 生成的圖片連結有效期僅1小時,正在快取圖片到本地...",
5 | "generate": "生成",
6 | "generating": "生成中...",
7 | "images": "圖片:",
8 | "prompt": "提示詞"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/services/import/index.ts:
--------------------------------------------------------------------------------
1 | import { isServerMode } from '@/const/version';
2 |
3 | import { ClientService } from './client';
4 | import { ServerService } from './server';
5 |
6 | export const importService = isServerMode ? new ServerService() : new ClientService();
7 |
--------------------------------------------------------------------------------
/src/services/plugin/index.ts:
--------------------------------------------------------------------------------
1 | import { isServerMode } from '@/const/version';
2 |
3 | import { ClientService } from './client';
4 | import { ServerService } from './server';
5 |
6 | export const pluginService = isServerMode ? new ServerService() : new ClientService();
7 |
--------------------------------------------------------------------------------
/src/services/topic/index.ts:
--------------------------------------------------------------------------------
1 | import { isServerMode } from '@/const/version';
2 |
3 | import { ClientService } from './client';
4 | import { ServerService } from './server';
5 |
6 | export const topicService = isServerMode ? new ServerService() : new ClientService();
7 |
--------------------------------------------------------------------------------
/src/services/user/index.ts:
--------------------------------------------------------------------------------
1 | import { isServerMode } from '@/const/version';
2 |
3 | import { ClientService } from './client';
4 | import { ServerService } from './server';
5 |
6 | export const userService = isServerMode ? new ServerService() : new ClientService();
7 |
--------------------------------------------------------------------------------
/src/database/client/schemas/sessionGroup.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod';
2 |
3 | export const DB_SessionGroupSchema = z.object({
4 | name: z.string(),
5 | sort: z.number().optional(),
6 | });
7 |
8 | export type DB_SessionGroup = z.infer;
9 |
--------------------------------------------------------------------------------
/src/server/mock.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file contains the root router of your tRPC-backend
3 | */
4 | import { createCallerFactory } from '@/libs/trpc';
5 |
6 | import { edgeRouter } from './routers/edge';
7 |
8 | export const createCaller = createCallerFactory(edgeRouter);
9 |
--------------------------------------------------------------------------------
/src/services/session/index.ts:
--------------------------------------------------------------------------------
1 | import { isServerMode } from '@/const/version';
2 |
3 | import { ClientService } from './client';
4 | import { ServerService } from './server';
5 |
6 | export const sessionService = isServerMode ? new ServerService() : new ClientService();
7 |
--------------------------------------------------------------------------------
/src/store/chat/slices/portal/initialState.ts:
--------------------------------------------------------------------------------
1 | export interface ChatPortalState {
2 | portalToolMessage?: { id: string; identifier: string };
3 | showPortal: boolean;
4 | }
5 |
6 | export const initialChatPortalState: ChatPortalState = {
7 | showPortal: false,
8 | };
9 |
--------------------------------------------------------------------------------
/src/const/user.ts:
--------------------------------------------------------------------------------
1 | import { UserPreference } from '@/types/user';
2 |
3 | export const DEFAULT_PREFERENCE: UserPreference = {
4 | guide: {
5 | moveSettingsToAvatar: true,
6 | topic: true,
7 | },
8 | telemetry: null,
9 | useCmdEnterToSend: false,
10 | };
11 |
--------------------------------------------------------------------------------
/src/locales/default/tool.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | dalle: {
3 | autoGenerate: '自动生成',
4 | downloading: 'DallE3 生成的图片链接有效期仅1小时,正在缓存图片到本地...',
5 | generate: '生成',
6 | generating: '生成中...',
7 | images: '图片:',
8 | prompt: '提示词',
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/locales/zh-CN/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Artifacts",
3 | "actions": {
4 | "genAiMessage": "创建助手消息",
5 | "summary": "总结",
6 | "summaryTooltip": "总结当前内容"
7 | },
8 | "emptyArtifactList": "当前 Artifacts 列表为空,请在会话中按需使用插件后再查看",
9 | "title": "工作区"
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/loading.tsx:
--------------------------------------------------------------------------------
1 | import SkeletonLoading from '@/components/SkeletonLoading';
2 |
3 | export default () => {
4 | return (
5 |
6 |
7 |
8 | );
9 | };
10 |
--------------------------------------------------------------------------------
/src/types/user/settings/tts.ts:
--------------------------------------------------------------------------------
1 | export type STTServer = 'openai' | 'browser';
2 |
3 | export interface UserTTSConfig {
4 | openAI: {
5 | sttModel: 'whisper-1';
6 | ttsModel: 'tts-1' | 'tts-1-hd';
7 | };
8 | sttAutoStop: boolean;
9 | sttServer: STTServer;
10 | }
11 |
--------------------------------------------------------------------------------
/locales/ja-JP/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "自動生成",
4 | "downloading": "DallE3 で生成された画像リンクは有効期間が1時間しかありません。画像をローカルにキャッシュしています...",
5 | "generate": "生成する",
6 | "generating": "生成中...",
7 | "images": "画像:",
8 | "prompt": "プロンプト"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/locales/ko-KR/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "자동 생성",
4 | "downloading": "DallE3로 생성된 이미지 링크는 1시간 동안 유효하며, 로컬에 이미지를 캐시하는 중입니다...",
5 | "generate": "생성",
6 | "generating": "생성 중...",
7 | "images": "이미지:",
8 | "prompt": "알림 단어"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/const/settings/tts.ts:
--------------------------------------------------------------------------------
1 | import { UserTTSConfig } from '@/types/user/settings';
2 |
3 | export const DEFAULT_TTS_CONFIG: UserTTSConfig = {
4 | openAI: {
5 | sttModel: 'whisper-1',
6 | ttsModel: 'tts-1',
7 | },
8 | sttAutoStop: true,
9 | sttServer: 'openai',
10 | };
11 |
--------------------------------------------------------------------------------
/src/locales/default/portal.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | Artifacts: 'Artifacts',
3 | actions: {
4 | genAiMessage: '创建助手消息',
5 | summary: '总结',
6 | summaryTooltip: '总结当前内容',
7 | },
8 | emptyArtifactList: '当前 Artifacts 列表为空,请在会话中按需使用插件后再查看',
9 | title: '工作区',
10 | };
11 |
--------------------------------------------------------------------------------
/src/store/chat/selectors.ts:
--------------------------------------------------------------------------------
1 | export { chatToolSelectors } from './slices/builtinTool/selectors';
2 | export { chatSelectors } from './slices/message/selectors';
3 | export { chatPortalSelectors } from './slices/portal/selectors';
4 | export { topicSelectors } from './slices/topic/selectors';
5 |
--------------------------------------------------------------------------------
/src/types/tool/tool.ts:
--------------------------------------------------------------------------------
1 | import { MetaData } from '@/types/meta';
2 |
3 | export type LobeToolType = 'builtin' | 'customPlugin' | 'plugin';
4 |
5 | export interface LobeToolMeta {
6 | author?: string;
7 | identifier: string;
8 | meta: MetaData;
9 | type: LobeToolType;
10 | }
11 |
--------------------------------------------------------------------------------
/src/types/topic.ts:
--------------------------------------------------------------------------------
1 | import { BaseDataModel } from '@/types/meta';
2 |
3 | export interface ChatTopic extends Omit {
4 | favorite?: boolean;
5 | sessionId?: string;
6 | title: string;
7 | }
8 |
9 | export type ChatTopicMap = Record;
10 |
--------------------------------------------------------------------------------
/src/types/user/settings/sync.ts:
--------------------------------------------------------------------------------
1 | export interface WebRTCSyncConfig {
2 | channelName?: string;
3 | channelPassword?: string;
4 | enabled: boolean;
5 | signaling?: string;
6 | }
7 | export interface UserSyncSettings {
8 | deviceName?: string;
9 | webrtc: WebRTCSyncConfig;
10 | }
11 |
--------------------------------------------------------------------------------
/locales/ko-KR/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "아티팩트",
3 | "actions": {
4 | "genAiMessage": "AI 메시지 생성",
5 | "summary": "요약",
6 | "summaryTooltip": "현재 콘텐츠를 요약합니다"
7 | },
8 | "emptyArtifactList": "현재 아티팩트 목록이 비어 있습니다. 플러그인을 사용한 후에 다시 확인해주세요.",
9 | "title": "확장 창"
10 | }
11 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | command = "pnpm run build"
3 | publish = ".next"
4 |
5 | [build.environment]
6 | NODE_OPTIONS = "--max_old_space_size=8192"
7 |
8 | [template.environment]
9 | OPENAI_API_KEY = "set your OpenAI API Key"
10 | ACCESS_CODE = "set your password to protect your api key"
11 |
--------------------------------------------------------------------------------
/src/components/Analytics/Google.tsx:
--------------------------------------------------------------------------------
1 | import { GoogleAnalytics as GA } from '@next/third-parties/google';
2 |
3 | import { analyticsEnv } from '@/config/analytics';
4 |
5 | const GoogleAnalytics = () => ;
6 |
7 | export default GoogleAnalytics;
8 |
--------------------------------------------------------------------------------
/src/libs/next-auth/sso-providers/index.ts:
--------------------------------------------------------------------------------
1 | import Auth0 from './auth0';
2 | import Authentik from './authentik';
3 | import AzureAD from './azure-ad';
4 | import Github from './github';
5 | import Zitadel from './zitadel';
6 |
7 | export const ssoProviders = [Auth0, Authentik, AzureAD, Github, Zitadel];
8 |
--------------------------------------------------------------------------------
/locales/ja-JP/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "アーティファクト",
3 | "actions": {
4 | "genAiMessage": "AIメッセージを生成",
5 | "summary": "サマリー",
6 | "summaryTooltip": "現在の内容を要約"
7 | },
8 | "emptyArtifactList": "現在、アーティファクトリストは空です。プラグインを使用してセッション中に追加してください。",
9 | "title": "拡張ウィンドウ"
10 | }
11 |
--------------------------------------------------------------------------------
/src/hooks/useQuery.ts:
--------------------------------------------------------------------------------
1 | import { useSearchParams } from 'next/navigation';
2 | import qs from 'query-string';
3 | import { useMemo } from 'react';
4 |
5 | export const useQuery = () => {
6 | const rawQuery = useSearchParams();
7 | return useMemo(() => qs.parse(rawQuery.toString()), [rawQuery]);
8 | };
9 |
--------------------------------------------------------------------------------
/src/tools/index.ts:
--------------------------------------------------------------------------------
1 | import { LobeBuiltinTool } from '@/types/tool';
2 |
3 | import { DalleManifest } from './dalle';
4 |
5 | export const builtinTools: LobeBuiltinTool[] = [
6 | {
7 | identifier: DalleManifest.identifier,
8 | manifest: DalleManifest,
9 | type: 'builtin',
10 | },
11 | ];
12 |
--------------------------------------------------------------------------------
/src/app/(main)/@nav/default.tsx:
--------------------------------------------------------------------------------
1 | import ServerLayout from '@/components/server/ServerLayout';
2 |
3 | import Desktop from './_layout/Desktop';
4 | import Mobile from './_layout/Mobile';
5 |
6 | const Nav = ServerLayout({ Desktop, Mobile });
7 |
8 | Nav.displayName = 'Nav';
9 |
10 | export default Nav;
11 |
--------------------------------------------------------------------------------
/src/utils/safeParseJSON.ts:
--------------------------------------------------------------------------------
1 | export const safeParseJSON = >(text: string) => {
2 | if (typeof text !== 'string') return undefined;
3 |
4 | let json: T;
5 | try {
6 | json = JSON.parse(text);
7 | } catch {
8 | return undefined;
9 | }
10 |
11 | return json;
12 | };
13 |
--------------------------------------------------------------------------------
/scripts/i18nWorkflow/index.ts:
--------------------------------------------------------------------------------
1 | import { genDefaultLocale } from './genDefaultLocale';
2 | import { genDiff } from './genDiff';
3 | import { split } from './utils';
4 |
5 | split('DIFF ANALYSIS');
6 | genDiff();
7 |
8 | split('GENERATE DEFAULT LOCALE');
9 | genDefaultLocale();
10 |
11 | split('GENERATE I18N FILES');
12 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/tts/index.tsx:
--------------------------------------------------------------------------------
1 | import OpenAI from './features/OpenAI';
2 | import STT from './features/STT';
3 |
4 | const Page = () => {
5 | return (
6 | <>
7 |
8 |
9 | >
10 | );
11 | };
12 |
13 | Page.displayName = 'TtsSetting';
14 |
15 | export default Page;
16 |
--------------------------------------------------------------------------------
/src/components/Analytics/Vercel.tsx:
--------------------------------------------------------------------------------
1 | import { Analytics } from '@vercel/analytics/react';
2 | import { memo } from 'react';
3 |
4 | import { analyticsEnv } from '@/config/analytics';
5 |
6 | const VercelAnalytics = memo(() => );
7 |
8 | export default VercelAnalytics;
9 |
--------------------------------------------------------------------------------
/src/migrations/FromV0ToV1.ts:
--------------------------------------------------------------------------------
1 | import type { Migration, MigrationData } from './VersionController';
2 |
3 | export class MigrationV0ToV1 implements Migration {
4 | // from this version to start migration
5 | version = 0;
6 |
7 | migrate(data: MigrationData): MigrationData {
8 | return data;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/utils/uploadFIle.ts:
--------------------------------------------------------------------------------
1 | export const createUploadImageHandler =
2 | (onUploadImage: (base64: string) => void) => (file: any) => {
3 | const reader = new FileReader();
4 | reader.readAsDataURL(file);
5 | reader.addEventListener('load', () => {
6 | onUploadImage(String(reader.result));
7 | });
8 | };
9 |
--------------------------------------------------------------------------------
/src/components/PageTitle/index.tsx:
--------------------------------------------------------------------------------
1 | import { memo, useEffect } from 'react';
2 |
3 | const PageTitle = memo<{ title: string }>(({ title }) => {
4 | useEffect(() => {
5 | document.title = title ? `${title} · LobeChat` : 'LobeChat';
6 | }, [title]);
7 |
8 | return null;
9 | });
10 |
11 | export default PageTitle;
12 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/novita/type.ts:
--------------------------------------------------------------------------------
1 | export interface NovitaModelCard {
2 | context_size: number;
3 | created: number;
4 | description: string;
5 | id: string;
6 | input_token_price_per_m: number;
7 | output_token_price_per_m: number;
8 | status: number;
9 | tags: string[];
10 | title: string;
11 | }
12 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/utils/streams/index.ts:
--------------------------------------------------------------------------------
1 | export * from './anthropic';
2 | export * from './azureOpenai';
3 | export * from './bedrock';
4 | export * from './google-ai';
5 | export * from './minimax';
6 | export * from './ollama';
7 | export * from './openai';
8 | export * from './protocol';
9 | export * from './qwen';
10 |
--------------------------------------------------------------------------------
/src/services/message/index.ts:
--------------------------------------------------------------------------------
1 | import { isServerMode } from '@/const/version';
2 |
3 | import { ClientService } from './client';
4 | import { ServerService } from './server';
5 |
6 | export type { CreateMessageParams } from './type';
7 |
8 | export const messageService = isServerMode ? new ServerService() : new ClientService();
9 |
--------------------------------------------------------------------------------
/src/utils/zustand.ts:
--------------------------------------------------------------------------------
1 | import { StoreApi } from 'zustand';
2 |
3 | export interface StoreApiWithSelector extends Omit, 'subscribe'> {
4 | subscribe: (
5 | selector: (state: Store, prevState: Store) => void,
6 | listener?: (state: Store[T]) => void,
7 | ) => () => void;
8 | }
9 |
--------------------------------------------------------------------------------
/tests/utils.tsx:
--------------------------------------------------------------------------------
1 | import { PropsWithChildren } from 'react';
2 | import { SWRConfig } from 'swr';
3 |
4 | // 全局的 SWR 配置
5 | const swrConfig = {
6 | provider: () => new Map(),
7 | };
8 |
9 | export const withSWR = ({ children }: PropsWithChildren) => (
10 | {children}
11 | );
12 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
15 | [Makefile]
16 | indent_style = tab
17 |
--------------------------------------------------------------------------------
/docs/self-hosting/server-database/sealos.zh-CN.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 在 SealOS 上部署 LobeChat
3 | description: 学习如何在 SealOS 上部署 LobeChat,包括准备 OpenAI API Key、点击部署按钮、绑定自定义域名等操作。
4 | tags:
5 | - SealOS
6 | - LobeChat
7 | - OpenAI API Key
8 | - 部署流程
9 | - 自定义域名
10 | ---
11 |
12 | # 使用 SealOS 部署 LobeChat 数据库版
13 |
14 | TODO
15 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/index.tsx:
--------------------------------------------------------------------------------
1 | import { ChatHeader } from '@lobehub/ui';
2 |
3 | import HeaderAction from './HeaderAction';
4 | import Main from './Main';
5 |
6 | const Header = () => } right={} style={{ zIndex: 11 }} />;
7 |
8 | export default Header;
9 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/common/index.tsx:
--------------------------------------------------------------------------------
1 | import Common from './features/Common';
2 | import Theme from './features/Theme';
3 |
4 | const Page = () => {
5 | return (
6 | <>
7 |
8 |
9 | >
10 | );
11 | };
12 |
13 | Page.displayName = 'CommonSetting';
14 |
15 | export default Page;
16 |
--------------------------------------------------------------------------------
/src/utils/storeDebug.ts:
--------------------------------------------------------------------------------
1 | export const setNamespace = (namespace: string) => {
2 | return (type: string, payload?: any) => {
3 | const name = [namespace, type].filter(Boolean).join('/');
4 | return payload
5 | ? {
6 | payload,
7 | type: name,
8 | }
9 | : name;
10 | };
11 | };
12 |
--------------------------------------------------------------------------------
/src/app/api/tts/edge-speech/route.ts:
--------------------------------------------------------------------------------
1 | import { EdgeSpeechPayload, EdgeSpeechTTS } from '@lobehub/tts';
2 |
3 | export const runtime = 'edge';
4 |
5 | export const POST = async (req: Request) => {
6 | const payload = (await req.json()) as EdgeSpeechPayload;
7 |
8 | return await EdgeSpeechTTS.createRequest({ payload });
9 | };
10 |
--------------------------------------------------------------------------------
/src/store/file/slices/images/initialState.ts:
--------------------------------------------------------------------------------
1 | import { FilePreview } from '@/types/files';
2 |
3 | export interface ImageFileState {
4 | imagesMap: Record;
5 | inputFilesList: string[];
6 | }
7 |
8 | export const initialImageFileState: ImageFileState = {
9 | imagesMap: {},
10 | inputFilesList: [],
11 | };
12 |
--------------------------------------------------------------------------------
/src/store/user/helpers.ts:
--------------------------------------------------------------------------------
1 | import { userGeneralSettingsSelectors } from './slices/settings/selectors';
2 | import { useUserStore } from './store';
3 |
4 | const getCurrentLanguage = () =>
5 | userGeneralSettingsSelectors.currentLanguage(useUserStore.getState());
6 |
7 | export const globalHelpers = {
8 | getCurrentLanguage,
9 | };
10 |
--------------------------------------------------------------------------------
/src/utils/parseMarkdown.ts:
--------------------------------------------------------------------------------
1 | import { remark } from 'remark';
2 | import remarkGfm from 'remark-gfm';
3 | import remarkHtml from 'remark-html';
4 |
5 | export const parseMarkdown = async (content: string) => {
6 | const file = await remark().use(remarkGfm).use(remarkHtml).process(content.trim());
7 |
8 | return String(file);
9 | };
10 |
--------------------------------------------------------------------------------
/docs/self-hosting/server-database/repocloud.zh-CN.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 在 RepoCloud 上部署 LobeChat 数据库版
3 | description: 学习如何在RepoCloud上部署LobeChat应用,包括准备OpenAI API Key、点击部署按钮、绑定自定义域名等操作。
4 | tags:
5 | - RepoCloud
6 | - LobeChat
7 | - 部署流程
8 | - OpenAI API Key
9 | - 自定义域名
10 | ---
11 |
12 | # 使用 RepoCloud 部署 LobeChat 数据库版
13 |
14 | TODO
15 |
--------------------------------------------------------------------------------
/locales/en-US/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "Auto Generate",
4 | "downloading": "The image links generated by DALL·E3 are only valid for 1 hour, caching the images locally...",
5 | "generate": "Generate",
6 | "generating": "Generating...",
7 | "images": "Images:",
8 | "prompt": "提示词"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/locales/vi-VN/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "Tự động tạo",
4 | "downloading": "Liên kết hình ảnh được tạo bởi DallE3 chỉ có hiệu lực trong 1 giờ, đang tải hình ảnh xuống máy...",
5 | "generate": "Tạo",
6 | "generating": "Đang tạo...",
7 | "images": "Hình ảnh:",
8 | "prompt": "Từ khóa"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/features/Conversation/Extras/index.ts:
--------------------------------------------------------------------------------
1 | import { RenderMessageExtra } from '../types';
2 | import { AssistantMessageExtra } from './Assistant';
3 | import { UserMessageExtra } from './User';
4 |
5 | export const renderMessagesExtra: Record = {
6 | assistant: AssistantMessageExtra,
7 | user: UserMessageExtra,
8 | };
9 |
--------------------------------------------------------------------------------
/src/features/PluginStore/Loading.tsx:
--------------------------------------------------------------------------------
1 | import { Skeleton } from 'antd';
2 | import { memo } from 'react';
3 | import { Flexbox } from 'react-layout-kit';
4 |
5 | const Loading = memo(() => {
6 | return (
7 |
8 |
9 |
10 | );
11 | });
12 |
13 | export default Loading;
14 |
--------------------------------------------------------------------------------
/src/utils/client/switchLang.ts:
--------------------------------------------------------------------------------
1 | import { changeLanguage } from 'i18next';
2 |
3 | import { LocaleMode } from '@/types/locale';
4 |
5 | export const switchLang = (locale: LocaleMode) => {
6 | const lang = locale === 'auto' ? navigator.language : locale;
7 |
8 | changeLanguage(lang);
9 | document.documentElement.lang = lang;
10 | };
11 |
--------------------------------------------------------------------------------
/docs/self-hosting/server-database/railway.zh-CN.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 在 Railway 上部署 LobeChat 数据库版
3 | description: 学习如何在 Railway 上部署 LobeChat 应用,包括准备 OpenAI API Key、点击按钮进行部署、绑定自定义域名等步骤。
4 | tags:
5 | - Railway
6 | - 部署
7 | - LobeChat
8 | - OpenAI
9 | - API Key
10 | - 自定义域名
11 | ---
12 |
13 | # 使用 Railway 部署 LobeChat 数据库版
14 |
15 | TODO
16 |
--------------------------------------------------------------------------------
/src/app/(main)/welcome/layout.tsx:
--------------------------------------------------------------------------------
1 | import ServerLayout from '@/components/server/ServerLayout';
2 |
3 | import Desktop from './_layout/Desktop';
4 | import Mobile from './_layout/Mobile';
5 |
6 | const WelcomeLayout = ServerLayout({ Desktop, Mobile });
7 |
8 | WelcomeLayout.displayName = 'WelcomeLayout';
9 |
10 | export default WelcomeLayout;
11 |
--------------------------------------------------------------------------------
/src/store/tool/selectors/index.ts:
--------------------------------------------------------------------------------
1 | export { builtinToolSelectors } from '../slices/builtin/selectors';
2 | export { customPluginSelectors } from '../slices/customPlugin/selectors';
3 | export { pluginSelectors } from '../slices/plugin/selectors';
4 | export { pluginStoreSelectors } from '../slices/store/selectors';
5 | export { toolSelectors } from './tool';
6 |
--------------------------------------------------------------------------------
/src/utils/merge.ts:
--------------------------------------------------------------------------------
1 | import { merge as _merge, mergeWith } from 'lodash-es';
2 |
3 | /**
4 | * 用于合并对象,如果是数组则直接替换
5 | * @param target
6 | * @param source
7 | */
8 | export const merge: typeof _merge = (target: T, source: T) =>
9 | mergeWith({}, target, source, (obj, src) => {
10 | if (Array.isArray(obj)) return src;
11 | });
12 |
--------------------------------------------------------------------------------
/locales/ar/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "توليد تلقائي",
4 | "downloading": "صلاحية روابط الصور المُولَّدة بواسطة DallE3 تدوم ساعة واحدة فقط، يتم تحميل الصور إلى الجهاز المحلي...",
5 | "generate": "توليد",
6 | "generating": "جارٍ التوليد...",
7 | "images": "الصور:",
8 | "prompt": "كلمة تلميح"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/hooks/useProviderName.ts:
--------------------------------------------------------------------------------
1 | import { DEFAULT_MODEL_PROVIDER_LIST } from '@/config/modelProviders';
2 |
3 | export const useProviderName = (provider: string) => {
4 | // const { t } = useTranslation('modelProvider');
5 | const providerCard = DEFAULT_MODEL_PROVIDER_LIST.find((p) => p.id === provider);
6 |
7 | return providerCard?.name || provider;
8 | };
9 |
--------------------------------------------------------------------------------
/.github/workflows/issues-translate.yml:
--------------------------------------------------------------------------------
1 | name: Issue Translate
2 | on:
3 | issue_comment:
4 | types: [created]
5 | issues:
6 | types: [opened]
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: usthe/issues-translate-action@v2.7
13 | with:
14 | BOT_GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
15 |
--------------------------------------------------------------------------------
/scripts/readmeWorkflow/index.ts:
--------------------------------------------------------------------------------
1 | import { consola } from 'consola';
2 |
3 | import syncAgentIndex from './syncAgentIndex';
4 | import syncPluginIndex from './syncPluginIndex';
5 |
6 | const runSync = async () => {
7 | consola.start('Start sync readme workflow...');
8 | await syncAgentIndex();
9 | await syncPluginIndex();
10 | };
11 |
12 | runSync();
13 |
--------------------------------------------------------------------------------
/src/app/api/tts/microsoft-speech/route.ts:
--------------------------------------------------------------------------------
1 | import { MicrosoftSpeechPayload, MicrosoftSpeechTTS } from '@lobehub/tts';
2 |
3 | export const runtime = 'edge';
4 |
5 | export const POST = async (req: Request) => {
6 | const payload = (await req.json()) as MicrosoftSpeechPayload;
7 |
8 | return await MicrosoftSpeechTTS.createRequest({ payload });
9 | };
10 |
--------------------------------------------------------------------------------
/src/database/server/schemas/lobechat/_helpers.ts:
--------------------------------------------------------------------------------
1 | import { timestamp } from 'drizzle-orm/pg-core';
2 |
3 | export const timestamptz = (name: string) => timestamp(name, { withTimezone: true });
4 |
5 | export const createdAt = () => timestamptz('created_at').notNull().defaultNow();
6 | export const updatedAt = () => timestamptz('updated_at').notNull().defaultNow();
7 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/(workspace)/features/ShareButton/type.ts:
--------------------------------------------------------------------------------
1 | export enum ImageType {
2 | JPG = 'jpg',
3 | PNG = 'png',
4 | SVG = 'svg',
5 | WEBP = 'webp',
6 | }
7 |
8 | export type FieldType = {
9 | imageType: ImageType;
10 | withBackground: boolean;
11 | withFooter: boolean;
12 | withPluginInfo: boolean;
13 | withSystemRole: boolean;
14 | };
15 |
--------------------------------------------------------------------------------
/src/components/StructuredData/index.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 |
3 | const StructuredData: FC<{ ld: any }> = ({ ld }) => {
4 | return (
5 |
10 | );
11 | };
12 | export default StructuredData;
13 |
--------------------------------------------------------------------------------
/src/store/tool/slices/customPlugin/selectors.ts:
--------------------------------------------------------------------------------
1 | import { pluginHelpers } from '../../helpers';
2 | import type { ToolStoreState } from '../../initialState';
3 |
4 | const isCustomPlugin = (id: string) => (s: ToolStoreState) =>
5 | pluginHelpers.isCustomPlugin(id, s.installedPlugins);
6 |
7 | export const customPluginSelectors = {
8 | isCustomPlugin,
9 | };
10 |
--------------------------------------------------------------------------------
/src/styles/index.ts:
--------------------------------------------------------------------------------
1 | import { createGlobalStyle } from 'antd-style';
2 |
3 | import antdOverride from './antdOverride';
4 | import global from './global';
5 |
6 | const prefixCls = 'ant';
7 |
8 | export const GlobalStyle = createGlobalStyle(({ theme }) => [
9 | global({ prefixCls, token: theme }),
10 | antdOverride({ prefixCls, token: theme }),
11 | ]);
12 |
--------------------------------------------------------------------------------
/src/types/user/settings/systemAgent.ts:
--------------------------------------------------------------------------------
1 | export interface SystemAgentItem {
2 | model: string;
3 | provider: string;
4 | }
5 |
6 | export interface UserSystemAgentConfig {
7 | agentMeta: SystemAgentItem;
8 | topic: SystemAgentItem;
9 | translation: SystemAgentItem;
10 | }
11 |
12 | export type UserSystemAgentConfigKey = keyof UserSystemAgentConfig;
13 |
--------------------------------------------------------------------------------
/locales/pt-BR/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "Auto gerar",
4 | "downloading": "O link da imagem gerada pelo DALL·E3 é válido apenas por 1 hora, está baixando a imagem para o armazenamento local...",
5 | "generate": "Gerar",
6 | "generating": "Gerando...",
7 | "images": "Imagens:",
8 | "prompt": "Palavra-chave"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/(loading)/Client.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { useTranslation } from 'react-i18next';
4 |
5 | import FullscreenLoading from '@/components/FullscreenLoading';
6 |
7 | const Loading = () => {
8 | const { t } = useTranslation('common');
9 |
10 | return ;
11 | };
12 |
13 | export default Loading;
14 |
--------------------------------------------------------------------------------
/src/const/layoutTokens.test.ts:
--------------------------------------------------------------------------------
1 | import { HEADER_ICON_SIZE } from './layoutTokens';
2 |
3 | describe('HEADER_ICON_SIZE', () => {
4 | it('mobile', () => {
5 | expect(HEADER_ICON_SIZE(true)).toEqual({ blockSize: 36, fontSize: 22 });
6 | });
7 |
8 | it('desktop', () => {
9 | expect(HEADER_ICON_SIZE(false)).toEqual({ fontSize: 24 });
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/src/const/meta.ts:
--------------------------------------------------------------------------------
1 | import { MetaData } from '@/types/meta';
2 |
3 | export const DEFAULT_AVATAR = '🤖';
4 | export const DEFAULT_USER_AVATAR = '😀';
5 | export const DEFAULT_BACKGROUND_COLOR = 'rgba(0,0,0,0)';
6 | export const DEFAULT_AGENT_META: MetaData = {};
7 | export const DEFAULT_INBOX_AVATAR = '🤯';
8 | export const DEFAULT_USER_AVATAR_URL = '/icons/icon-192x192.png';
9 |
--------------------------------------------------------------------------------
/src/styles/mobileHeader.ts:
--------------------------------------------------------------------------------
1 | import { CSSProperties } from 'react';
2 |
3 | export const mobileHeaderSticky: CSSProperties = {
4 | position: 'sticky',
5 | top: 0,
6 | width: '100%',
7 | zIndex: 100,
8 | };
9 |
10 | export const mobileHeaderFixed: CSSProperties = {
11 | position: 'absolute',
12 | top: 0,
13 | width: '100%',
14 | zIndex: 100,
15 | };
16 |
--------------------------------------------------------------------------------
/docs/self-hosting/server-database/sealos.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Deploy LobeChat on SealOS
3 | description: >-
4 | Learn how to deploy LobeChat on SealOS with ease. Follow the provided steps to
5 | set up LobeChat and start using it efficiently.
6 | tags:
7 | - Deploy LobeChat
8 | - SealOS Deployment
9 | - OpenAI API Key
10 | - Custom Domain Binding
11 | ---
12 |
13 |
--------------------------------------------------------------------------------
/locales/de-DE/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "Automatisch generieren",
4 | "downloading": "Die von DallE3 generierten Bildlinks sind nur 1 Stunde lang gültig. Das Bild wird lokal zwischengespeichert...",
5 | "generate": "Generieren",
6 | "generating": "Generiert",
7 | "images": "Bilder:",
8 | "prompt": "Hinweiswort"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/locales/it-IT/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "Auto-generato",
4 | "downloading": "Il link dell'immagine generata da DALL·E3 è valido solo per 1 ora, sta scaricando l'immagine in locale...",
5 | "generate": "Genera",
6 | "generating": "Generazione in corso...",
7 | "images": "Immagini:",
8 | "prompt": "parola chiave"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/locales/tr-TR/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "Otomatik Oluştur",
4 | "downloading": "DallE3 tarafından oluşturulan resim bağlantıları sadece 1 saat geçerlidir, resim yerel olarak önbelleğe alınıyor...",
5 | "generate": "Oluştur",
6 | "generating": "Oluşturuluyor...",
7 | "images": "Görseller:",
8 | "prompt": "İpucu"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/ModelTag/index.tsx:
--------------------------------------------------------------------------------
1 | import { Tag } from '@lobehub/ui';
2 | import { memo } from 'react';
3 |
4 | import ModelIcon from './ModelIcon';
5 |
6 | interface ModelTagProps {
7 | model: string;
8 | }
9 | const ModelTag = memo(({ model }) => (
10 | }>{model}
11 | ));
12 |
13 | export default ModelTag;
14 |
--------------------------------------------------------------------------------
/src/features/AgentSetting/AgentTTS/options.ts:
--------------------------------------------------------------------------------
1 | import { SelectProps } from 'antd';
2 |
3 | export const ttsOptions: SelectProps['options'] = [
4 | {
5 | label: 'OpenAI',
6 | value: 'openai',
7 | },
8 | {
9 | label: 'Edge Speech',
10 | value: 'edge',
11 | },
12 | {
13 | label: 'Microsoft Speech',
14 | value: 'microsoft',
15 | },
16 | ];
17 |
--------------------------------------------------------------------------------
/src/hooks/useIsSubSlug.ts:
--------------------------------------------------------------------------------
1 | import { usePathname } from 'next/navigation';
2 |
3 | /**
4 | * Returns true if the current path has a sub slug (`/chat/mobile` or `/chat/settings`)
5 | */
6 | export const useIsSubSlug = () => {
7 | const pathname = usePathname();
8 |
9 | const slugs = pathname.split('/').filter(Boolean);
10 |
11 | return slugs.length > 1;
12 | };
13 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/utils/response.ts:
--------------------------------------------------------------------------------
1 | export const StreamingResponse = (
2 | stream: ReadableStream,
3 | options?: { headers?: Record },
4 | ) => {
5 | return new Response(stream, {
6 | headers: {
7 | 'Cache-Control': 'no-cache',
8 | 'Content-Type': 'text/event-stream',
9 | ...options?.headers,
10 | },
11 | });
12 | };
13 |
--------------------------------------------------------------------------------
/src/libs/trpc/client/types.ts:
--------------------------------------------------------------------------------
1 | export type ErrorResponse = ErrorItem[];
2 |
3 | export interface ErrorItem {
4 | error: {
5 | json: {
6 | code: number;
7 | data: Data;
8 | message: string;
9 | };
10 | };
11 | }
12 |
13 | export interface Data {
14 | code: string;
15 | httpStatus: number;
16 | path: string;
17 | stack: string;
18 | }
19 |
--------------------------------------------------------------------------------
/docs/self-hosting/server-database/netlify.zh-CN.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 在 Netlify 上部署 LobeChat 服务端数据库版
3 | description: >-
4 | 学习如何在 Netlify 上部署 LobeChat,包括 Fork 仓库、准备 OpenAI API Key、导入到 Netlify
5 | 工作台、配置站点名称与环境变量等步骤。
6 | tags:
7 | - Netlify
8 | - LobeChat
9 | - 部署教程
10 | - OpenAI API Key
11 | - 环境配置
12 | ---
13 |
14 | # 使用 Netlify 部署 LobeChat 数据库版
15 |
16 | TODO
17 |
--------------------------------------------------------------------------------
/locales/ar/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "القطع الأثرية",
3 | "actions": {
4 | "genAiMessage": "إنشاء رسالة مساعد ذكاء اصطناعي",
5 | "summary": "ملخص",
6 | "summaryTooltip": "ملخص للمحتوى الحالي"
7 | },
8 | "emptyArtifactList": "قائمة القطع الأثرية الحالية فارغة، يرجى استخدام الإضافات في الجلسة ومن ثم التحقق مرة أخرى",
9 | "title": "نافذة موسعة"
10 | }
11 |
--------------------------------------------------------------------------------
/locales/ru-RU/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "Автогенерация",
4 | "downloading": "Ссылка на изображение, созданное DALL·E3, действительна только в течение 1 часа. Идет кэширование изображения локально...",
5 | "generate": "Создать",
6 | "generating": "Создание...",
7 | "images": "Изображения:",
8 | "prompt": "подсказка"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/(main)/market/@detail/default.tsx:
--------------------------------------------------------------------------------
1 | import { isMobileDevice } from '@/utils/responsive';
2 |
3 | import AgentDetailContent from './features/AgentDetailContent';
4 |
5 | const Detail = () => {
6 | const mobile = isMobileDevice();
7 | return ;
8 | };
9 |
10 | Detail.displayName = 'AgentDetail';
11 |
12 | export default Detail;
13 |
--------------------------------------------------------------------------------
/src/database/client/schemas/topic.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable sort-keys-fix/sort-keys-fix */
2 | import { z } from 'zod';
3 |
4 | export const DB_TopicSchema = z.object({
5 | title: z.string(),
6 | favorite: z.number().int().default(0),
7 |
8 | // foreign keys
9 | sessionId: z.string().optional(),
10 | });
11 |
12 | export type DB_Topic = z.infer;
13 |
--------------------------------------------------------------------------------
/locales/bg-BG/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "Автоматично генериране",
4 | "downloading": "Връзките към изображенията, генерирани от DALL·E3, са валидни само за 1 час, кеширане на изображенията локално...",
5 | "generate": "Генерирай",
6 | "generating": "Генериране...",
7 | "images": "Изображения:",
8 | "prompt": "подсказка"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/locales/es-ES/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "Auto-generar",
4 | "downloading": "El enlace de la imagen generada por DALL·E 3 solo es válido durante 1 hora, descargando la imagen al dispositivo local...",
5 | "generate": "Generar",
6 | "generating": "Generando...",
7 | "images": "Imágenes:",
8 | "prompt": "Palabra de aviso"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/locales/tr-TR/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Artefaktlar",
3 | "actions": {
4 | "genAiMessage": "Yapay Zeka Mesajı Oluştur",
5 | "summary": "Özet",
6 | "summaryTooltip": "Mevcut içeriği özetle"
7 | },
8 | "emptyArtifactList": "Mevcut Artefakt listesi boş, lütfen eklentileri kullanarak oturumda gerektiğinde göz atın",
9 | "title": "Genişletme Penceresi"
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/features/Migration/const.ts:
--------------------------------------------------------------------------------
1 | export const MIGRATE_KEY = 'migrated';
2 | export enum UpgradeStatus {
3 | START,
4 | UPGRADING,
5 | UPGRADED,
6 | UPGRADE_FAILED,
7 | }
8 |
9 | export const V1DB_NAME = 'LobeHub';
10 | export const V1DB_TABLE_NAME = 'LOBE_CHAT';
11 |
12 | export interface MigrationError {
13 | message: string;
14 | stack: string;
15 | }
16 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/layout.ts:
--------------------------------------------------------------------------------
1 | import ServerLayout from '@/components/server/ServerLayout';
2 |
3 | import Desktop from './_layout/Desktop';
4 | import Mobile from './_layout/Mobile';
5 | import { LayoutProps } from './_layout/type';
6 |
7 | const Layout = ServerLayout({ Desktop, Mobile });
8 |
9 | Layout.displayName = 'ChatLayout';
10 |
11 | export default Layout;
12 |
--------------------------------------------------------------------------------
/src/app/(main)/profile/_layout/Mobile/index.tsx:
--------------------------------------------------------------------------------
1 | import { PropsWithChildren } from 'react';
2 |
3 | import Header from './Header';
4 |
5 | const Layout = ({ children }: PropsWithChildren) => {
6 | return (
7 | <>
8 |
9 | {children}
10 | >
11 | );
12 | };
13 |
14 | Layout.displayName = 'ProfileMobileLayout';
15 |
16 | export default Layout;
17 |
--------------------------------------------------------------------------------
/src/app/(main)/welcome/_layout/Mobile.tsx:
--------------------------------------------------------------------------------
1 | import { PropsWithChildren } from 'react';
2 | import { Center } from 'react-layout-kit';
3 |
4 | const MobileLayout = ({ children }: PropsWithChildren) => {
5 | return (
6 |
7 | {children}
8 |
9 | );
10 | };
11 |
12 | export default MobileLayout;
13 |
--------------------------------------------------------------------------------
/docs/self-hosting/server-database/netlify.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Deploy LobeChat with Database on Netlify
3 | description: >-
4 | Learn how to deploy LobeChat on Netlify with ease, including: database,
5 | authentication and S3 storage service.
6 | tags:
7 | - Deploy LobeChat
8 | - Netlify Deployment
9 | ---
10 |
11 | # Deploy LobeChat with Database on Netlify
12 |
13 | TODO
14 |
15 |
--------------------------------------------------------------------------------
/docs/self-hosting/server-database/railway.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Deploy LobeChat with Database on Railway
3 | description: >-
4 | Learn how to deploy LobeChat on Railway with ease, including: database,
5 | authentication and S3 storage service.
6 | tags:
7 | - Deploy LobeChat
8 | - Railway Deployment
9 | ---
10 |
11 | # Deploy LobeChat with Database on Railway
12 |
13 | TODO
14 |
15 |
--------------------------------------------------------------------------------
/locales/en-US/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Artifacts",
3 | "actions": {
4 | "genAiMessage": "Generate Assistant Message",
5 | "summary": "Summary",
6 | "summaryTooltip": "Summarize current content"
7 | },
8 | "emptyArtifactList": "The current Artifacts list is empty. Please use plugins in the session as needed before viewing.",
9 | "title": "Portal View"
10 | }
11 |
--------------------------------------------------------------------------------
/locales/fr-FR/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "Auto-générer",
4 | "downloading": "Les liens d'image générés par DallE3 ne sont valides que pendant 1 heure. Le téléchargement de l'image est en cours...",
5 | "generate": "Générer",
6 | "generating": "En cours de génération...",
7 | "images": "Images :",
8 | "prompt": "Mot de rappel"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/features/AgentSetting/store/selectors.ts:
--------------------------------------------------------------------------------
1 | import { DEFAULT_AGENT_CHAT_CONFIG } from '@/const/settings';
2 | import { LobeAgentChatConfig } from '@/types/agent';
3 |
4 | import { Store } from './action';
5 |
6 | const chatConfig = (s: Store): LobeAgentChatConfig =>
7 | s.config.chatConfig || DEFAULT_AGENT_CHAT_CONFIG;
8 |
9 | export const selectors = {
10 | chatConfig,
11 | };
12 |
--------------------------------------------------------------------------------
/src/hooks/useActiveTabKey.ts:
--------------------------------------------------------------------------------
1 | import { usePathname } from 'next/navigation';
2 |
3 | import { SidebarTabKey } from '@/store/global/initialState';
4 |
5 | /**
6 | * Returns the active tab key (chat/market/settings/...)
7 | */
8 | export const useActiveTabKey = () => {
9 | const pathname = usePathname();
10 |
11 | return pathname.split('/').find(Boolean)! as SidebarTabKey;
12 | };
13 |
--------------------------------------------------------------------------------
/src/services/file/type.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable typescript-sort-keys/interface */
2 | import { FilePreview, UploadFileParams } from '@/types/files';
3 |
4 | export interface IFileService {
5 | createFile(file: UploadFileParams): Promise<{ id: string }>;
6 | removeFile(id: string): Promise;
7 | removeAllFiles(): Promise;
8 | getFile(id: string): Promise;
9 | }
10 |
--------------------------------------------------------------------------------
/locales/pl-PL/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "Automatyczne generowanie",
4 | "downloading": "Linki do obrazów wygenerowanych przez DallE3 są ważne tylko przez 1 godzinę. Trwa pobieranie obrazów do lokalnego bufora...",
5 | "generate": "Generuj",
6 | "generating": "Generowanie...",
7 | "images": "Obrazy:",
8 | "prompt": "słowo kluczowe"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/(main)/layout.tsx:
--------------------------------------------------------------------------------
1 | import ServerLayout from '@/components/server/ServerLayout';
2 |
3 | import Desktop from './_layout/Desktop';
4 | import Mobile from './_layout/Mobile';
5 | import { LayoutProps } from './_layout/type';
6 |
7 | const MainLayout = ServerLayout({ Desktop, Mobile });
8 |
9 | MainLayout.displayName = 'MainLayout';
10 |
11 | export default MainLayout;
12 |
--------------------------------------------------------------------------------
/src/features/Conversation/Extras/ExtraContainer.tsx:
--------------------------------------------------------------------------------
1 | import { Divider } from 'antd';
2 | import { PropsWithChildren, memo } from 'react';
3 |
4 | const ExtraContainer = memo(({ children }) => {
5 | return (
6 |
10 | );
11 | });
12 |
13 | export default ExtraContainer;
14 |
--------------------------------------------------------------------------------
/src/services/file/index.ts:
--------------------------------------------------------------------------------
1 | // import { getClientConfig } from '@/config/client';
2 | import { ClientService } from './client';
3 |
4 | // import { ServerService } from './server';
5 | //
6 | // const { ENABLED_SERVER_SERVICE } = getClientConfig();
7 | //
8 | // export const fileService = ENABLED_SERVER_SERVICE ? new ServerService() : new ClientService();
9 | export const fileService = new ClientService();
--------------------------------------------------------------------------------
/locales/ru-RU/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Артефакты",
3 | "actions": {
4 | "genAiMessage": "Создать сообщение помощника",
5 | "summary": "Сводка",
6 | "summaryTooltip": "Сводка текущего содержимого"
7 | },
8 | "emptyArtifactList": "Список текущих артефактов пуст. Пожалуйста, используйте плагины во время сеанса и затем просмотрите.",
9 | "title": "Расширенное окно"
10 | }
11 |
--------------------------------------------------------------------------------
/locales/vi-VN/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Tác Phẩm",
3 | "actions": {
4 | "genAiMessage": "Tạo tin nhắn trợ giúp",
5 | "summary": "Tóm tắt",
6 | "summaryTooltip": "Tóm tắt nội dung hiện tại"
7 | },
8 | "emptyArtifactList": "Danh sách Tác Phẩm hiện tại đang trống, vui lòng sử dụng các plugin trong cuộc trò chuyện trước khi xem lại",
9 | "title": "Cửa sổ mở rộng"
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/@category/default.tsx:
--------------------------------------------------------------------------------
1 | import UpgradeAlert from '../features/UpgradeAlert';
2 | import CategoryContent from './features/CategoryContent';
3 |
4 | const Category = () => {
5 | return (
6 | <>
7 |
8 |
9 | >
10 | );
11 | };
12 |
13 | Category.displayName = 'SettingCategory';
14 |
15 | export default Category;
16 |
--------------------------------------------------------------------------------
/src/hooks/useYamlArguments.ts:
--------------------------------------------------------------------------------
1 | import { parse } from 'partial-json';
2 | import { stringify } from 'yaml';
3 |
4 | export const useYamlArguments = (args?: string) => {
5 | if (!args) return '';
6 |
7 | try {
8 | const obj = parse(args);
9 |
10 | if (Object.keys(obj).length === 0) return '';
11 |
12 | return stringify(obj);
13 | } catch {
14 | return args;
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/src/utils/keyboard.ts:
--------------------------------------------------------------------------------
1 | import { KeyboardEvent } from 'react';
2 |
3 | import { isMacOS } from './platform';
4 |
5 | export const isCommandPressed = (event: KeyboardEvent) => {
6 | const isMac = isMacOS();
7 |
8 | if (isMac) {
9 | return event.metaKey; // Use metaKey (Command key) on macOS
10 | } else {
11 | return event.ctrlKey; // Use ctrlKey on Windows/Linux
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/locales/nl-NL/tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "dalle": {
3 | "autoGenerate": "Automatisch genereren",
4 | "downloading": "De link naar de afbeelding gegenereerd door DallE3 is slechts 1 uur geldig. De afbeelding wordt lokaal in de cache opgeslagen...",
5 | "generate": "Genereren",
6 | "generating": "Bezig met genereren...",
7 | "images": "Afbeeldingen:",
8 | "prompt": "prompt"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/(main)/market/layout.tsx:
--------------------------------------------------------------------------------
1 | import ServerLayout from '@/components/server/ServerLayout';
2 |
3 | import Desktop from './_layout/Desktop';
4 | import Mobile from './_layout/Mobile';
5 | import { LayoutProps } from './_layout/type';
6 |
7 | const MainLayout = ServerLayout({ Desktop, Mobile });
8 |
9 | MainLayout.displayName = 'MarketLayout';
10 |
11 | export default MainLayout;
12 |
--------------------------------------------------------------------------------
/src/features/PluginsUI/Render/useParseContent.ts:
--------------------------------------------------------------------------------
1 | import { useMemo } from 'react';
2 |
3 | export const useParseContent = (content: string) => {
4 | let isJSON = true;
5 |
6 | try {
7 | JSON.parse(content);
8 | } catch {
9 | isJSON = false;
10 | }
11 |
12 | const data = isJSON ? JSON.parse(content) : content;
13 |
14 | return useMemo(() => ({ data, isJSON }), [content]);
15 | };
16 |
--------------------------------------------------------------------------------
/src/store/session/slices/sessionGroup/selectors.ts:
--------------------------------------------------------------------------------
1 | import { SessionStore } from '@/store/session';
2 |
3 | const sessionGroupItems = (s: SessionStore) => s.sessionGroups;
4 |
5 | const getGroupById = (id: string) => (s: SessionStore) =>
6 | sessionGroupItems(s).find((group) => group.id === id);
7 |
8 | export const sessionGroupSelectors = {
9 | getGroupById,
10 | sessionGroupItems,
11 | };
12 |
--------------------------------------------------------------------------------
/locales/nl-NL/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Artifacts",
3 | "actions": {
4 | "genAiMessage": "Creëer assistentbericht",
5 | "summary": "Samenvatting",
6 | "summaryTooltip": "Samenvatting van de huidige inhoud"
7 | },
8 | "emptyArtifactList": "De huidige lijst met Artifacts is leeg. Gebruik plugins in de sessie en bekijk deze later opnieuw.",
9 | "title": "Uitbreidingsvenster"
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/(workspace)/layout.ts:
--------------------------------------------------------------------------------
1 | import ServerLayout from '@/components/server/ServerLayout';
2 |
3 | import Desktop from './_layout/Desktop';
4 | import Mobile from './_layout/Mobile';
5 | import { LayoutProps } from './_layout/type';
6 |
7 | const Layout = ServerLayout({ Desktop, Mobile });
8 |
9 | Layout.displayName = 'ChatConversationLayout';
10 |
11 | export default Layout;
12 |
--------------------------------------------------------------------------------
/src/components/Error/sentryCaptureException.ts:
--------------------------------------------------------------------------------
1 | import { appEnv } from '@/config/app';
2 |
3 | export type ErrorType = Error & { digest?: string };
4 |
5 | export const sentryCaptureException = async (error: Error & { digest?: string }) => {
6 | if (!appEnv.NEXT_PUBLIC_ENABLE_SENTRY) return;
7 | const { captureException } = await import('@sentry/nextjs');
8 | return captureException(error);
9 | };
10 |
--------------------------------------------------------------------------------
/src/features/MobileSwitchLoading/index.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { useTranslation } from 'react-i18next';
4 |
5 | import FullscreenLoading from '@/components/FullscreenLoading';
6 |
7 | const MobileSwitchLoading = () => {
8 | const { t } = useTranslation('common');
9 |
10 | return ;
11 | };
12 |
13 | export default MobileSwitchLoading;
14 |
--------------------------------------------------------------------------------
/src/store/tool/slices/builtin/initialState.ts:
--------------------------------------------------------------------------------
1 | import { builtinTools } from '@/tools';
2 | import { LobeBuiltinTool } from '@/types/tool';
3 |
4 | export interface BuiltinToolState {
5 | builtinToolLoading: Record;
6 | builtinTools: LobeBuiltinTool[];
7 | }
8 |
9 | export const initialBuiltinToolState: BuiltinToolState = {
10 | builtinToolLoading: {},
11 | builtinTools,
12 | };
13 |
--------------------------------------------------------------------------------
/src/types/user/settings/general.ts:
--------------------------------------------------------------------------------
1 | import type { NeutralColors, PrimaryColors } from '@lobehub/ui';
2 | import type { ThemeMode } from 'antd-style';
3 |
4 | import { LocaleMode } from '@/types/locale';
5 |
6 | export interface UserGeneralConfig {
7 | fontSize: number;
8 | language: LocaleMode;
9 | neutralColor?: NeutralColors;
10 | primaryColor?: PrimaryColors;
11 | themeMode: ThemeMode;
12 | }
13 |
--------------------------------------------------------------------------------
/src/utils/cookie.ts:
--------------------------------------------------------------------------------
1 | import dayjs from 'dayjs';
2 |
3 | import { COOKIE_CACHE_DAYS } from '@/const/settings';
4 |
5 | export const setCookie = (key: string, value: string | undefined) => {
6 | const expires = dayjs().add(COOKIE_CACHE_DAYS, 'day').toISOString();
7 |
8 | // eslint-disable-next-line unicorn/no-document-cookie
9 | document.cookie = `${key}=${value};expires=${expires};path=/;`;
10 | };
11 |
--------------------------------------------------------------------------------
/locales/pl-PL/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Artefakty",
3 | "actions": {
4 | "genAiMessage": "Tworzenie wiadomości AI",
5 | "summary": "Podsumowanie",
6 | "summaryTooltip": "Podsumowanie bieżącej zawartości"
7 | },
8 | "emptyArtifactList": "Obecna lista Artefaktów jest pusta. Proszę użyć wtyczek w trakcie sesji, a następnie sprawdzić ponownie.",
9 | "title": "Okno rozszerzenia"
10 | }
11 |
--------------------------------------------------------------------------------
/src/utils/uuid.ts:
--------------------------------------------------------------------------------
1 | // generate('1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 16); //=> "4f90d13a42"
2 | import { customAlphabet } from 'nanoid/non-secure';
3 |
4 | export const createNanoId = (size = 8) =>
5 | customAlphabet('1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', size);
6 |
7 | export const nanoid = createNanoId();
8 |
9 | export { v4 as uuid } from 'uuid';
10 |
--------------------------------------------------------------------------------
/locales/es-ES/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Artefactos",
3 | "actions": {
4 | "genAiMessage": "Crear mensaje de IA",
5 | "summary": "Resumen",
6 | "summaryTooltip": "Resumir el contenido actual"
7 | },
8 | "emptyArtifactList": "La lista de Artefactos actual está vacía. Por favor, utilice los complementos en la conversación y vuelva a intentarlo.",
9 | "title": "Ventana de expansión"
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/layout.ts:
--------------------------------------------------------------------------------
1 | import ServerLayout from '@/components/server/ServerLayout';
2 |
3 | import Desktop from './_layout/Desktop';
4 | import Mobile from './_layout/Mobile';
5 | import { LayoutProps } from './_layout/type';
6 |
7 | const SettingsLayout = ServerLayout({ Desktop, Mobile });
8 |
9 | SettingsLayout.displayName = 'SettingsLayout';
10 |
11 | export default SettingsLayout;
12 |
--------------------------------------------------------------------------------
/src/database/client/core/types/db.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod';
2 |
3 | export type DBModel = T & {
4 | createdAt: number;
5 | id: string;
6 | updatedAt: number;
7 | };
8 |
9 | export const DBBaseFieldsSchema = z.object({
10 | createdAt: z.number().or(z.string()),
11 | id: z.string(),
12 | updatedAt: z.number().or(z.string()),
13 | });
14 |
15 | export const LOBE_CHAT_LOCAL_DB_NAME = 'LOBE_CHAT_DB';
16 |
--------------------------------------------------------------------------------
/src/database/client/schemas/plugin.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable sort-keys-fix/sort-keys-fix */
2 | import { z } from 'zod';
3 |
4 | export const DB_PluginSchema = z.object({
5 | identifier: z.string(),
6 | id: z.string(),
7 | type: z.enum(['plugin', 'customPlugin']),
8 | manifest: z.any().optional(),
9 | settings: z.any().optional(),
10 | });
11 |
12 | export type DB_Plugin = z.infer;
13 |
--------------------------------------------------------------------------------
/src/hooks/useGreeting/greetingTime.ts:
--------------------------------------------------------------------------------
1 | export const parseGreetingTime = () => {
2 | const now = new Date();
3 | const hours = now.getHours();
4 |
5 | if (hours >= 4 && hours < 11) {
6 | return 'morning';
7 | } else if (hours >= 11 && hours < 14) {
8 | return 'noon';
9 | } else if (hours >= 14 && hours < 18) {
10 | return 'afternoon';
11 | } else {
12 | return 'night';
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/ai360/index.ts:
--------------------------------------------------------------------------------
1 | import { ModelProvider } from '../types';
2 | import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
3 |
4 | export const LobeAi360AI = LobeOpenAICompatibleFactory({
5 | baseURL: 'https://ai.360.cn/v1',
6 | debug: {
7 | chatCompletion: () => process.env.DEBUG_AI360_CHAT_COMPLETION === '1',
8 | },
9 | provider: ModelProvider.Ai360,
10 | });
11 |
--------------------------------------------------------------------------------
/locales/bg-BG/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Артефакти",
3 | "actions": {
4 | "genAiMessage": "Създаване на съобщение на помощника",
5 | "summary": "Обобщение",
6 | "summaryTooltip": "Обобщение на текущото съдържание"
7 | },
8 | "emptyArtifactList": "Списъкът с текущите артефакти е празен. Моля, използвайте добавки в разговора и след това проверете отново.",
9 | "title": "Разширено прозорец"
10 | }
11 |
--------------------------------------------------------------------------------
/locales/pt-BR/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Artefatos",
3 | "actions": {
4 | "genAiMessage": "Gerar mensagem de IA",
5 | "summary": "Resumo",
6 | "summaryTooltip": "Resumir o conteúdo atual"
7 | },
8 | "emptyArtifactList": "A lista de Artefatos atual está vazia. Por favor, use os plugins conforme necessário durante a sessão e depois verifique novamente.",
9 | "title": "Janela de Expansão"
10 | }
11 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "automerge": false,
4 | "dependencyDashboard": true,
5 | "ignoreDeps": [],
6 | "labels": ["dependencies"],
7 | "postUpdateOptions": ["yarnDedupeHighest"],
8 | "prConcurrentLimit": 30,
9 | "prHourlyLimit": 0,
10 | "rebaseWhen": "conflicted",
11 | "schedule": "on sunday before 6:00am",
12 | "timezone": "UTC"
13 | }
14 |
--------------------------------------------------------------------------------
/src/app/(main)/(mobile)/me/(home)/features/Category.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { memo } from 'react';
4 |
5 | import Cell from '@/components/Cell';
6 |
7 | import { useCategory } from './useCategory';
8 |
9 | const Category = memo(() => {
10 | const items = useCategory();
11 |
12 | return items?.map((item, index) => | );
13 | });
14 |
15 | export default Category;
16 |
--------------------------------------------------------------------------------
/src/app/(main)/(mobile)/me/settings/features/Category.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { memo } from 'react';
4 |
5 | import Cell from '@/components/Cell';
6 |
7 | import { useCategory } from './useCategory';
8 |
9 | const Category = memo(() => {
10 | const items = useCategory();
11 |
12 | return items?.map((item, index) => | );
13 | });
14 |
15 | export default Category;
16 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/(workspace)/_layout/useInitAgentConfig.ts:
--------------------------------------------------------------------------------
1 | import { useAgentStore } from '@/store/agent';
2 | import { useSessionStore } from '@/store/session';
3 |
4 | export const useInitAgentConfig = () => {
5 | const [useFetchAgentConfig] = useAgentStore((s) => [s.useFetchAgentConfig]);
6 |
7 | const [sessionId] = useSessionStore((s) => [s.activeId]);
8 |
9 | return useFetchAgentConfig(sessionId);
10 | };
11 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/openai/index.ts:
--------------------------------------------------------------------------------
1 | import { ModelProvider } from '../types';
2 | import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
3 |
4 | export const LobeOpenAI = LobeOpenAICompatibleFactory({
5 | baseURL: 'https://api.openai.com/v1',
6 | debug: {
7 | chatCompletion: () => process.env.DEBUG_OPENAI_CHAT_COMPLETION === '1',
8 | },
9 | provider: ModelProvider.OpenAI,
10 | });
11 |
--------------------------------------------------------------------------------
/src/types/tool/dalle.ts:
--------------------------------------------------------------------------------
1 | export type DallEImageQuality = 'standard' | 'hd';
2 | export type DallEImageStyle = 'vivid' | 'natural';
3 | export type DallEImageSize = '1792x1024' | '1024x1024' | '1024x1792';
4 |
5 | export interface DallEImageItem {
6 | imageId?: string;
7 | previewUrl?: string;
8 | prompt: string;
9 | quality: DallEImageQuality;
10 | size: DallEImageSize;
11 | style: DallEImageStyle;
12 | }
13 |
--------------------------------------------------------------------------------
/.github/workflows/wiki-sync.yml:
--------------------------------------------------------------------------------
1 | name: Wiki Sync
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | paths:
7 | - 'contributing/**'
8 | branches:
9 | - main
10 |
11 | jobs:
12 | update-wiki:
13 | runs-on: ubuntu-latest
14 | name: Wiki sync
15 | steps:
16 | - uses: OrlovM/Wiki-Action@v1
17 | with:
18 | path: 'contributing'
19 | token: ${{ secrets.GH_TOKEN }}
20 |
--------------------------------------------------------------------------------
/locales/fr-FR/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Artifacts",
3 | "actions": {
4 | "genAiMessage": "Créer un message d'assistant",
5 | "summary": "Résumé",
6 | "summaryTooltip": "Résumé du contenu actuel"
7 | },
8 | "emptyArtifactList": "La liste des Artifacts est actuellement vide. Veuillez utiliser les plugins dans la conversation avant de consulter à nouveau.",
9 | "title": "Fenêtre d'extension"
10 | }
11 |
--------------------------------------------------------------------------------
/src/store/chat/slices/builtinTool/selectors.ts:
--------------------------------------------------------------------------------
1 | import { ChatStoreState } from '@/store/chat';
2 |
3 | const isDallEImageGenerating = (id: string) => (s: ChatStoreState) => s.dalleImageLoading[id];
4 |
5 | const isGeneratingDallEImage = (s: ChatStoreState) =>
6 | Object.values(s.dalleImageLoading).some(Boolean);
7 |
8 | export const chatToolSelectors = {
9 | isDallEImageGenerating,
10 | isGeneratingDallEImage,
11 | };
12 |
--------------------------------------------------------------------------------
/src/store/session/initialState.ts:
--------------------------------------------------------------------------------
1 | import { SessionState, initialSessionState } from './slices/session/initialState';
2 | import { SessionGroupState, initSessionGroupState } from './slices/sessionGroup/initialState';
3 |
4 | export interface SessionStoreState extends SessionGroupState, SessionState {}
5 |
6 | export const initialState: SessionStoreState = {
7 | ...initSessionGroupState,
8 | ...initialSessionState,
9 | };
10 |
--------------------------------------------------------------------------------
/src/store/user/slices/sync/initialState.ts:
--------------------------------------------------------------------------------
1 | import { PeerSyncStatus, SyncAwarenessState } from '@/types/sync';
2 |
3 | export interface UserSyncState {
4 | syncAwareness: SyncAwarenessState[];
5 | syncEnabled: boolean;
6 | syncStatus: PeerSyncStatus;
7 | }
8 |
9 | export const initialSyncState: UserSyncState = {
10 | syncAwareness: [],
11 | syncEnabled: false,
12 | syncStatus: PeerSyncStatus.Disabled,
13 | };
14 |
--------------------------------------------------------------------------------
/locales/it-IT/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Artefatti",
3 | "actions": {
4 | "genAiMessage": "Genera messaggio AI",
5 | "summary": "Sommario",
6 | "summaryTooltip": "Sommario del contenuto attuale"
7 | },
8 | "emptyArtifactList": "La lista degli Artefatti attuale è vuota, si prega di utilizzare i plugin necessari durante la sessione e poi controllare di nuovo",
9 | "title": "Finestra di espansione"
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/system-agent/index.tsx:
--------------------------------------------------------------------------------
1 | import SystemAgentForm from './features/createForm';
2 |
3 | const Page = () => {
4 | return (
5 | <>
6 |
7 |
8 |
9 | >
10 | );
11 | };
12 |
13 | Page.displayName = 'SystemAgent';
14 |
15 | export default Page;
16 |
--------------------------------------------------------------------------------
/src/const/locale.ts:
--------------------------------------------------------------------------------
1 | import { normalizeLocale, supportLocales } from '@/locales/resources';
2 |
3 | export const DEFAULT_LANG = 'en-US';
4 | export const LOBE_LOCALE_COOKIE = 'LOBE_LOCALE';
5 |
6 | /**
7 | * Check if the language is supported
8 | * @param locale
9 | */
10 | export const isLocaleNotSupport = (locale: string) => {
11 | return normalizeLocale(locale) === DEFAULT_LANG || !supportLocales.includes(locale);
12 | };
13 |
--------------------------------------------------------------------------------
/src/features/DataImporter/style.ts:
--------------------------------------------------------------------------------
1 | import { createStyles } from 'antd-style';
2 |
3 | export const useStyles = createStyles(({ css }) => {
4 | return {
5 | children: css`
6 | &::before {
7 | content: '';
8 | position: absolute;
9 | inset: 0;
10 | background-color: transparent;
11 | }
12 | `,
13 | wrapper: css`
14 | font-size: inherit;
15 | `,
16 | };
17 | });
18 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/stepfun/index.ts:
--------------------------------------------------------------------------------
1 | import { ModelProvider } from '../types';
2 | import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
3 |
4 | export const LobeStepfunAI = LobeOpenAICompatibleFactory({
5 | baseURL: 'https://api.stepfun.com/v1',
6 | debug: {
7 | chatCompletion: () => process.env.DEBUG_STEPFUN_CHAT_COMPLETION === '1',
8 | },
9 | provider: ModelProvider.Stepfun,
10 | });
11 |
--------------------------------------------------------------------------------
/src/store/session/slices/sessionGroup/initialState.ts:
--------------------------------------------------------------------------------
1 | import { CustomSessionGroup, LobeSessionGroups } from '@/types/session';
2 |
3 | export interface SessionGroupState {
4 | activeGroupId?: string;
5 | customSessionGroups: CustomSessionGroup[];
6 | sessionGroups: LobeSessionGroups;
7 | }
8 |
9 | export const initSessionGroupState: SessionGroupState = {
10 | customSessionGroups: [],
11 | sessionGroups: [],
12 | };
13 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/deepseek/index.ts:
--------------------------------------------------------------------------------
1 | import { ModelProvider } from '../types';
2 | import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
3 |
4 | export const LobeDeepSeekAI = LobeOpenAICompatibleFactory({
5 | baseURL: 'https://api.deepseek.com/v1',
6 | debug: {
7 | chatCompletion: () => process.env.DEBUG_DEEPSEEK_CHAT_COMPLETION === '1',
8 | },
9 | provider: ModelProvider.DeepSeek,
10 | });
11 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/moonshot/index.ts:
--------------------------------------------------------------------------------
1 | import { ModelProvider } from '../types';
2 | import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
3 |
4 | export const LobeMoonshotAI = LobeOpenAICompatibleFactory({
5 | baseURL: 'https://api.moonshot.cn/v1',
6 | debug: {
7 | chatCompletion: () => process.env.DEBUG_MOONSHOT_CHAT_COMPLETION === '1',
8 | },
9 | provider: ModelProvider.Moonshot,
10 | });
11 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/taichu/index.ts:
--------------------------------------------------------------------------------
1 | import { ModelProvider } from '../types';
2 | import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
3 |
4 | export const LobeTaichuAI = LobeOpenAICompatibleFactory({
5 | baseURL: 'https://ai-maas.wair.ac.cn/maas/v1',
6 | debug: {
7 | chatCompletion: () => process.env.DEBUG_TAICHU_CHAT_COMPLETION === '1',
8 | },
9 | provider: ModelProvider.Taichu,
10 | });
11 |
--------------------------------------------------------------------------------
/locales/de-DE/portal.json:
--------------------------------------------------------------------------------
1 | {
2 | "Artifacts": "Artefakte",
3 | "actions": {
4 | "genAiMessage": "Assistenten-Nachricht erstellen",
5 | "summary": "Zusammenfassung",
6 | "summaryTooltip": "Zusammenfassung des aktuellen Inhalts"
7 | },
8 | "emptyArtifactList": "Die Liste der Artefakte ist derzeit leer. Bitte verwenden Sie Plugins in der Sitzung und überprüfen Sie sie erneut.",
9 | "title": "Erweiterungsfenster"
10 | }
11 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/zeroone/index.ts:
--------------------------------------------------------------------------------
1 | import { ModelProvider } from '../types';
2 | import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
3 |
4 | export const LobeZeroOneAI = LobeOpenAICompatibleFactory({
5 | baseURL: 'https://api.lingyiwanwu.com/v1',
6 | debug: {
7 | chatCompletion: () => process.env.DEBUG_ZEROONE_CHAT_COMPLETION === '1',
8 | },
9 |
10 | provider: ModelProvider.ZeroOne,
11 | });
12 |
--------------------------------------------------------------------------------
/src/store/user/slices/preference/initialState.ts:
--------------------------------------------------------------------------------
1 | import { DEFAULT_PREFERENCE } from '@/const/user';
2 | import { UserPreference } from '@/types/user';
3 |
4 | export interface UserPreferenceState {
5 | /**
6 | * the user preference, which only store in local storage
7 | */
8 | preference: UserPreference;
9 | }
10 |
11 | export const initialPreferenceState: UserPreferenceState = {
12 | preference: DEFAULT_PREFERENCE,
13 | };
14 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/tts/page.tsx:
--------------------------------------------------------------------------------
1 | import { metadataModule } from '@/server/metadata';
2 | import { translation } from '@/server/translation';
3 |
4 | export const generateMetadata = async () => {
5 | const { t } = await translation('setting');
6 | return metadataModule.generate({
7 | description: t('header.desc'),
8 | title: t('tab.tts'),
9 | url: '/settings/tts',
10 | });
11 | };
12 | export { default } from './index';
13 |
--------------------------------------------------------------------------------
/src/app/(main)/(mobile)/me/data/layout.tsx:
--------------------------------------------------------------------------------
1 | import { PropsWithChildren } from 'react';
2 |
3 | import MobileContentLayout from '@/components/server/MobileNavLayout';
4 |
5 | import Header from './features/Header';
6 |
7 | const Layout = ({ children }: PropsWithChildren) => {
8 | return }>{children};
9 | };
10 |
11 | Layout.displayName = 'MeDataLayout';
12 |
13 | export default Layout;
14 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/LocalFiles.tsx:
--------------------------------------------------------------------------------
1 | import { memo } from 'react';
2 |
3 | import EditableFileList from '@/components/FileList/EditableFileList';
4 | import { useFileStore } from '@/store/file';
5 |
6 | export const LocalFiles = memo(() => {
7 | const inputFilesList = useFileStore((s) => s.inputFilesList);
8 |
9 | return ;
10 | });
11 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/agent/page.tsx:
--------------------------------------------------------------------------------
1 | import { metadataModule } from '@/server/metadata';
2 | import { translation } from '@/server/translation';
3 |
4 | export const generateMetadata = async () => {
5 | const { t } = await translation('setting');
6 | return metadataModule.generate({
7 | description: t('header.desc'),
8 | title: t('tab.agent'),
9 | url: '/settings/agent',
10 | });
11 | };
12 | export { default } from './index';
13 |
--------------------------------------------------------------------------------
/src/libs/agent-runtime/siliconcloud/index.ts:
--------------------------------------------------------------------------------
1 | import { ModelProvider } from '../types';
2 | import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
3 |
4 | export const LobeSiliconCloudAI = LobeOpenAICompatibleFactory({
5 | baseURL: 'https://api.siliconflow.cn/v1',
6 | debug: {
7 | chatCompletion: () => process.env.DEBUG_SILICONCLOUD_CHAT_COMPLETION === '1',
8 | },
9 | provider: ModelProvider.SiliconCloud,
10 | });
11 |
--------------------------------------------------------------------------------
/docs/usage/tools-calling/moonshot.zh-CN.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Moonshot 系列 Tools Calling 评测
3 | description: 使用 LobeChat 测试 Moonshot 系列模型(Moonshot-1) 的工具调用(Function Calling)能力,并展现评测结果
4 | tags:
5 | - Tools Calling
6 | - Benchmark
7 | - Function Calling
8 | - 工具调用
9 | - 插件
10 | ---
11 |
12 | # Moonshot 系列工具调用(Tools Calling)
13 |
14 | ### 简单调用指令:天气查询
15 |
16 | 测试指令:指令 ①
17 |
18 | TODO
19 |
20 | ### 复杂调用指令:文生图
21 |
22 | 测试指令:指令 ②
23 |
24 | TODO
25 |
--------------------------------------------------------------------------------
/src/chains/translate.ts:
--------------------------------------------------------------------------------
1 | import { ChatStreamPayload } from '@/types/openai/chat';
2 |
3 | export const chainTranslate = (
4 | content: string,
5 | targetLang: string,
6 | ): Partial => ({
7 | messages: [
8 | {
9 | content: '你是一名擅长翻译的助理,你需要将输入的语言翻译为目标语言',
10 | role: 'system',
11 | },
12 | {
13 | content: `请将以下内容 ${content},翻译为 ${targetLang} `,
14 | role: 'user',
15 | },
16 | ],
17 | });
18 |
--------------------------------------------------------------------------------
/src/components/Analytics/Umami.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import Script from 'next/script';
4 | import { memo } from 'react';
5 |
6 | interface UmamiAnalyticsProps {
7 | scriptUrl: string;
8 | websiteId?: string;
9 | }
10 |
11 | const UmamiAnalytics = memo(
12 | ({ scriptUrl, websiteId }) =>
13 | websiteId && ,
14 | );
15 |
16 | export default UmamiAnalytics;
17 |
--------------------------------------------------------------------------------
/src/libs/next-auth/sso-providers/sso.config.ts:
--------------------------------------------------------------------------------
1 | import { OAuth2Config } from '@auth/core/providers';
2 | import type { Profile } from 'next-auth';
3 |
4 | export const CommonProviderConfig = {
5 | // Auth.js does not allow email account linking by default cause it's dangerous
6 | // ref: https://authjs.dev/reference/core/providers#allowdangerousemailaccountlinking
7 | allowDangerousEmailAccountLinking: true,
8 | } satisfies Partial>;
9 |
--------------------------------------------------------------------------------
/docs/self-hosting/server-database/repocloud.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Deploy LobeChat with Database on RepoCloud
3 | description: >-
4 | Learn how to deploy LobeChat on RepoCloud with ease, including: database,
5 | authentication and S3 storage service.
6 | tags:
7 | - Deploy LobeChat
8 | - RepoCloud Deployment
9 | - OpenAI API Key
10 | - Custom Domain Binding
11 | ---
12 |
13 | # Deploying LobeChat Database Edition with RepoCloud
14 |
15 | TODO
16 |
17 |
--------------------------------------------------------------------------------
/src/app/(main)/(mobile)/me/settings/layout.tsx:
--------------------------------------------------------------------------------
1 | import { PropsWithChildren } from 'react';
2 |
3 | import MobileContentLayout from '@/components/server/MobileNavLayout';
4 |
5 | import Header from './features/Header';
6 |
7 | const Layout = ({ children }: PropsWithChildren) => {
8 | return }>{children};
9 | };
10 |
11 | Layout.displayName = 'MeSettingsLayout';
12 |
13 | export default Layout;
14 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/common/page.tsx:
--------------------------------------------------------------------------------
1 | import { metadataModule } from '@/server/metadata';
2 | import { translation } from '@/server/translation';
3 |
4 | export const generateMetadata = async () => {
5 | const { t } = await translation('setting');
6 | return metadataModule.generate({
7 | description: t('header.desc'),
8 | title: t('tab.common'),
9 | url: '/settings/common',
10 | });
11 | };
12 |
13 | export { default } from './index';
14 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # Eslintignore for LobeHub
2 | ################################################################
3 |
4 | # dependencies
5 | node_modules
6 |
7 | # ci
8 | coverage
9 | .coverage
10 |
11 | # test
12 | jest*
13 | *.test.ts
14 | *.test.tsx
15 |
16 | # umi
17 | .umi
18 | .umi-production
19 | .umi-test
20 | .dumi/tmp*
21 | !.dumirc.ts
22 |
23 | # production
24 | dist
25 | es
26 | lib
27 | logs
28 |
29 | # misc
30 | # add other ignore file below
31 | .next
--------------------------------------------------------------------------------
/src/store/user/slices/common/initialState.ts:
--------------------------------------------------------------------------------
1 | export interface CommonState {
2 | isOnboard: boolean;
3 | isShowPWAGuide: boolean;
4 | isUserCanEnableTrace: boolean;
5 | isUserHasConversation: boolean;
6 | isUserStateInit: boolean;
7 | }
8 |
9 | export const initialCommonState: CommonState = {
10 | isOnboard: false,
11 | isShowPWAGuide: false,
12 | isUserCanEnableTrace: false,
13 | isUserHasConversation: false,
14 | isUserStateInit: false,
15 | };
16 |
--------------------------------------------------------------------------------
/src/app/(main)/market/@detail/features/Comment.tsx:
--------------------------------------------------------------------------------
1 | import { Giscus } from '@lobehub/ui';
2 | import { memo } from 'react';
3 |
4 | const Comment = memo<{ identifier: string }>(({ identifier }) => (
5 |
14 | ));
15 |
16 | export default Comment;
17 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/system-agent/page.tsx:
--------------------------------------------------------------------------------
1 | import { metadataModule } from '@/server/metadata';
2 | import { translation } from '@/server/translation';
3 |
4 | export const generateMetadata = async () => {
5 | const { t } = await translation('setting');
6 |
7 | return metadataModule.generate({
8 | description: t('header.desc'),
9 | title: t('tab.system-agent'),
10 | url: '/settings/system-agent',
11 | });
12 | };
13 |
14 | export { default } from './index';
15 |
--------------------------------------------------------------------------------
/src/const/market.ts:
--------------------------------------------------------------------------------
1 | import { DEFAULT_AGENT_CONFIG } from '@/const/settings';
2 | import { AgentsMarketItem } from '@/types/market';
3 |
4 | import { DEFAULT_AGENT_META } from './meta';
5 |
6 | export const DEFAULT_AGENTS_MARKET_ITEM: AgentsMarketItem = {
7 | author: '',
8 | config: DEFAULT_AGENT_CONFIG,
9 | createAt: Date.now().toString(),
10 | homepage: '',
11 | identifier: '',
12 | manifest: '',
13 | meta: DEFAULT_AGENT_META,
14 | schemaVersion: 1,
15 | };
16 |
--------------------------------------------------------------------------------
/src/features/AgentSetting/AgentSettingsStore.tsx:
--------------------------------------------------------------------------------
1 | import { memo } from 'react';
2 |
3 | import StoreUpdater, { StoreUpdaterProps } from './StoreUpdater';
4 | import { Provider, createStore } from './store';
5 |
6 | type AgentSettingsProps = StoreUpdaterProps;
7 |
8 | export const AgentSettingsStore = memo((props) => {
9 | return (
10 |
11 |
12 |
13 | );
14 | });
15 |
--------------------------------------------------------------------------------
/src/server/routers/edge/config/index.ts:
--------------------------------------------------------------------------------
1 | import { publicProcedure, router } from '@/libs/trpc';
2 | import { getServerDefaultAgentConfig, getServerGlobalConfig } from '@/server/globalConfig';
3 |
4 | export const configRouter = router({
5 | getDefaultAgentConfig: publicProcedure.query(async () => {
6 | return getServerDefaultAgentConfig();
7 | }),
8 |
9 | getGlobalConfig: publicProcedure.query(async () => {
10 | return getServerGlobalConfig();
11 | }),
12 | });
13 |
--------------------------------------------------------------------------------
/src/components/Analytics/Plausible.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import Script from 'next/script';
4 | import { memo } from 'react';
5 |
6 | interface PlausibleAnalyticsProps {
7 | domain?: string;
8 | scriptBaseUrl: string;
9 | }
10 |
11 | const PlausibleAnalytics = memo(
12 | ({ domain, scriptBaseUrl }) =>
13 | domain && ,
14 | );
15 |
16 | export default PlausibleAnalytics;
17 |
--------------------------------------------------------------------------------
/src/tools/renders.ts:
--------------------------------------------------------------------------------
1 | import { BuiltinRender } from '@/types/tool';
2 |
3 | import { DalleManifest } from './dalle';
4 | import DalleRender from './dalle/Render';
5 |
6 | export const BuiltinToolsRenders: Record = {
7 | [DalleManifest.identifier]: DalleRender as BuiltinRender,
8 | /**
9 | * 兼容旧版本 dalle3 的 identifier
10 | * TODO: 后续数据库版本迁移时记得迁移 dalle3 对应的 identifier
11 | * @deprecated
12 | */
13 | dalle3: DalleRender as BuiltinRender,
14 | };
15 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/@session/_layout/Desktop/index.tsx:
--------------------------------------------------------------------------------
1 | import { PropsWithChildren } from 'react';
2 |
3 | import PanelBody from './PanelBody';
4 | import Header from './SessionHeader';
5 |
6 | const DesktopLayout = ({ children }: PropsWithChildren) => {
7 | return (
8 | <>
9 |
10 | {children}
11 | {/* ↓ cloud slot ↓ */}
12 |
13 | {/* ↑ cloud slot ↑ */}
14 | >
15 | );
16 | };
17 |
18 | export default DesktopLayout;
19 |
--------------------------------------------------------------------------------
/src/features/AgentSetting/useSyncAgemtSettings.ts:
--------------------------------------------------------------------------------
1 | import { FormInstance } from 'antd/es/form/hooks/useForm';
2 | import isEqual from 'fast-deep-equal';
3 | import { useLayoutEffect } from 'react';
4 |
5 | import { useStore } from './store';
6 |
7 | export const useAgentSyncSettings = (form: FormInstance) => {
8 | const config = useStore((s) => s.config, isEqual);
9 | useLayoutEffect(() => {
10 | form.setFieldsValue(config);
11 | }, [config]);
12 |
13 | return config;
14 | };
15 |
--------------------------------------------------------------------------------
/src/layout/AuthProvider/NoAuth/index.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { PropsWithChildren, memo } from 'react';
4 | import { createStoreUpdater } from 'zustand-utils';
5 |
6 | import { useUserStore } from '@/store/user';
7 |
8 | const NoAuthProvider = memo(({ children }) => {
9 | const useStoreUpdater = createStoreUpdater(useUserStore);
10 |
11 | useStoreUpdater('isLoaded', true);
12 |
13 | return children;
14 | });
15 |
16 | export default NoAuthProvider;
17 |
--------------------------------------------------------------------------------
/src/server/routers/edge/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file contains the root router of Lobe Chat tRPC-backend
3 | */
4 | import { publicProcedure, router } from '@/libs/trpc';
5 |
6 | import { configRouter } from './config';
7 | import { uploadRouter } from './upload';
8 |
9 | export const edgeRouter = router({
10 | config: configRouter,
11 | healthcheck: publicProcedure.query(() => "i'm live!"),
12 | upload: uploadRouter,
13 | });
14 |
15 | export type EdgeRouter = typeof edgeRouter;
16 |
--------------------------------------------------------------------------------
/src/app/(main)/(mobile)/me/(home)/layout.tsx:
--------------------------------------------------------------------------------
1 | import { PropsWithChildren } from 'react';
2 |
3 | import MobileContentLayout from '@/components/server/MobileNavLayout';
4 |
5 | import Header from './features/Header';
6 |
7 | const Layout = ({ children }: PropsWithChildren) => {
8 | return (
9 | } withNav>
10 | {children}
11 |
12 | );
13 | };
14 |
15 | Layout.displayName = 'MeLayout';
16 |
17 | export default Layout;
18 |
--------------------------------------------------------------------------------
/src/libs/trpc/middleware/userAuth.ts:
--------------------------------------------------------------------------------
1 | import { TRPCError } from '@trpc/server';
2 |
3 | import { trpc } from '../init';
4 |
5 | export const userAuth = trpc.middleware(async (opts) => {
6 | const { ctx } = opts;
7 | // `ctx.user` is nullable
8 | if (!ctx.userId) {
9 | throw new TRPCError({ code: 'UNAUTHORIZED' });
10 | }
11 |
12 | return opts.next({
13 | ctx: {
14 | // ✅ user value is known to be non-null now
15 | userId: ctx.userId,
16 | },
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/src/features/Conversation/Error/InvalidAPIKey.tsx:
--------------------------------------------------------------------------------
1 | import { memo } from 'react';
2 |
3 | import APIKeyForm from './APIKeyForm';
4 | import { ErrorActionContainer } from './style';
5 |
6 | interface InvalidAPIKeyProps {
7 | id: string;
8 | provider?: string;
9 | }
10 | const InvalidAPIKey = memo(({ id, provider }) => (
11 |
12 |
13 |
14 | ));
15 |
16 | export default InvalidAPIKey;
17 |
--------------------------------------------------------------------------------
/src/services/user/type.ts:
--------------------------------------------------------------------------------
1 | import { DeepPartial } from 'utility-types';
2 |
3 | import { UserInitializationState, UserPreference } from '@/types/user';
4 | import { UserSettings } from '@/types/user/settings';
5 |
6 | export interface IUserService {
7 | getUserState: () => Promise;
8 | resetUserSettings: () => Promise;
9 | updatePreference: (preference: UserPreference) => Promise;
10 | updateUserSettings: (patch: DeepPartial) => Promise;
11 | }
12 |
--------------------------------------------------------------------------------
/src/layout/AuthProvider/NextAuth/index.tsx:
--------------------------------------------------------------------------------
1 | import { SessionProvider } from 'next-auth/react';
2 | import { PropsWithChildren } from 'react';
3 |
4 | import { API_ENDPOINTS } from '@/services/_url';
5 |
6 | import UserUpdater from './UserUpdater';
7 |
8 | const NextAuth = ({ children }: PropsWithChildren) => {
9 | return (
10 |
11 | {children}
12 |
13 |
14 | );
15 | };
16 |
17 | export default NextAuth;
18 |
--------------------------------------------------------------------------------
/src/store/tool/slices/plugin/initialState.ts:
--------------------------------------------------------------------------------
1 | import { LobeTool } from '@/types/tool';
2 |
3 | export type PluginsSettings = Record;
4 |
5 | export interface PluginState {
6 | installedPlugins: LobeTool[];
7 | loadingInstallPlugins: boolean;
8 | pluginsSettings: PluginsSettings;
9 | updatePluginSettingsSignal?: AbortController;
10 | }
11 |
12 | export const initialPluginState: PluginState = {
13 | installedPlugins: [],
14 | loadingInstallPlugins: true,
15 | pluginsSettings: {},
16 | };
17 |
--------------------------------------------------------------------------------
/src/app/(main)/settings/sync/index.tsx:
--------------------------------------------------------------------------------
1 | import Alert from './features/Alert';
2 | import DeviceInfo from './features/DeviceInfo';
3 | import WebRTC from './features/WebRTC';
4 |
5 | const Page = ({ browser, os, mobile }: { browser?: string; mobile?: boolean; os?: string }) => {
6 | return (
7 | <>
8 |
9 |
10 |
11 | >
12 | );
13 | };
14 |
15 | Page.displayName = 'SyncSetting';
16 |
17 | export default Page;
18 |
--------------------------------------------------------------------------------
/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import { Metadata } from 'next';
2 |
3 | import { getCanonicalUrl } from '@/const/url';
4 |
5 | import Client from './(loading)/Client';
6 | import Redirect from './(loading)/Redirect';
7 |
8 | export const metadata: Metadata = {
9 | alternates: { canonical: getCanonicalUrl('/') },
10 | };
11 |
12 | const Page = () => {
13 | return (
14 | <>
15 |
16 |
17 | >
18 | );
19 | };
20 |
21 | Page.displayName = 'Loading';
22 |
23 | export default Page;
24 |
--------------------------------------------------------------------------------
/src/components/Analytics/Posthog.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import posthog from 'posthog-js';
4 | import { memo, useEffect } from 'react';
5 |
6 | interface PostHogProps {
7 | debug: boolean;
8 | host: string;
9 | token?: string;
10 | }
11 |
12 | const PostHog = memo(({ token, host, debug }) => {
13 | useEffect(() => {
14 | if (!token) return;
15 |
16 | posthog.init(token, { api_host: host, debug });
17 | }, []);
18 |
19 | return null;
20 | });
21 |
22 | export default PostHog;
23 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | #### 💻 变更类型 | Change Type
2 |
3 |
4 |
5 | - [ ] ✨ feat
6 | - [ ] 🐛 fix
7 | - [ ] ♻️ refactor
8 | - [ ] 💄 style
9 | - [ ] 👷 build
10 | - [ ] ⚡️ perf
11 | - [ ] 📝 docs
12 | - [ ] 🔨 chore
13 |
14 | #### 🔀 变更说明 | Description of Change
15 |
16 |
17 |
18 | #### 📝 补充信息 | Additional Information
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/(workspace)/@portal/_layout/Desktop.tsx:
--------------------------------------------------------------------------------
1 | import { PropsWithChildren } from 'react';
2 | import { Flexbox } from 'react-layout-kit';
3 |
4 | import Header from '../features/Header';
5 |
6 | const Layout = ({ children }: PropsWithChildren) => {
7 | return (
8 | <>
9 |
10 |
11 | {children}
12 |
13 | >
14 | );
15 | };
16 |
17 | export default Layout;
18 |
--------------------------------------------------------------------------------
/src/app/(main)/chat/(workspace)/@topic/_layout/Desktop.tsx:
--------------------------------------------------------------------------------
1 | import { PropsWithChildren } from 'react';
2 | import { Flexbox } from 'react-layout-kit';
3 |
4 | import Header from '../features/Header';
5 |
6 | const Layout = ({ children }: PropsWithChildren) => {
7 | return (
8 | <>
9 |
10 |
11 | {children}
12 |
13 | >
14 | );
15 | };
16 |
17 | export default Layout;
18 |
--------------------------------------------------------------------------------
/src/features/AgentSetting/AgentModal/ModelSelect.tsx:
--------------------------------------------------------------------------------
1 | import { memo } from 'react';
2 |
3 | import Select from '@/features/ModelSelect';
4 |
5 | import { useStore } from '../store';
6 |
7 | const ModelSelect = memo(() => {
8 | const [model, updateConfig] = useStore((s) => [s.config.model, s.setAgentConfig]);
9 |
10 | return (
11 |