feat: 先进智能体功能上线
- 基于 agent-runtime 打造,默认 ReAct agent - 支持 agent 能力对接,已对接工作流、插件、知识库等 tool 能力 - 全新 agent 编排界面,支持可视化便捷配置 agent - 全新 agent 聊天界面,支持快捷操作、额外知识库选择等
This commit is contained in:
@@ -34,6 +34,8 @@ import {useAgentDesignerState} from './composables/useAgentDesignerState';
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const AGENT_TAB_PAGE_KEY = '/ai/agents';
|
||||
const DEFAULT_AGENT_TITLE = '未命名智能体';
|
||||
const {
|
||||
state,
|
||||
addKnowledgeNode,
|
||||
@@ -52,6 +54,7 @@ const {
|
||||
|
||||
const pageLoading = ref(false);
|
||||
const saveLoading = ref(false);
|
||||
const offlineLoading = ref(false);
|
||||
const publishLoading = ref(false);
|
||||
const issues = ref<AgentValidationIssue[]>([]);
|
||||
const categories = ref<AgentOption[]>([]);
|
||||
@@ -62,14 +65,6 @@ const pluginTools = ref<AgentOption[]>([]);
|
||||
|
||||
const isNew = computed(() => String(route.params.id || '') === 'new');
|
||||
const publishText = computed(() => {
|
||||
if (
|
||||
canAiResourceOffline(
|
||||
state.agent.displayPublishStatus,
|
||||
state.agent.publishStatus,
|
||||
)
|
||||
) {
|
||||
return '下线';
|
||||
}
|
||||
if (
|
||||
canAiResourceRepublish(
|
||||
state.agent.displayPublishStatus,
|
||||
@@ -81,6 +76,13 @@ const publishText = computed(() => {
|
||||
return '发布';
|
||||
});
|
||||
|
||||
const offlineVisible = computed(() =>
|
||||
canAiResourceOffline(
|
||||
state.agent.displayPublishStatus,
|
||||
state.agent.publishStatus,
|
||||
),
|
||||
);
|
||||
|
||||
const publishDisabled = computed(() => {
|
||||
if (!state.agent.id) return true;
|
||||
if (
|
||||
@@ -99,14 +101,15 @@ const publishDisabled = computed(() => {
|
||||
canAiResourceRepublish(
|
||||
state.agent.displayPublishStatus,
|
||||
state.agent.publishStatus,
|
||||
) ||
|
||||
canAiResourceOffline(
|
||||
state.agent.displayPublishStatus,
|
||||
state.agent.publishStatus,
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
const offlineDisabled = computed(() => {
|
||||
if (!state.agent.id) return true;
|
||||
return !offlineVisible.value;
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
pageLoading.value = true;
|
||||
try {
|
||||
@@ -119,14 +122,55 @@ onMounted(async () => {
|
||||
async function loadAgent() {
|
||||
if (isNew.value) {
|
||||
reset();
|
||||
syncNavTitle(DEFAULT_AGENT_TITLE, { force: true });
|
||||
return;
|
||||
}
|
||||
const [, res] = await tryit(getAgentDetail)(String(route.params.id));
|
||||
if (res?.errorCode === 0) {
|
||||
reset(res.data);
|
||||
syncNavTitle(resolveAgentTitle(res.data), { force: !hasNavTitle() });
|
||||
}
|
||||
}
|
||||
|
||||
function hasNavTitle() {
|
||||
const navTitle = Array.isArray(route.query.navTitle)
|
||||
? route.query.navTitle[0]
|
||||
: route.query.navTitle;
|
||||
return typeof navTitle === 'string' && navTitle.trim();
|
||||
}
|
||||
|
||||
function resolveAgentTitle(agent = state.agent) {
|
||||
return String(agent.name || '').trim() || DEFAULT_AGENT_TITLE;
|
||||
}
|
||||
|
||||
function syncNavTitle(title: string, options: { force?: boolean } = {}) {
|
||||
const normalizedTitle = String(title || '').trim() || DEFAULT_AGENT_TITLE;
|
||||
const query = route.query as Record<string, any>;
|
||||
const currentNavTitle = Array.isArray(query.navTitle)
|
||||
? query.navTitle[0]
|
||||
: query.navTitle;
|
||||
const currentPageKey = Array.isArray(query.pageKey)
|
||||
? query.pageKey[0]
|
||||
: query.pageKey;
|
||||
|
||||
if (
|
||||
!options.force &&
|
||||
currentNavTitle === normalizedTitle &&
|
||||
currentPageKey === AGENT_TAB_PAGE_KEY
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
router.replace({
|
||||
path: route.path,
|
||||
query: {
|
||||
...query,
|
||||
pageKey: AGENT_TAB_PAGE_KEY,
|
||||
navTitle: normalizedTitle,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function loadOptions() {
|
||||
const [categoryRes, modelRes, knowledgeRes, workflowRes, pluginRes] =
|
||||
await Promise.all([
|
||||
@@ -245,8 +289,18 @@ async function handleSave(showMessage = true) {
|
||||
id,
|
||||
};
|
||||
state.dirty = false;
|
||||
const title = resolveAgentTitle();
|
||||
if (isNew.value) {
|
||||
await router.replace(`/ai/agents/designer/${id}`);
|
||||
await router.replace({
|
||||
path: `/ai/agents/designer/${id}`,
|
||||
query: {
|
||||
...route.query,
|
||||
pageKey: AGENT_TAB_PAGE_KEY,
|
||||
navTitle: title,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
syncNavTitle(title, { force: true });
|
||||
}
|
||||
if (showMessage) {
|
||||
ElMessage.success('已保存');
|
||||
@@ -262,29 +316,19 @@ async function handlePublish() {
|
||||
const saved = await handleSave(false);
|
||||
if (!saved) return;
|
||||
|
||||
const offline = canAiResourceOffline(
|
||||
state.agent.displayPublishStatus,
|
||||
state.agent.publishStatus,
|
||||
);
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
offline ? '确认提交下线审批?' : '确认提交发布审批?',
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: offline ? 'warning' : 'info',
|
||||
},
|
||||
);
|
||||
await ElMessageBox.confirm('确认提交发布审批?', '提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'info',
|
||||
});
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
publishLoading.value = true;
|
||||
try {
|
||||
const res = offline
|
||||
? await submitAgentOfflineApproval(String(state.agent.id))
|
||||
: await submitAgentPublishApproval(String(state.agent.id));
|
||||
const res = await submitAgentPublishApproval(String(state.agent.id));
|
||||
if (res.errorCode === 0) {
|
||||
ElMessage.success(res.message || '已提交');
|
||||
await loadAgent();
|
||||
@@ -294,6 +338,33 @@ async function handlePublish() {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleOffline() {
|
||||
if (!state.agent.id) return;
|
||||
const saved = await handleSave(false);
|
||||
if (!saved) return;
|
||||
|
||||
try {
|
||||
await ElMessageBox.confirm('确认提交下线审批?', '提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
offlineLoading.value = true;
|
||||
try {
|
||||
const res = await submitAgentOfflineApproval(String(state.agent.id));
|
||||
if (res.errorCode === 0) {
|
||||
ElMessage.success(res.message || '已提交');
|
||||
await loadAgent();
|
||||
}
|
||||
} finally {
|
||||
offlineLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleTryout() {
|
||||
if (!runValidation()) return;
|
||||
openTryout();
|
||||
@@ -330,8 +401,12 @@ function handleCloseTryout() {
|
||||
:publish-loading="publishLoading"
|
||||
:publish-disabled="publishDisabled"
|
||||
:publish-text="publishText"
|
||||
:offline-disabled="offlineDisabled"
|
||||
:offline-loading="offlineLoading"
|
||||
:offline-visible="offlineVisible"
|
||||
@add="handleAdd"
|
||||
@save="handleSave()"
|
||||
@offline="handleOffline"
|
||||
@publish="handlePublish"
|
||||
@tryout="handleTryout"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user