style: 优化部分细节样式
This commit is contained in:
parent
2a0f650963
commit
c89ba37617
@ -7,20 +7,20 @@ class AgentManager:
|
|||||||
self._classes = {}
|
self._classes = {}
|
||||||
self._instances = {} # 存储已创建的 agent 实例
|
self._instances = {} # 存储已创建的 agent 实例
|
||||||
|
|
||||||
def register_agent(self, agent_id, agent_class):
|
def register_agent(self, agent_class):
|
||||||
self._classes[agent_id] = agent_class
|
self._classes[agent_class.name] = agent_class
|
||||||
|
|
||||||
def init_all_agents(self):
|
def init_all_agents(self):
|
||||||
for agent_id, agent_class in self._classes.items():
|
for agent_class in self._classes.values():
|
||||||
self.get_agent(agent_id)
|
self.get_agent(agent_class.name)
|
||||||
|
|
||||||
def get_agent(self, agent_id, **kwargs):
|
def get_agent(self, agent_name, **kwargs):
|
||||||
# 检查是否已经创建了该 agent 的实例
|
# 检查是否已经创建了该 agent 的实例
|
||||||
if agent_id not in self._instances:
|
if agent_name not in self._instances:
|
||||||
agent_class = self._classes[agent_id]
|
agent_class = self._classes[agent_name]
|
||||||
self._instances[agent_id] = agent_class()
|
self._instances[agent_name] = agent_class()
|
||||||
|
|
||||||
return self._instances[agent_id]
|
return self._instances[agent_name]
|
||||||
|
|
||||||
def get_agents(self):
|
def get_agents(self):
|
||||||
return list(self._instances.values())
|
return list(self._instances.values())
|
||||||
@ -31,8 +31,8 @@ class AgentManager:
|
|||||||
|
|
||||||
|
|
||||||
agent_manager = AgentManager()
|
agent_manager = AgentManager()
|
||||||
agent_manager.register_agent("chatbot", ChatbotAgent)
|
agent_manager.register_agent(ChatbotAgent)
|
||||||
agent_manager.register_agent("react", ReActAgent) # 暂时屏蔽 ReActAgent
|
agent_manager.register_agent(ReActAgent) # 暂时屏蔽 ReActAgent
|
||||||
agent_manager.init_all_agents()
|
agent_manager.init_all_agents()
|
||||||
|
|
||||||
__all__ = ["agent_manager"]
|
__all__ = ["agent_manager"]
|
||||||
|
|||||||
@ -7,7 +7,7 @@ from src.agents.registry import BaseAgent
|
|||||||
from src.agents.react.configuration import ReActConfiguration
|
from src.agents.react.configuration import ReActConfiguration
|
||||||
|
|
||||||
class ReActAgent(BaseAgent):
|
class ReActAgent(BaseAgent):
|
||||||
name = "react"
|
name = "ReAct"
|
||||||
description = "A react agent that can answer questions and help with tasks."
|
description = "A react agent that can answer questions and help with tasks."
|
||||||
config_schema = ReActConfiguration
|
config_schema = ReActConfiguration
|
||||||
|
|
||||||
|
|||||||
@ -550,6 +550,10 @@ const toggleToolCall = (toolCallId) => {
|
|||||||
-moz-tab-size: 4;
|
-moz-tab-size: 4;
|
||||||
background-color: var(--gray-100);
|
background-color: var(--gray-100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-box.font-smaller #preview-only-preview {
|
.chat-box.font-smaller #preview-only-preview {
|
||||||
|
|||||||
@ -263,7 +263,6 @@ const toggleCollapse = () => {
|
|||||||
.conversation-title {
|
.conversation-title {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: var(--gray-900);
|
color: var(--gray-900);
|
||||||
margin-bottom: 4px;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|||||||
@ -2,13 +2,9 @@
|
|||||||
<div :class="['log-viewer', { fullscreen: state.isFullscreen }]" ref="logViewer">
|
<div :class="['log-viewer', { fullscreen: state.isFullscreen }]" ref="logViewer">
|
||||||
<div class="control-panel">
|
<div class="control-panel">
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<a-button @click="fetchLogs" :loading="state.fetching">
|
<a-button @click="fetchLogs" :loading="state.fetching" :icon="h(ReloadOutlined)" class="icon-only">
|
||||||
<template #icon><ReloadOutlined /></template>
|
|
||||||
刷新
|
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button @click="clearLogs">
|
<a-button @click="clearLogs" :icon="h(ClearOutlined)" class="icon-only">
|
||||||
<template #icon><ClearOutlined /></template>
|
|
||||||
清空
|
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button @click="printSystemConfig">
|
<a-button @click="printSystemConfig">
|
||||||
<template #icon><SettingOutlined /></template>
|
<template #icon><SettingOutlined /></template>
|
||||||
@ -98,7 +94,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, onActivated, onUnmounted, nextTick, reactive, computed } from 'vue';
|
import { ref, onMounted, onActivated, onUnmounted, nextTick, reactive, computed, h } from 'vue';
|
||||||
import { useConfigStore } from '@/stores/config';
|
import { useConfigStore } from '@/stores/config';
|
||||||
import { useUserStore } from '@/stores/user';
|
import { useUserStore } from '@/stores/user';
|
||||||
import { useDatabaseStore } from '@/stores/database';
|
import { useDatabaseStore } from '@/stores/database';
|
||||||
@ -428,10 +424,6 @@ const printAgentConfig = async () => {
|
|||||||
|
|
||||||
.control-panel {
|
.control-panel {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
padding: 16px;
|
|
||||||
background: var(--gray-50);
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 1px solid var(--gray-200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-group {
|
.button-group {
|
||||||
@ -448,6 +440,11 @@ const printAgentConfig = async () => {
|
|||||||
border-color: var(--gray-300);
|
border-color: var(--gray-300);
|
||||||
color: var(--gray-700);
|
color: var(--gray-700);
|
||||||
|
|
||||||
|
&.icon-only {
|
||||||
|
min-width: 32px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: var(--main-color);
|
border-color: var(--main-color);
|
||||||
color: var(--main-color);
|
color: var(--main-color);
|
||||||
|
|||||||
@ -479,17 +479,7 @@ const filteredModels = computed(() => {
|
|||||||
&.available {
|
&.available {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
&::after {
|
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.05);
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: -1px;
|
|
||||||
right: -1px;
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
background: #10b981;
|
|
||||||
border: 1px solid white;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,8 @@
|
|||||||
<div class="agent-view-header">
|
<div class="agent-view-header">
|
||||||
<div class="header-left">
|
<div class="header-left">
|
||||||
<div class="header-item">
|
<div class="header-item">
|
||||||
<a-button class="header-button" @click="toggleSidebar">
|
<a-button class="header-button" @click="toggleConf">
|
||||||
<template #icon><MenuOutlined /></template>
|
<template #icon><SettingOutlined /></template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-item">
|
<div class="header-item">
|
||||||
@ -55,117 +55,126 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="agent-view-body">
|
<div class="agent-view-body">
|
||||||
<!-- 左侧智能体列表侧边栏 -->
|
<!-- 配置弹窗 -->
|
||||||
<div class="sidebar" :class="{ 'is-open': state.agentSiderbarConfigOpen }">
|
<a-modal
|
||||||
<div class="agent-info">
|
v-model:open="state.agentConfOpen"
|
||||||
<h3>详细配置信<span @click="toggleDebugMode">息</span></h3>
|
title="智能体详细配置"
|
||||||
<p>{{ selectedAgent.description }}</p>
|
:width="600"
|
||||||
<pre v-if="state.debug_mode">{{ selectedAgent }}</pre>
|
:footer="null"
|
||||||
|
:maskClosable="false"
|
||||||
|
class="conf-modal"
|
||||||
|
>
|
||||||
|
<div class="conf-content">
|
||||||
|
<div class="agent-info">
|
||||||
|
<h3>详细配置信<span @click="toggleDebugMode">息</span></h3>
|
||||||
|
<p>{{ selectedAgent.description }}</p>
|
||||||
|
<pre v-if="state.debug_mode">{{ selectedAgent }}</pre>
|
||||||
|
|
||||||
<!-- 添加requirements显示部分 -->
|
<!-- 添加requirements显示部分 -->
|
||||||
<div v-if="agents[selectedAgentId]?.requirements && agents[selectedAgentId]?.requirements.length > 0" class="info-section">
|
<div v-if="agents[selectedAgentId]?.requirements && agents[selectedAgentId]?.requirements.length > 0" class="info-section">
|
||||||
<h3>所需环境变量:</h3>
|
<h3>所需环境变量:</h3>
|
||||||
<div class="requirements-list">
|
<div class="requirements-list">
|
||||||
<a-tag v-for="req in agents[selectedAgentId].requirements" :key="req">
|
<a-tag v-for="req in agents[selectedAgentId].requirements" :key="req">
|
||||||
{{ req }}
|
{{ req }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<a-divider />
|
<a-divider />
|
||||||
|
|
||||||
<div v-if="selectedAgentId && configSchema" class="config-modal-content">
|
<div v-if="selectedAgentId && configSchema" class="config-modal-content">
|
||||||
<!-- 配置表单 -->
|
<!-- 配置表单 -->
|
||||||
<a-form :model="agentConfig" layout="vertical">
|
<a-form :model="agentConfig" layout="vertical">
|
||||||
<a-alert v-if="state.isEmptyConfig" type="warning" message="该智能体没有配置项" show-icon/>
|
<a-alert v-if="state.isEmptyConfig" type="warning" message="该智能体没有配置项" show-icon/>
|
||||||
<a-alert v-if="!selectedAgent.has_checkpointer" type="error" message="该智能体没有配置 Checkpointer,功能无法正常使用,参考:https://langchain-ai.github.io/langgraph/concepts/persistence/" show-icon/>
|
<a-alert v-if="!selectedAgent.has_checkpointer" type="error" message="该智能体没有配置 Checkpointer,功能无法正常使用,参考:https://langchain-ai.github.io/langgraph/concepts/persistence/" show-icon/>
|
||||||
<!-- 统一显示所有配置项 -->
|
<!-- 统一显示所有配置项 -->
|
||||||
<template v-for="(value, key) in configurableItems" :key="key">
|
<template v-for="(value, key) in configurableItems" :key="key">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="getConfigLabel(key, value)"
|
:label="getConfigLabel(key, value)"
|
||||||
:name="key"
|
:name="key"
|
||||||
class="config-item"
|
class="config-item"
|
||||||
>
|
|
||||||
<p v-if="value.description" class="description">{{ value.description }}</p>
|
|
||||||
|
|
||||||
<!-- key匹配 -->
|
|
||||||
<div v-if="key === 'model'" class="agent-model">
|
|
||||||
<!-- <p><small>注意,部分模型对于 Tool Calling 的支持不稳定,建议采用{{ value.options }} </small></p> -->
|
|
||||||
<ModelSelectorComponent
|
|
||||||
@select-model="handleModelChange"
|
|
||||||
:model_name="agentConfig[key] ? agentConfig[key].split('/').slice(1).join('/') : ''"
|
|
||||||
:model_provider="agentConfig[key] ? agentConfig[key].split('/')[0] : ''"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<a-textarea
|
|
||||||
v-else-if="key === 'system_prompt'"
|
|
||||||
v-model:value="agentConfig[key]"
|
|
||||||
:rows="4"
|
|
||||||
:placeholder="getPlaceholder(key, value)"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 数据类型匹配 -->
|
|
||||||
<a-switch
|
|
||||||
v-else-if="typeof agentConfig[key] === 'boolean'"
|
|
||||||
v-model:checked="agentConfig[key]"
|
|
||||||
/>
|
|
||||||
<a-select
|
|
||||||
v-else-if="value?.options && value?.type === 'str'"
|
|
||||||
v-model:value="agentConfig[key]"
|
|
||||||
>
|
>
|
||||||
<a-select-option v-for="option in value.options" :key="option" :value="option"></a-select-option>
|
<p v-if="value.description" class="description">{{ value.description }}</p>
|
||||||
</a-select>
|
|
||||||
<!-- 多选标签卡片 -->
|
<!-- key匹配 -->
|
||||||
<div v-else-if="value?.options && value?.type === 'list'" class="multi-select-cards">
|
<div v-if="key === 'model'" class="agent-model">
|
||||||
<div class="multi-select-label">
|
<!-- <p><small>注意,部分模型对于 Tool Calling 的支持不稳定,建议采用{{ value.options }} </small></p> -->
|
||||||
<span>已选择 {{ getSelectedCount(key) }} 项</span>
|
<ModelSelectorComponent
|
||||||
<a-button type="link" size="small" @click="clearSelection(key)" v-if="getSelectedCount(key) > 0" >
|
@select-model="handleModelChange"
|
||||||
清空
|
:model_name="agentConfig[key] ? agentConfig[key].split('/').slice(1).join('/') : ''"
|
||||||
</a-button>
|
:model_provider="agentConfig[key] ? agentConfig[key].split('/')[0] : ''"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="options-grid">
|
<a-textarea
|
||||||
<div
|
v-else-if="key === 'system_prompt'"
|
||||||
v-for="option in value.options"
|
v-model:value="agentConfig[key]"
|
||||||
:key="option"
|
:rows="4"
|
||||||
class="option-card"
|
:placeholder="getPlaceholder(key, value)"
|
||||||
:class="{
|
/>
|
||||||
'selected': isOptionSelected(key, option),
|
|
||||||
'unselected': !isOptionSelected(key, option)
|
<!-- 数据类型匹配 -->
|
||||||
}"
|
<a-switch
|
||||||
@click="toggleOption(key, option)"
|
v-else-if="typeof agentConfig[key] === 'boolean'"
|
||||||
>
|
v-model:checked="agentConfig[key]"
|
||||||
<div class="option-content">
|
/>
|
||||||
<span class="option-text">{{ option }}</span>
|
<a-select
|
||||||
<div class="option-indicator">
|
v-else-if="value?.options && value?.type === 'str'"
|
||||||
<CheckCircleOutlined v-if="isOptionSelected(key, option)" />
|
v-model:value="agentConfig[key]"
|
||||||
<PlusCircleOutlined v-else />
|
>
|
||||||
|
<a-select-option v-for="option in value.options" :key="option" :value="option"></a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<!-- 多选标签卡片 -->
|
||||||
|
<div v-else-if="value?.options && value?.type === 'list'" class="multi-select-cards">
|
||||||
|
<div class="multi-select-label">
|
||||||
|
<span>已选择 {{ getSelectedCount(key) }} 项</span>
|
||||||
|
<a-button type="link" size="small" @click="clearSelection(key)" v-if="getSelectedCount(key) > 0" >
|
||||||
|
清空
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<div class="options-grid">
|
||||||
|
<div
|
||||||
|
v-for="option in value.options"
|
||||||
|
:key="option"
|
||||||
|
class="option-card"
|
||||||
|
:class="{
|
||||||
|
'selected': isOptionSelected(key, option),
|
||||||
|
'unselected': !isOptionSelected(key, option)
|
||||||
|
}"
|
||||||
|
@click="toggleOption(key, option)"
|
||||||
|
>
|
||||||
|
<div class="option-content">
|
||||||
|
<span class="option-text">{{ option }}</span>
|
||||||
|
<div class="option-indicator">
|
||||||
|
<CheckCircleOutlined v-if="isOptionSelected(key, option)" />
|
||||||
|
<PlusCircleOutlined v-else />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<a-input
|
||||||
|
v-else
|
||||||
|
v-model:value="agentConfig[key]"
|
||||||
|
:placeholder="getPlaceholder(key, value)"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<a-divider />
|
||||||
|
|
||||||
|
<!-- 弹窗底部按钮 -->
|
||||||
|
<div class="form-actions" v-if="!state.isEmptyConfig">
|
||||||
|
<div class="form-actions-left">
|
||||||
|
<a-button type="primary" @click="saveConfig">保存并发布配置</a-button>
|
||||||
|
<a-button @click="resetConfig">重置</a-button>
|
||||||
</div>
|
</div>
|
||||||
<a-input
|
|
||||||
v-else
|
|
||||||
v-model:value="agentConfig[key]"
|
|
||||||
:placeholder="getPlaceholder(key, value)"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<a-divider />
|
|
||||||
|
|
||||||
<!-- 弹窗底部按钮 -->
|
|
||||||
<div class="form-actions" v-if="!state.isEmptyConfig">
|
|
||||||
<div class="form-actions-left">
|
|
||||||
<a-button type="primary" @click="saveConfig">保存并发布配置</a-button>
|
|
||||||
<a-button @click="resetConfig">重置</a-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a-form>
|
||||||
</a-form>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a-modal>
|
||||||
|
|
||||||
<!-- 中间内容区域 -->
|
<!-- 中间内容区域 -->
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@ -173,7 +182,7 @@
|
|||||||
:agent-id="selectedAgentId"
|
:agent-id="selectedAgentId"
|
||||||
:config="agentConfig"
|
:config="agentConfig"
|
||||||
:state="state"
|
:state="state"
|
||||||
@open-config="toggleConfigSidebar(true)"
|
@open-config="toggleConf"
|
||||||
>
|
>
|
||||||
</AgentChatComponent>
|
</AgentChatComponent>
|
||||||
</div>
|
</div>
|
||||||
@ -189,7 +198,6 @@ import {
|
|||||||
SettingOutlined,
|
SettingOutlined,
|
||||||
LinkOutlined,
|
LinkOutlined,
|
||||||
StarOutlined,
|
StarOutlined,
|
||||||
MenuOutlined,
|
|
||||||
StarFilled,
|
StarFilled,
|
||||||
CheckCircleOutlined,
|
CheckCircleOutlined,
|
||||||
PlusCircleOutlined
|
PlusCircleOutlined
|
||||||
@ -210,7 +218,7 @@ const agents = ref({});
|
|||||||
const selectedAgentId = ref(null);
|
const selectedAgentId = ref(null);
|
||||||
const defaultAgentId = ref(null); // 存储默认智能体ID
|
const defaultAgentId = ref(null); // 存储默认智能体ID
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
agentSiderbarConfigOpen: false,
|
agentConfOpen: false,
|
||||||
debug_mode: false,
|
debug_mode: false,
|
||||||
isEmptyConfig: computed(() =>
|
isEmptyConfig: computed(() =>
|
||||||
!selectedAgentId.value ||
|
!selectedAgentId.value ||
|
||||||
@ -483,8 +491,8 @@ const toggleDebugMode = () => {
|
|||||||
console.log("debug_mode", state.debug_mode);
|
console.log("debug_mode", state.debug_mode);
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleSidebar = () => {
|
const toggleConf = () => {
|
||||||
state.agentSiderbarConfigOpen = !state.agentSiderbarConfigOpen
|
state.agentConfOpen = !state.agentConfOpen
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -496,7 +504,6 @@ const toggleSidebar = () => {
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
--agent-view-header-height: 60px;
|
--agent-view-header-height: 60px;
|
||||||
--agent-sidebar-width: 450px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.agent-view-header {
|
.agent-view-header {
|
||||||
@ -533,112 +540,30 @@ const toggleSidebar = () => {
|
|||||||
padding: var(--gap-radius);
|
padding: var(--gap-radius);
|
||||||
gap: var(--gap-radius);
|
gap: var(--gap-radius);
|
||||||
|
|
||||||
.sidebar.is-open,
|
|
||||||
.content {
|
.content {
|
||||||
border-radius: var(--gap-radius);
|
border-radius: var(--gap-radius);
|
||||||
border: 1px solid var(--gray-300);
|
border: 1px solid var(--gray-300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
width: 0;
|
|
||||||
max-width: var(--agent-sidebar-width);
|
|
||||||
background-color: var(--bg-sider);
|
|
||||||
overflow-y: auto;
|
|
||||||
transition: width 0.3s ease;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&.is-open {
|
|
||||||
width: var(--agent-sidebar-width);
|
|
||||||
box-sizing: content-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-title {
|
|
||||||
height: var(--header-height);
|
|
||||||
font-weight: bold;
|
|
||||||
user-select: none;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
font-size: 1rem;
|
|
||||||
border-bottom: 1px solid var(--main-light-3);
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 16px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.agent-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 12px;
|
|
||||||
border-radius: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--main-light-4);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
background-color: var(--main-light-3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-info {
|
|
||||||
padding: 16px;
|
|
||||||
min-width: calc(var(--agent-sidebar-width) - 16px);
|
|
||||||
overflow-y: auto;
|
|
||||||
max-height: calc(100vh - 60px); /* 减去标题栏的高度 */
|
|
||||||
scrollbar-width: thin;
|
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
width: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
background-color: var(--main-light-4);
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-name {
|
|
||||||
font-weight: 500;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-desc {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #666;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-model {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 配置弹窗内容样式
|
||||||
|
.conf-content {
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.agent-info {
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
overflow-y: visible;
|
||||||
|
max-height: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 添加requirements相关样式
|
// 添加requirements相关样式
|
||||||
.info-section {
|
.info-section {
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
@ -661,35 +586,8 @@ const toggleSidebar = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 520px) {
|
.agent-model {
|
||||||
.sidebar {
|
width: 100%;
|
||||||
position: absolute;
|
|
||||||
z-index: 101;
|
|
||||||
width: 0;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 0 16px 16px 0;
|
|
||||||
box-shadow: 0 0 10px 1px rgba(0, 0, 0, 0.05);
|
|
||||||
|
|
||||||
&.is-open {
|
|
||||||
width: var(--agent-sidebar-width);
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.config-sidebar {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 101;
|
|
||||||
right: 0;
|
|
||||||
width: 0;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 16px 0 0 16px;
|
|
||||||
box-shadow: 0 0 10px 1px rgba(0, 0, 0, 0.05);
|
|
||||||
|
|
||||||
&.is-open {
|
|
||||||
width: 90%;
|
|
||||||
max-width: var(--config-sidebar-width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-modal-content {
|
.config-modal-content {
|
||||||
@ -849,12 +747,16 @@ const toggleSidebar = () => {
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.conf-content {
|
||||||
|
max-height: 60vh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.toggle-sidebar {
|
.toggle-conf {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&.nav-btn {
|
&.nav-btn {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user