refactor: 专员目录收敛为 6 个,重整 AI 路由与系统管理页
一次性提交当天全部改动(110 个文件)。 **未按 TOP_CODING_RULES.md G14.5「一次提交只装一件事」拆分** —— 用户明确要求 单一提交,此处如实记录,不静默忽略该冲突。 提交前验证:后端 go build / go vet / go test ./... 全绿,前端 npm run build exit 0,/api/health 与管理员 login 均返回 200。 - 专员目录收敛为 6 个:下线 knowledge-operations / process-coordination / presentation-briefing / report-generation 四个专员(前后端 manifest 与 seed 同步删除),新增 general-assistant。专员的归属关系(拥有哪些技能定义、 哪些目录项、提示词与绑定从哪来)改由 specialists/core 的 ownership.go、 prompt_provider.go、binding_provider.go 统一提供,seed 与 admin_handlers 随之内置化,卸载路径统一走 uninstall.go。 - 技能:补齐 text-to-speech 的前端 manifest(后端包在 HEAD 已存在), skillcore/ownership.go 提供与专员对称的归属查询。 - AI 路由:ai_config.json 由 OpenRouter/Ollama 切到 LMUAI / SiliconFlow / llama.cpp 本地路由,ai_secrets.example.json 与部署 env 样例同步新增 SILICONFLOW_API_KEY。 - 系统管理页重整:新增 AiAdminPage、OrganizationManagementPage,删除 AdminOverviewPage、CompanyConfigPage,SystemConfigPage 精简,nav / router / config/workbench.js 同步调整。依 G05.5,开发阶段直接收口到新结构,不留旧路由。 - 新增 internal/objectrefs:统一统计对象(专员 / 技能 / xapp)的运行时引用 (被多少 xapp、项目、任务引用),供管理页做删除前的影响面判断。 - 公众号创作专员:新增 OfficialAccountSpecialistPanel,workflow 与投递链路调整。 - XApp:考试 / 培训 Shell 扩展,XAppDirectoryPage 与 xappDefinition 同步。 - 文档:新增 GW01–GW05 工作台演进系列与 AR12 对话驱动与结构化交互架构; 同步 AR05 / SY17 / SY23 / SY25 / PL04;TOP_CODING_RULES.md 增补 G05.5。 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"eai_agentplatform/backend/internal/jsonutil"
|
||||
"eai_agentplatform/backend/internal/middleware"
|
||||
"eai_agentplatform/backend/internal/web"
|
||||
xappcore "eai_agentplatform/backend/internal/xapps/core"
|
||||
xappdefs "eai_agentplatform/backend/internal/xapps/model"
|
||||
)
|
||||
|
||||
@@ -132,6 +133,16 @@ func validateDefinitionReq(req *definitionReq) *web.AppError {
|
||||
if !jsonutil.ValidateStringArrayJSON(req.TagsJSON) {
|
||||
return web.NewBadRequest("tags_json 必须是字符串数组")
|
||||
}
|
||||
if req.SpecialistKey != "" {
|
||||
if _, found := (dal.SpecialistDAO{}).GetByKey(req.SpecialistKey); !found {
|
||||
return web.NewBadRequest("specialist_key 指向的专员不存在")
|
||||
}
|
||||
}
|
||||
if req.SkillKey != "" {
|
||||
if _, found := (dal.SkillDefinitionDAO{}).GetByKey(req.SkillKey); !found {
|
||||
return web.NewBadRequest("skill_key 指向的技能不存在")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -270,6 +281,10 @@ func DeleteXAppDefinition(c *gin.Context) {
|
||||
web.Fail(c, web.NewNotFoundError("应用定义不存在"))
|
||||
return
|
||||
}
|
||||
if plan := xappcore.BuildRemovePlan(item); plan.Blocked {
|
||||
web.Fail(c, web.NewConflictError("应用仍被运行时对象引用,请先处理 remove-plan 中的关联项"))
|
||||
return
|
||||
}
|
||||
if !xAppDefinitionDAO.Delete(&item) {
|
||||
web.Fail(c, web.NewBadRequest("删除应用定义失败"))
|
||||
return
|
||||
@@ -277,6 +292,28 @@ func DeleteXAppDefinition(c *gin.Context) {
|
||||
web.OK(c, gin.H{"id": id, "deleted": true})
|
||||
}
|
||||
|
||||
func PreviewXAppRemovePlan(c *gin.Context) {
|
||||
id, ok := parseID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
item, found := xAppDefinitionDAO.GetByID(id)
|
||||
if !found {
|
||||
web.Fail(c, web.NewNotFoundError("应用定义不存在"))
|
||||
return
|
||||
}
|
||||
plan := xappcore.BuildRemovePlan(item)
|
||||
web.OK(c, gin.H{
|
||||
"id": item.ID,
|
||||
"key": item.Key,
|
||||
"label": item.Label,
|
||||
"source": item.Source,
|
||||
"state": item.State,
|
||||
"is_builtin": false,
|
||||
"plan": plan,
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
maxFavoriteXAppCount = 24
|
||||
maxRecentXAppCount = 8
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
package xappcore
|
||||
|
||||
import (
|
||||
"eai_agentplatform/backend/internal/objectrefs"
|
||||
xappmodel "eai_agentplatform/backend/internal/xapps/model"
|
||||
)
|
||||
|
||||
type UninstallPreview struct {
|
||||
DefinitionKeys []string
|
||||
CatalogEntries []string
|
||||
Policy SharedReferencePolicy
|
||||
}
|
||||
|
||||
type RemovePlan struct {
|
||||
Key string
|
||||
Label string
|
||||
DefinitionKeys []string
|
||||
CatalogEntries []string
|
||||
Policy SharedReferencePolicy
|
||||
RuntimeRefs objectrefs.XAppRuntimeRefs
|
||||
Blocked bool
|
||||
}
|
||||
|
||||
func BuildUninstallPreview(manifest Manifest) UninstallPreview {
|
||||
meta := manifest.UninstallMeta()
|
||||
return UninstallPreview{
|
||||
@@ -14,3 +29,21 @@ func BuildUninstallPreview(manifest Manifest) UninstallPreview {
|
||||
Policy: meta.ReferencePolicy,
|
||||
}
|
||||
}
|
||||
|
||||
func BuildRemovePlan(item xappmodel.XAppDefinition) RemovePlan {
|
||||
definitionKeys := []string{}
|
||||
catalogEntries := []string{}
|
||||
if item.Key != "" {
|
||||
definitionKeys = []string{"xapp." + item.Key + ".definition"}
|
||||
catalogEntries = []string{"catalog.xapp." + item.Key}
|
||||
}
|
||||
return RemovePlan{
|
||||
Key: item.Key,
|
||||
Label: item.Label,
|
||||
DefinitionKeys: definitionKeys,
|
||||
CatalogEntries: catalogEntries,
|
||||
Policy: "",
|
||||
RuntimeRefs: objectrefs.CollectXAppRuntimeRefs(item.Key),
|
||||
Blocked: false,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user