<template><div class="page-content"><div class="mb-5 flex items-start justify-between"><div><h2 class="text-xl font-semibold">AI 应用</h2><p class="text-g-500 mt-1 text-sm">组合模型、Prompt、知识库和工具；发布生成不可变版本，运行入口仍经过网关全治理链路</p></div><ElButton type="primary" @click="openCreate">新建应用</ElButton></div><ElTable v-loading="loading" :data="items" row-key="id"><ElTableColumn prop="code" label="编码" min-width="140"/><ElTableColumn prop="name" label="名称" min-width="150"/><ElTableColumn label="模型" min-width="180"><template #default="{row}">{{row.draft_config.model||'未配置'}}</template></ElTableColumn><ElTableColumn label="资产" min-width="170"><template #default="{row}">Prompt {{row.draft_config.prompt_template_id?'1':'0'}} / 知识库 {{row.draft_config.knowledge_base_ids.length}} / 工具 {{row.draft_config.tool_ids.length}}</template></ElTableColumn><ElTableColumn label="线上版本" width="100"><template #default="{row}"><ElTag :type="row.published_version?'success':'info'">{{row.published_version?`v${row.published_version}`:'未发布'}}</ElTag></template></ElTableColumn><ElTableColumn prop="status" label="状态" width="100"/><ElTableColumn label="操作" width="250" fixed="right"><template #default="{row}"><ElButton link type="primary" @click="openEdit(row)">编排</ElButton><ElButton link type="success" @click="publish(row)">发布</ElButton><ElButton link type="primary" @click="inspect(row)">记录</ElButton><ElButton link type="danger" @click="remove(row)">删除</ElButton></template></ElTableColumn></ElTable>
<ElDialog v-model="visible" :title="editing?'编辑应用编排':'新建应用'" width="780px"><ElForm label-width="120px"><div class="grid grid-cols-2 gap-x-4"><ElFormItem label="应用编码"><ElInput v-model="form.code" :disabled="!!editing" placeholder="customer_assistant"/></ElFormItem><ElFormItem label="名称"><ElInput v-model="form.name"/></ElFormItem></div><ElFormItem label="描述"><ElInput v-model="form.description" type="textarea"/></ElFormItem><ElFormItem label="模型"><ElInput v-model="form.draft_config.model" placeholder="已注册的模型别名或模型名"/></ElFormItem><ElFormItem label="Prompt"><ElSelect v-model="form.draft_config.prompt_template_id" clearable class="w-full"><ElOption v-for="p in prompts" :key="p.id" :label="`${p.name} (v${p.current_version||'-'})`" :value="p.id"/></ElSelect></ElFormItem><ElFormItem label="知识库"><ElSelect v-model="form.draft_config.knowledge_base_ids" multiple class="w-full"><ElOption v-for="k in knowledge" :key="k.id" :label="k.name" :value="k.id"/></ElSelect></ElFormItem><ElFormItem label="工具"><ElSelect v-model="form.draft_config.tool_ids" multiple class="w-full"><ElOption v-for="t in tools" :key="t.id" :label="`${t.name} (${t.code})`" :value="t.id"/></ElSelect></ElFormItem><div class="grid grid-cols-3 gap-x-4"><ElFormItem label="检索 Top K"><ElInputNumber v-model="form.draft_config.retrieval_top_k" :min="1" :max="20"/></ElFormItem><ElFormItem label="温度"><ElInputNumber v-model="form.draft_config.temperature" :min="0" :max="2" :step="0.1"/></ElFormItem><ElFormItem label="工具轮次"><ElInputNumber v-model="form.draft_config.max_tool_rounds" :min="0" :max="8"/></ElFormItem></div><ElFormItem label="部门范围"><ElSelect v-model="form.department_ids" multiple allow-create filterable class="w-full" placeholder="留空表示全部部门"/></ElFormItem><ElFormItem label="状态"><ElSelect v-model="form.status"><ElOption label="草稿" value="draft"/><ElOption label="启用" value="active"/><ElOption label="暂停" value="suspended"/><ElOption label="退役" value="retired"/></ElSelect></ElFormItem></ElForm><template #footer><ElButton @click="visible=false">取消</ElButton><ElButton type="primary" @click="save">保存草稿</ElButton></template></ElDialog>
<ElDrawer v-model="inspectVisible" :title="`${selected?.name||''} · 版本与运行`" size="65%"><ElTabs><ElTabPane label="发布版本"><pre class="whitespace-pre-wrap text-xs">{{JSON.stringify(versions,null,2)}}</pre></ElTabPane><ElTabPane label="最近运行"><ElTable :data="runs"><ElTableColumn prop="request_id" label="请求 ID"/><ElTableColumn prop="version" label="版本" width="80"/><ElTableColumn prop="status" label="状态" width="90"/><ElTableColumn prop="latency_ms" label="延迟 ms" width="100"/><ElTableColumn prop="retrieval_count" label="检索" width="80"/><ElTableColumn prop="tool_count" label="工具" width="80"/><ElTableColumn prop="error" label="错误"/></ElTable></ElTabPane></ElTabs></ElDrawer></div></template>
<script setup lang="ts">import{Application,ApplicationInput,KnowledgeBase,PromptTemplate,ToolDefinition,createApplication,deleteApplication,fetchApplicationRuns,fetchApplicationVersions,fetchApplications,fetchKnowledgeBases,fetchPrompts,fetchTools,publishApplication,updateApplication}from'@/api/workbench';import{ElMessage,ElMessageBox}from'element-plus';const loading=ref(false),visible=ref(false),inspectVisible=ref(false),editing=ref('');const items=ref<Application[]>([]),prompts=ref<PromptTemplate[]>([]),knowledge=ref<KnowledgeBase[]>([]),tools=ref<ToolDefinition[]>([]),versions=ref<any[]>([]),runs=ref<any[]>([]),selected=ref<Application>();const blank=():ApplicationInput=>({code:'',name:'',description:'',status:'draft',department_ids:[],draft_config:{model:'',prompt_template_id:'',knowledge_base_ids:[],tool_ids:[],retrieval_top_k:4,temperature:.2,max_tool_rounds:3}});const form=reactive<ApplicationInput>(blank());async function load(){loading.value=true;try{[items.value,prompts.value,knowledge.value,tools.value]=await Promise.all([fetchApplications(),fetchPrompts(),fetchKnowledgeBases(),fetchTools()])}finally{loading.value=false}}function openCreate(){editing.value='';Object.assign(form,blank());visible.value=true}function openEdit(row:Application){editing.value=row.id;Object.assign(form,{code:row.code,name:row.name,description:row.description,status:row.status,department_ids:[...row.department_ids],draft_config:{...row.draft_config,knowledge_base_ids:[...row.draft_config.knowledge_base_ids],tool_ids:[...row.draft_config.tool_ids]}});visible.value=true}async function save(){editing.value?await updateApplication(editing.value,form):await createApplication(form);visible.value=false;await load();ElMessage.success('草稿已保存')}async function publish(row:Application){const{value}=await ElMessageBox.prompt('填写本次发布说明','发布应用',{inputPlaceholder:'例如：接入新版知识库'});await publishApplication(row.id,value||'');ElMessage.success('已发布不可变版本');await load()}async function remove(row:Application){await ElMessageBox.confirm(`删除应用“${row.name}”？`,'确认',{type:'warning'});await deleteApplication(row.id);await load()}async function inspect(row:Application){selected.value=row;[versions.value,runs.value]=await Promise.all([fetchApplicationVersions(row.id),fetchApplicationRuns(row.id)]);inspectVisible.value=true}onMounted(load)</script>
