feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FC, type ReactNode } from 'react';
|
||||
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { Popover } from '@coze-arch/bot-semi';
|
||||
import { CollapsibleIconButton } from '@coze-studio/components/collapsible-icon-button';
|
||||
import { InputSlider } from '@coze-studio/components';
|
||||
import { useModelStore } from '@coze-studio/bot-detail-store/model';
|
||||
import { ModelFormItem } from '@coze-agent-ide/model-manager';
|
||||
import { IconCozChatSetting } from '@coze-arch/coze-design/icons';
|
||||
|
||||
const DialogueConfig: FC<{ tips: ReactNode }> = ({ tips }) => {
|
||||
const { model, setModelByImmer } = useModelStore(
|
||||
useShallow(state => ({
|
||||
model: state,
|
||||
setModelByImmer: state.setModelByImmer,
|
||||
})),
|
||||
);
|
||||
|
||||
const handleChange = (value: number) => {
|
||||
setModelByImmer(draft => {
|
||||
if (!draft.config.ShortMemPolicy) {
|
||||
draft.config.ShortMemPolicy = { HistoryRound: value };
|
||||
return;
|
||||
}
|
||||
draft.config.ShortMemPolicy.HistoryRound = value;
|
||||
});
|
||||
};
|
||||
return (
|
||||
<div className="p-[24px]">
|
||||
<div className="leading-[32px] coz-fg-plus text-[20px] font-[500]">
|
||||
{I18n.t('workflow_agent_dialog_set')}
|
||||
</div>
|
||||
{tips ? (
|
||||
<div className="mt-[16px] coz-fg-secondary text-[14px] leading-[20px]">
|
||||
{tips}
|
||||
</div>
|
||||
) : null}
|
||||
<div className="mt-[16px] coz-fg-plus text-[14px] leading-[20px] font-[500]">
|
||||
{I18n.t('workflow_agent_dialog_set_chathistory')}
|
||||
</div>
|
||||
<ModelFormItem
|
||||
popoverContent={I18n.t('model_config_history_round_explain')}
|
||||
label={I18n.t('model_config_history_round')}
|
||||
>
|
||||
<InputSlider
|
||||
step={1}
|
||||
min={0}
|
||||
max={100}
|
||||
decimalPlaces={0}
|
||||
value={model.config.ShortMemPolicy?.HistoryRound}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</ModelFormItem>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const itemKey = Symbol.for('DialogueConfigView');
|
||||
|
||||
export const DialogueConfigView: FC<{
|
||||
tips: ReactNode;
|
||||
}> = ({ tips }) => (
|
||||
<Popover
|
||||
className="overflow-hidden rounded-[12px] w-[600px]"
|
||||
trigger="click"
|
||||
autoAdjustOverflow={true}
|
||||
content={<DialogueConfig tips={tips} />}
|
||||
>
|
||||
<CollapsibleIconButton
|
||||
itemKey={itemKey}
|
||||
data-testid="bot.ide.bot_creator.set_model_view_button"
|
||||
icon={<IconCozChatSetting className="text-[16px]" />}
|
||||
text={I18n.t('workflow_agent_dialog_set')}
|
||||
/>
|
||||
</Popover>
|
||||
);
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { DialogueConfigView } from './dialogue-config-view';
|
||||
export { SingleAgentModelView } from './single-agent-model-view';
|
||||
export { ModelConfigView } from './model-config-view';
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { BotMode } from '@coze-arch/bot-api/playground_api';
|
||||
import { useGetSingleAgentCurrentModel } from '@coze-agent-ide/model-manager';
|
||||
|
||||
import { SingleAgentModelView } from './single-agent-model-view';
|
||||
import { DialogueConfigView } from './dialogue-config-view';
|
||||
|
||||
export const ModelConfigView: React.FC<{
|
||||
mode: BotMode;
|
||||
modelListExtraHeaderSlot?: React.ReactNode;
|
||||
}> = ({ mode, modelListExtraHeaderSlot }) => {
|
||||
const currentModel = useGetSingleAgentCurrentModel();
|
||||
|
||||
if (mode === BotMode.SingleMode) {
|
||||
return currentModel?.model_type ? (
|
||||
<SingleAgentModelView
|
||||
modelListExtraHeaderSlot={modelListExtraHeaderSlot}
|
||||
/>
|
||||
) : null;
|
||||
}
|
||||
if (mode === BotMode.MultiMode || mode === BotMode.WorkflowMode) {
|
||||
return (
|
||||
<DialogueConfigView
|
||||
tips={
|
||||
mode === BotMode.WorkflowMode
|
||||
? I18n.t('workflow_agent_dialog_set_desc')
|
||||
: null
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { useModelStore } from '@coze-studio/bot-detail-store/model';
|
||||
import { useBotDetailIsReadonly } from '@coze-studio/bot-detail-store';
|
||||
import { useSpaceStore } from '@coze-arch/bot-studio-store';
|
||||
import { type Model } from '@coze-arch/bot-api/developer_api';
|
||||
import { ModelSelect } from '@coze-agent-ide/model-manager/model-select-v2';
|
||||
import {
|
||||
useModelCapabilityCheckModal,
|
||||
useGetSingleAgentCurrentModel,
|
||||
getModelOptionList,
|
||||
} from '@coze-agent-ide/model-manager';
|
||||
import { useBotEditor } from '@coze-agent-ide/bot-editor-context-store';
|
||||
import {
|
||||
useBotCreatorContext,
|
||||
BotCreatorScene,
|
||||
} from '@coze-agent-ide/bot-creator-context';
|
||||
|
||||
export interface SingleAgentModelViewProps {
|
||||
modelListExtraHeaderSlot?: React.ReactNode;
|
||||
triggerRender?: (model?: Model, popoverVisible?: boolean) => React.ReactNode;
|
||||
}
|
||||
|
||||
export function SingleAgentModelView(props: SingleAgentModelViewProps) {
|
||||
const { modelListExtraHeaderSlot, triggerRender } = props;
|
||||
const spaceId = useSpaceStore(store => store.space.id);
|
||||
const { scene } = useBotCreatorContext();
|
||||
const currentModel = useGetSingleAgentCurrentModel();
|
||||
const currentModelId = currentModel?.model_type
|
||||
? String(currentModel.model_type)
|
||||
: undefined;
|
||||
|
||||
const { storeSet } = useBotEditor();
|
||||
const modelStore = storeSet.useModelStore(
|
||||
useShallow(state => ({
|
||||
onlineModelList: state.onlineModelList,
|
||||
offlineModelMap: state.offlineModelMap,
|
||||
getModelPreset: state.getModelPreset,
|
||||
})),
|
||||
);
|
||||
|
||||
const [currentModelIdState, setCurrentModelIdState] = useState<
|
||||
string | undefined
|
||||
>(currentModelId);
|
||||
|
||||
const { modelConfig, setModelByImmer } = useModelStore(
|
||||
useShallow(state => ({
|
||||
modelConfig: state.config,
|
||||
setModelByImmer: state.setModelByImmer,
|
||||
})),
|
||||
);
|
||||
|
||||
const { modalNode, checkAndOpenModal } = useModelCapabilityCheckModal({
|
||||
onOk: modelId => {
|
||||
setCurrentModelIdState(modelId);
|
||||
},
|
||||
});
|
||||
|
||||
const isReadonly = useBotDetailIsReadonly();
|
||||
|
||||
const modelList = getModelOptionList({
|
||||
onlineModelList: modelStore.onlineModelList,
|
||||
offlineModelMap: modelStore.offlineModelMap,
|
||||
currentModelId: String(currentModel?.model_type),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentModelIdState(currentModelId);
|
||||
}, [currentModelId]);
|
||||
|
||||
return currentModelIdState ? (
|
||||
<>
|
||||
<ModelSelect
|
||||
popoverClassName="h-auto !max-h-[70vh]"
|
||||
disabled={isReadonly}
|
||||
enableJumpDetail={
|
||||
scene === BotCreatorScene.Bot && spaceId && !IS_OPEN_SOURCE
|
||||
? { spaceId }
|
||||
: undefined
|
||||
}
|
||||
modelListExtraHeaderSlot={modelListExtraHeaderSlot}
|
||||
selectedModelId={currentModelIdState}
|
||||
modelList={modelList}
|
||||
onModelChange={m => {
|
||||
const modelId = String(m.model_type);
|
||||
const checkPassed = checkAndOpenModal(modelId);
|
||||
if (checkPassed) {
|
||||
setCurrentModelIdState(modelId);
|
||||
}
|
||||
return checkPassed;
|
||||
}}
|
||||
modelConfigProps={{
|
||||
hideDiversityCollapseButton: true,
|
||||
agentType: 'single',
|
||||
currentConfig: modelConfig,
|
||||
onConfigChange: v => {
|
||||
setModelByImmer(draft => {
|
||||
draft.config = {
|
||||
model: currentModelIdState,
|
||||
...v,
|
||||
};
|
||||
});
|
||||
},
|
||||
modelStore,
|
||||
}}
|
||||
triggerRender={triggerRender}
|
||||
modalSlot={modalNode}
|
||||
/>
|
||||
</>
|
||||
) : null;
|
||||
}
|
||||
Reference in New Issue
Block a user