feat: support coze bot & update comments & fix some ui bug.

This commit is contained in:
quemingyi.wudong 2025-04-16 20:47:16 +08:00
parent dc4124e362
commit f028bea0c5
11 changed files with 307 additions and 114 deletions

View File

@ -41,7 +41,7 @@
}
],
"rules": {
"prettier/prettier": ["warn", { "trailingComma": "es5", "printWidth": 200 }],
"prettier/prettier": ["warn", { "trailingComma": "es5", "printWidth": 100 }],
"linebreak-style": "off",
"no-console": ["warn", { "allow": ["warn", "error", "log"] }],
"no-case-declarations": 0,

View File

@ -8,11 +8,11 @@
## 【必看】环境准备
- **Node 版本: 16.0+**
1. 需要准备两个 Terminal分别启动服务端、前端页面。
2. 开通 ASR、TTS、LLM、RTC 等服务,可通过 [无代码跑通实时对话式](https://console.volcengine.com/rtc/guide) 快速开通服务, 点击 **快速开始** 中的 **跑通 Demo** 进行服务开通。
2. 开通 ASR、TTS、LLM、RTC 等服务,可参考 [开通服务](https://www.volcengine.com/docs/6348/1315561?s=g) 进行相关服务的授权与开通。
3. **根据你自定义的
RoomId、UserId 以及申请的 AppID、BusinessID(如有)、Token、ASR AppID、TTS AppID修改 `src/config/config.ts` 文件中 `ConfigFactory``BaseConfig` 的配置信息**。
4. 使用火山引擎控制台账号的 [AK、SK](https://console.volcengine.com/iam/keymanage?s=g)、[SessionToken](https://www.volcengine.com/docs/6348/1315561#sub?s=g)(临时token, 子账号才需要), 修改 `Server/app.js` 文件中的 `ACCOUNT_INFO`
5. 您需要在 [火山方舟-在线推理](https://console.volcengine.com/ark/region:ark+cn-beijing/endpoint?config=%7B%7D&s=g) 中创建接入点, 并将模型对应的接入点 ID 填入 `src/config/common.ts` 文件中的 `ARK_V3_MODEL_ID`, 否则无法正常启动智能体。
4. 使用火山引擎控制台账号的 [AK、SK](https://console.volcengine.com/iam/keymanage?s=g), 修改 `Server/app.js` 文件中的 `ACCOUNT_INFO`
5. 使用的是官方模型, 需要在 [火山方舟-在线推理](https://console.volcengine.com/ark/region:ark+cn-beijing/endpoint?config=%7B%7D&s=g) 中创建接入点, 并将模型对应的接入点 ID 填入 `src/config/common.ts` 文件中的 `ARK_V3_MODEL_ID`, 否则无法正常启动智能体。
6. 如果您已经自行完成了服务端的逻辑,可以不依赖 Demo 中的 Server直接修改前端代码文件 `src/config/index.ts` 中的 `AIGC_PROXY_HOST` 请求域名和接口,并在 `src/app/api.ts` 中修改接口的参数配置 `APIS_CONFIG`
## 快速开始
@ -43,12 +43,12 @@ yarn dev
### 常见问题
| 问题 | 解决方案 |
| :-- | :-- |
| **启动智能体之后, 对话无反馈,或者一直停留在 "AI 准备中, 请稍侯"** | <li>可能因为控制台中相关权限没有正常授予,请参考[流程](https://www.volcengine.com/docs/6348/1315561?s=g)再次确认下是否完成相关操作。此问题的可能性较大,建议仔细对照是否已经将相应的权限开通。</li><li>参数传递可能有问题, 例如参数大小写、类型等问题,请再次确认下这类型问题是否存在。</li><li>相关资源可能未开通或者用量不足,请再次确认。</li><li>**请检查当前使用的模型 ID 等内容都是正确且可用的。**</li> |
| `Server/app.js` 中的 `sessionToken` 是什么,该怎么填,为什么要填 | `sessionToken` 是火山引擎子账号发起 OpenAPI 请求时所必须携带的临时 Token获取方式可参考 [此文章末尾](https://www.volcengine.com/docs/6348/1315561?s=g)。 |
| **浏览器报了 `Uncaught (in promise) r: token_error` 错误** | 请检查您填在项目中的 RTC Token 是否合法,检测用于生成 Token 的 UserId、RoomId 是否与项目中填写的一致;或者 Token 可能过期, 可尝试重新生成下。 |
| 如何使用第三方模型、Coze Bot | 点击页面上的 "修改 AI 设定" 进入配置页,可切换 官方模型/Coze/第三方模型,填写对应参数即可,相关代码对应 `src/components/AISettings/index.tsx` 文件。 |
| **启动智能体之后, 对话无反馈,或者一直停留在 "AI 准备中, 请稍侯"** | <li>可能因为控制台中相关权限没有正常授予,请参考[流程](https://www.volcengine.com/docs/6348/1315561?s=g)再次确认下是否完成相关操作。此问题的可能性较大,建议仔细对照是否已经将相应的权限开通。</li><li>参数传递可能有问题, 例如参数大小写、类型等问题,请再次确认下这类型问题是否存在。</li><li>相关资源可能未开通或者用量不足/欠费,请再次确认。</li><li>**请检查当前使用的模型 ID 等内容都是正确且可用的。**</li> |
| **浏览器报了 `Uncaught (in promise) r: token_error` 错误** | 请检查您填在项目中的 RTC Token 是否合法,检测用于生成 Token 的 UserId、RoomId 以及 Token 本身是否与项目中填写的一致;或者 Token 可能过期, 可尝试重新生成下。 |
| **[StartVoiceChat]Failed(Reason: The task has been started. Please do not call the startup task interface repeatedly.)** 报错 | 由于目前设置的 RoomId、UserId 为固定值,重复调用 startAudioBot 会导致出错,只需先调用 stopAudioBot 后再重新 startAudioBot 即可。 |
| 为什么我的麦克风正常、摄像头也正常,但是设备没有正常工作? | 可能是设备权限未授予,详情可参考 [Web 排查设备权限获取失败问题](https://www.volcengine.com/docs/6348/1356355?s=g)。 |
| 接口调用时, 返回 "Invalid 'Authorization' header, Pls check your authorization header" 错误 | `Server/app.js` 中的 AK/SK/SessionToken 不正确 |
| 接口调用时, 返回 "Invalid 'Authorization' header, Pls check your authorization header" 错误 | `Server/app.js` 中的 AK/SK 不正确 |
| 什么是 RTC | **R**eal **T**ime **C**ommunication, RTC 的概念可参考[官网文档](https://www.volcengine.com/docs/6348/66812?s=g)。 |
| 不清楚什么是主账号,什么是子账号 | 可以参考[官方概念](https://www.volcengine.com/docs/6257/64963?hyperlink_open_type=lark.open_in_browser&s=g) 。|
@ -61,7 +61,21 @@ yarn dev
## 更新日志
### [1.5.0] - [2025-03-31]
### OpenAPI 更新
参考 [OpenAPI 更新](https://www.volcengine.com/docs/6348/116363?s=g) 中与 实时对话式 AI 相关的更新内容。
### Demo 更新
#### [1.6.0] - [2025-04-16]
- 支持 Coze Bot
- 更新部分注释和文档内容
- 删除子账号的 SessionToken 配置, 子账号调用无须 SessionToken
- 修复通话前修改内容,在通话后配置消失的问题
#### [1.5.1] - [2025-04-11]
- 移除无用代码和依赖
- 修复字幕逻辑
#### [1.5.0] - [2025-03-31]
- 修复部分 UI 问题
- 追加屏幕共享能力 (视觉模型可用,**读屏助手** 人设下可使用)
- 修改字幕逻辑,避免字幕回调中标点符号、大小写不一致引起的字幕重复问题

View File

@ -27,11 +27,6 @@ const ACCOUNT_INFO = {
* @notes 必填, https://console.volcengine.com/iam/keymanage/ 获取
*/
secretKey: 'Your SK',
/**
* @notes 非必填, 主账号无须传入, 子账号须传, 获取方式可参考
* https://www.volcengine.com/docs/6348/1315561 中的 步骤 4-使用子账号调用智能体接口 一节
*/
// sessionToken: 'Your SessionToken',
}
app.use(bodyParser());
@ -67,9 +62,7 @@ app.use(async ctx => {
/** 参考 https://www.volcengine.com/docs/6348/69828 可获取更多 OpenAPI 的信息 */
const result = await fetch(`https://rtc.volcengineapi.com?Action=${Action}&Version=${Version}`, {
method: 'POST',
headers: {
...openApiRequestData.headers,
},
headers: openApiRequestData.headers,
body: JSON.stringify(body),
});
const volcResponse = await result.json();

View File

@ -1,6 +1,6 @@
{
"name": "aigc",
"version": "1.5.0",
"version": "1.6.0",
"license": "BSD-3-Clause",
"private": true,
"dependencies": {

View File

@ -91,6 +91,12 @@
flex-direction: column;
gap: 36px;
.ai-settings-radio {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.anchor {
position: absolute;
border-bottom: 12px solid white;
@ -104,6 +110,7 @@
width: 100%;
display: flex;
flex-direction: row;
margin-top: -16px;
gap: 24px;
.ai-settings-wrapper {

View File

@ -3,10 +3,10 @@
* SPDX-license-identifier: BSD-3-Clause
*/
import { Button, Drawer, Input, Message } from '@arco-design/web-react';
import { Button, Drawer, Input, Message, Radio, Tooltip } from '@arco-design/web-react';
import { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { IconSwap } from '@arco-design/web-react/icon';
import { IconExclamationCircle } from '@arco-design/web-react/icon';
import { StreamIndex } from '@volcengine/rtc';
import CheckIcon from '../CheckIcon';
import Config, {
@ -18,7 +18,7 @@ import Config, {
Voice,
Model,
AI_MODEL,
ModelSourceType,
MODEL_MODE,
VOICE_INFO_MAP,
VOICE_TYPE,
isVisionMode,
@ -26,7 +26,7 @@ import Config, {
import TitleCard from '../TitleCard';
import CheckBoxSelector from '@/components/CheckBoxSelector';
import RtcClient from '@/lib/RtcClient';
import { clearHistoryMsg, updateAIConfig, updateScene } from '@/store/slices/room';
import { clearHistoryMsg, updateAIConfig, updateModelMode, updateScene } from '@/store/slices/room';
import { RootState } from '@/store';
import utils from '@/utils/utils';
import { useDeviceState } from '@/lib/useCommon';
@ -42,6 +42,8 @@ export interface IAISettingsProps {
onCancel?: () => void;
}
const RadioGroup = Radio.Group;
const SCENES = [
SCENE.INTELLIGENT_ASSISTANT,
SCENE.SCREEN_READER,
@ -59,17 +61,19 @@ function AISettings({ open, onCancel, onOk }: IAISettingsProps) {
useDeviceState();
const room = useSelector((state: RootState) => state.room);
const [loading, setLoading] = useState(false);
const [use3Part, setUse3Part] = useState(false);
const [modelMode, setModelMode] = useState<MODEL_MODE>(room.modelMode);
const [scene, setScene] = useState(room.scene);
const [data, setData] = useState({
prompt: Prompt[scene],
welcome: Welcome[scene],
voice: Voice[scene],
model: Model[scene],
prompt: Config.Prompt || Prompt[scene],
welcome: Config.WelcomeSpeech || Welcome[scene],
voice: Config.VoiceType || Voice[scene],
model: Config.Model || Model[scene],
Url: '',
APIKey: '',
customModelName: '',
Url: Config.Url || '',
APIKey: Config.APIKey || '',
customModelName: (Config.Model || '') as string,
BotID: Config.BotID || '',
});
const handleVoiceTypeChanged = (key: string) => {
@ -90,35 +94,55 @@ function AISettings({ open, onCancel, onOk }: IAISettingsProps) {
}));
};
const handleUseThirdPart = () => {
setUse3Part(!use3Part);
Config.ModeSourceType = use3Part ? ModelSourceType.Custom : ModelSourceType.Available;
const handleUseThirdPart = (val: MODEL_MODE) => {
setModelMode(val);
Config.ModeSourceType = val;
};
const handleUpdateConfig = async () => {
dispatch(updateScene({ scene }));
if (use3Part) {
if (!data.Url) {
Message.error('请输入正确的第三方模型地址');
return;
}
if (!data.Url.startsWith('http://') && !data.Url.startsWith('https://')) {
Message.error('第三方模型请求地址格式不正确, 请以 http:// 或 https:// 为开头');
return;
}
Config.Url = data.Url;
Config.APIKey = data.APIKey;
Config.ModeSourceType = ModelSourceType.Custom;
} else {
Config.Url = undefined;
Config.APIKey = undefined;
Config.ModeSourceType = ModelSourceType.Available;
Config.ModeSourceType = modelMode;
switch (modelMode) {
case MODEL_MODE.ORIGINAL:
Config.Url = undefined;
Config.APIKey = undefined;
break;
case MODEL_MODE.COZE:
if (!data.APIKey) {
Message.error('访问令牌必填');
return;
}
if (!data.BotID) {
Message.error('智能体 ID 必填');
return;
}
Config.APIKey = data.APIKey;
Config.BotID = data.BotID;
break;
case MODEL_MODE.VENDOR:
if (!data.Url) {
Message.error('请输入正确的第三方模型地址');
return;
}
if (!data.Url.startsWith('http://') && !data.Url.startsWith('https://')) {
Message.error('第三方模型请求地址格式不正确, 请以 http:// 或 https:// 为开头');
return;
}
Config.Url = data.Url;
Config.APIKey = data.APIKey;
break;
default:
break;
}
setLoading(true);
Config.Model = use3Part ? (data.customModelName as AI_MODEL) : (data.model as AI_MODEL);
Config.Model =
modelMode === MODEL_MODE.VENDOR
? (data.customModelName as AI_MODEL)
: (data.model as AI_MODEL);
Config.Prompt = data.prompt;
Config.VoiceType = data.voice;
Config.WelcomeSpeech = data.welcome;
dispatch(updateModelMode(modelMode));
dispatch(updateAIConfig(Config.aigcConfig));
if (isVisionMode(data.model)) {
@ -218,32 +242,85 @@ function AISettings({ open, onCancel, onOk }: IAISettingsProps) {
}}
/>
)}
<TitleCard title="Prompt">
<Input.TextArea
autoSize
value={data.prompt}
onChange={(val) => {
setData((prev) => ({
...prev,
prompt: val,
}));
}}
placeholder="请输入你需要的 Prompt 设定"
/>
</TitleCard>
<TitleCard title="欢迎语">
<Input.TextArea
autoSize
value={data.welcome}
onChange={(val) => {
setData((prev) => ({
...prev,
welcome: val,
}));
}}
placeholder="请输入欢迎语"
/>
</TitleCard>
<RadioGroup
options={[
{
value: MODEL_MODE.ORIGINAL,
label: '官方模型',
},
{
value: MODEL_MODE.COZE,
label: (
<div className={styles['radio-text']}>
<span style={{ marginRight: '4px' }}>Coze</span>
<Tooltip
content={
<div>
访{' '}
<a
href="https://www.coze.cn/open/docs/developer_guides/pat"
target="_blank"
rel="noreferrer"
style={{ color: 'gray' }}
>
访
</a>{' '}
<br />
ID {' '}
<a
href="https://www.coze.cn/open/docs/developer_guides/coze_api_overview#c5ac4993"
target="_blank"
rel="noreferrer"
style={{ color: 'gray' }}
>
</a>{' '}
<br />
API
</div>
}
>
<IconExclamationCircle />
</Tooltip>
</div>
),
},
{
value: MODEL_MODE.VENDOR,
label: (
<div className={styles['radio-text']}>
<span style={{ marginRight: '4px' }}></span>
<Tooltip
content={
<div>
使, {' '}
<a
href="https://www.volcengine.com/docs/6348/1399966"
target="_blank"
rel="noreferrer"
style={{ color: 'gray' }}
>
</a>{' '}
</div>
}
>
<IconExclamationCircle />
</Tooltip>
</div>
),
},
]}
value={modelMode}
size="mini"
type="button"
defaultValue="Beijing"
className={styles['ai-settings-radio']}
onChange={handleUseThirdPart}
/>
<div
className={styles['ai-settings']}
style={{
@ -272,7 +349,29 @@ function AISettings({ open, onCancel, onOk }: IAISettingsProps) {
</div>
</TitleCard>
<div className={styles['ai-settings-model']}>
{use3Part ? (
{modelMode === MODEL_MODE.ORIGINAL && (
<TitleCard title="官方模型">
<CheckBoxSelector
label="模型选择"
data={Object.keys(AI_MODEL).map((type) => ({
key: AI_MODEL[type as keyof typeof AI_MODEL],
label: type.replaceAll('_', ' '),
icon: DoubaoModelSVG,
}))}
moreIcon={ModelChangeSVG}
moreText="更换模型"
placeHolder="请选择你需要的模型"
onChange={(key) => {
setData((prev) => ({
...prev,
model: key as AI_MODEL,
}));
}}
value={data.model}
/>
</TitleCard>
)}
{modelMode === MODEL_MODE.VENDOR && (
<>
<TitleCard required title="第三方模型地址">
<Input.TextArea
@ -314,34 +413,68 @@ function AISettings({ open, onCancel, onOk }: IAISettingsProps) {
/>
</TitleCard>
</>
) : (
<TitleCard title="官方模型">
<CheckBoxSelector
label="模型选择"
data={Object.keys(AI_MODEL).map((type) => ({
key: AI_MODEL[type as keyof typeof AI_MODEL],
label: type.replaceAll('_', ' '),
icon: DoubaoModelSVG,
}))}
moreIcon={ModelChangeSVG}
moreText="更换模型"
placeHolder="请选择你需要的模型"
onChange={(key) => {
setData((prev) => ({
...prev,
model: key as AI_MODEL,
}));
}}
value={data.model}
/>
</TitleCard>
)}
<Button size="mini" type="text" onClick={handleUseThirdPart}>
{use3Part ? '使用官方模型' : '使用第三方模型'} <IconSwap />
</Button>
{modelMode === MODEL_MODE.COZE && (
<>
<TitleCard required title="请求地址">
<Input.TextArea autoSize disabled value="https://api.coze.cn" />
</TitleCard>
<TitleCard required title="访问令牌">
<Input.TextArea
autoSize
value={data.APIKey}
onChange={(val) => {
setData((prev) => ({
...prev,
APIKey: val,
}));
}}
placeholder="请输入访问令牌"
/>
</TitleCard>
<TitleCard required title="智能体 ID">
<Input.TextArea
autoSize
value={data.BotID}
onChange={(val) => {
setData((prev) => ({
...prev,
BotID: val,
}));
}}
placeholder="请输入智能体 ID"
/>
</TitleCard>
</>
)}
</div>
</div>
<TitleCard title="系统 Prompt">
<Input.TextArea
autoSize
value={data.prompt}
onChange={(val) => {
setData((prev) => ({
...prev,
prompt: val,
}));
}}
placeholder="请输入你需要的 Prompt 设定"
/>
</TitleCard>
<TitleCard title="欢迎语">
<Input.TextArea
autoSize
value={data.welcome}
onChange={(val) => {
setData((prev) => ({
...prev,
welcome: val,
}));
}}
placeholder="请输入欢迎语"
/>
</TitleCard>
</div>
</Drawer>
);

View File

@ -10,7 +10,7 @@ import AISettings from '../AISettings';
import style from './index.module.less';
import DouBaoAvatar from '@/assets/img/DoubaoAvatarGIF.webp';
import { RootState } from '@/store';
import { Name, VOICE_TYPE } from '@/config';
import { MODEL_MODE, Name, VOICE_TYPE } from '@/config';
interface IAvatarCardProps extends React.HTMLAttributes<HTMLDivElement> {
avatar?: string;
@ -24,11 +24,16 @@ const ReversedVoiceType = Object.entries(VOICE_TYPE).reduce<Record<string, strin
{}
);
const SourceName = {
[MODEL_MODE.VENDOR]: '第三方模型',
[MODEL_MODE.COZE]: 'Coze',
};
function AvatarCard(props: IAvatarCardProps) {
const room = useSelector((state: RootState) => state.room);
const { scene, aiConfig, modelMode } = room;
const [open, setOpen] = useState(false);
const scene = room.scene;
const { LLMConfig, TTSConfig } = room.aiConfig.Config || {};
const { LLMConfig, TTSConfig } = aiConfig.Config || {};
const { avatar, className, ...rest } = props;
const voice = TTSConfig.ProviderParams.audio.voice_type;
@ -51,7 +56,11 @@ function AvatarCard(props: IAvatarCardProps) {
<div className={style['user-info']}>
<div className={style.title}>{Name[scene]}</div>
<div className={style.description}> {ReversedVoiceType[voice || '']}</div>
<div className={style.description}> {LLMConfig.ModelName}</div>
<div className={style.description}>
{modelMode === MODEL_MODE.ORIGINAL
? `模型 ${LLMConfig.ModelName}`
: `模型来源 ${SourceName[modelMode]}`}
</div>
<AISettings open={open} onOk={handleCloseDrawer} onCancel={handleCloseDrawer} />
<Button className={style.button} onClick={handleOpenDrawer}>
<div className={style['button-text']}> AI </div>

View File

@ -24,6 +24,12 @@ export enum CustomParamsType {
LLM = 'LLM',
}
export enum MODEL_MODE {
ORIGINAL = 'original',
VENDOR = 'vendor',
COZE = 'coze',
}
/**
* @brief AI
* @default
@ -328,4 +334,4 @@ export const Prompt = {
[SCENE.CUSTOM]: '',
};
export const isVisionMode = (model: AI_MODEL) => model.startsWith('Vision');
export const isVisionMode = (model?: AI_MODEL) => model?.startsWith('Vision');

View File

@ -7,13 +7,12 @@ import { StreamIndex } from '@volcengine/rtc';
import {
TTS_CLUSTER,
ARK_V3_MODEL_ID,
ModelSourceType,
MODEL_MODE,
SCENE,
Prompt,
Welcome,
Model,
Voice,
// LLM_BOT_ID,
AI_MODEL,
AI_MODE_MAP,
AI_MODEL_MODE,
@ -98,7 +97,11 @@ export class ConfigFactory {
*/
WelcomeSpeech = Welcome[SCENE.INTELLIGENT_ASSISTANT];
ModeSourceType = ModelSourceType.Available;
/**
* @note 使, MODEL_MODE
* UI ,
*/
ModeSourceType = MODEL_MODE.ORIGINAL;
/**
* @note , 使,
@ -116,6 +119,11 @@ export class ConfigFactory {
*/
BotName = 'RobotMan_';
/**
* @note Coze ID UI
*/
BotID = '';
/**
* @brief
*/
@ -130,7 +138,6 @@ export class ConfigFactory {
const params: Record<string, unknown> = {
Mode: AI_MODE_MAP[this.Model || ''] || AI_MODEL_MODE.CUSTOM,
EndPointId: ARK_V3_MODEL_ID[this.Model],
// BotId: LLM_BOT_ID[this.Model],
MaxTokens: 1024,
Temperature: 0.1,
TopP: 0.3,
@ -139,7 +146,6 @@ export class ConfigFactory {
ModelName: this.Model,
ModelVersion: '1.0',
WelcomeSpeech: this.WelcomeSpeech,
ModeSourceType: this.ModeSourceType,
APIKey: this.APIKey,
Url: this.Url,
Feature: JSON.stringify({ Http: true }),
@ -154,6 +160,23 @@ export class ConfigFactory {
},
};
}
if (this.ModeSourceType === MODEL_MODE.COZE) {
/**
* @note Coze , 可参考: https://www.volcengine.com/docs/6348/1404673?s=g#llmconfig%EF%BC%88coze%E5%B9%B3%E5%8F%B0%EF%BC%89
*/
return {
Mode: 'CozeBot',
CozeBotConfig: {
Url: 'https://api.coze.cn',
BotID: this.BotID,
APIKey: this.APIKey,
UserId: this.BaseConfig.UserId,
HistoryLength: 10,
Prefill: false,
EnableConversation: false,
},
};
}
return params;
}

View File

@ -8,7 +8,6 @@ import { ConfigFactory } from './config';
export * from './common';
export const AIGC_PROXY_HOST = 'http://localhost:3001/proxyAIGCFetch';
export const DEMO_VERSION = '1.4.0';
export const Config = ConfigFactory;
export default new ConfigFactory();

View File

@ -10,7 +10,7 @@ import {
NetworkQuality,
RemoteAudioStats,
} from '@volcengine/rtc';
import config, { SCENE } from '@/config';
import config, { MODEL_MODE, SCENE } from '@/config';
export interface IUser {
username?: string;
@ -71,6 +71,10 @@ export interface RoomState {
* @brief AI
*/
aiConfig: ReturnType<any>;
/**
* @brief
*/
modelMode: MODEL_MODE;
/**
* @brief
*/
@ -116,6 +120,7 @@ const initialState: RoomState = {
networkQuality: NetworkQuality.UNKNOWN,
aiConfig: config.aigcConfig,
modelMode: MODEL_MODE.ORIGINAL,
msgHistory: [],
currentConversation: {},
@ -225,6 +230,9 @@ export const roomSlice = createSlice({
updateAIConfig: (state, { payload }) => {
state.aiConfig = Object.assign(state.aiConfig, payload);
},
updateModelMode: (state, { payload }) => {
state.modelMode = payload;
},
clearHistoryMsg: (state) => {
state.msgHistory = [];
},
@ -307,6 +315,7 @@ export const {
updateAITalkState,
updateAIThinkState,
updateAIConfig,
updateModelMode,
setHistoryMsg,
clearHistoryMsg,
clearCurrentMsg,