docs: 工作台设计稿收入 docs 体系,routes.go 更名 ai_routes.go

7 份散落在 frontend/src/views/workbench/ 的设计稿按现有编号体系收入 docs/,
源码目录现在只剩 12 个 .vue 页面:

  PlatformArchitectureRethink       -> docs/01_System_Overall/SY24
  WorkbenchArchitectureContract     -> docs/02_Architecture/AR05
  SkillPackagingSpecification       -> docs/02_Architecture/AR06
  ArchitectureAlignmentAudit        -> docs/02_Architecture/AR07
  RoleInteractionDesign             -> docs/02_Architecture/AR08
  YunQuParityRoadmap_OfficePlatform -> docs/06_Product_Lines/PL04
  WorkBuddySkillRpaLearning         -> docs/09_Research/RS01

14 处交叉引用同步更新(含 SY20/SY21 里指向旧源码路径的两处);三份 README 索引
补齐 SY20-SY24 与 AR05-AR08、PL04;README 顶部「本目录全是历史快照」的说法改精确
(AR05-AR08、PL04 不属于 V1.1 / V1 快照)。

AR08 文首补注「采纳与废弃」,避免它被当成现行设计照做:
- 已采纳:对象不跳页 / 不做独立工具页 / + 菜单挂载 / 切换对象=更新任务上下文
- 已废弃:「数字技术员」第三类对象(SY21 §2.2 已废除 tool 命名)、
  「通用助手 = 默认专员」、§14「与本稿冲突以本稿为准」的自我授权

backend-go: internal/api/routes.go -> ai_routes.go。该文件管的是 AI 模型路由
(LLM provider 列表),与 router.go 的 URL 路由注册同包同名易混,加文件头注释钉死。

验证:go build ./... 通过;go vet ./internal/api/ 无告警;npm run build 通过。

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
eaiadmin
2026-09-17 19:26:26 +08:00
co-authored by Claude Code
parent 24cac4de6e
commit fa6c26ea41
16 changed files with 5735 additions and 55 deletions
@@ -0,0 +1,120 @@
// ai_routes.go —— 「AI 模型路由」的查询接口(LLM provider / model 列表)。
//
// 注意与 router.go 区分:router.go 是 URL 路由注册(gin 的 r.GET/r.POST),
// 本文件里的 "route" 一律指 AI 模型路由,与 HTTP 路由无关。
package api
import (
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/web"
"time"
"github.com/gin-gonic/gin"
)
// routeItem AI 模型路由摘要(返回给前端选择器)
type routeItem struct {
AIRouteID string `json:"ai_route_id"`
Provider string `json:"provider"`
Model string `json:"model"`
BaseURL string `json:"base_url"`
Description string `json:"description"`
ShortRouteName string `json:"short_route_name,omitempty"`
ShortModelName string `json:"short_model_name,omitempty"`
Healthy bool `json:"healthy"`
Checked bool `json:"checked"`
LatencyMs int64 `json:"latency_ms,omitempty"`
LastCheckedAt string `json:"last_checked_at,omitempty"`
LastError string `json:"last_error,omitempty"`
ResolvedAIRouteID string `json:"resolved_ai_route_id,omitempty"`
}
func toRouteItems(routes []*config.RouteConfig) []routeItem {
items := make([]routeItem, 0, len(routes))
for _, r := range routes {
health, _ := config.GetRouteHealth(r.RouteID)
items = append(items, routeItem{
AIRouteID: r.RouteID,
Provider: r.Provider,
Model: r.Model,
BaseURL: r.BaseURL,
Description: r.Description,
ShortRouteName: r.ShortRouteName,
ShortModelName: r.ShortModelName,
Healthy: health.Healthy,
Checked: health.Checked,
LatencyMs: health.LatencyMs,
LastError: health.LastError,
LastCheckedAt: formatCheckedAt(health.LastCheckedAt),
})
}
return items
}
func autoRouteItem(routeID string, category string) routeItem {
item := routeItem{
AIRouteID: routeID,
Description: "自动选择当前最优可用模型",
ShortRouteName: "自动",
ShortModelName: "检测中",
}
resolved, err := config.GetRoute(routeID)
if err == nil && resolved != nil {
health, _ := config.GetRouteHealth(resolved.RouteID)
item.Provider = resolved.Provider
item.Model = resolved.Model
item.BaseURL = resolved.BaseURL
item.ShortModelName = resolved.ShortModelName
if item.ShortModelName == "" {
item.ShortModelName = "优选"
}
item.ResolvedAIRouteID = resolved.RouteID
item.Description = "自动选择当前最优可用模型"
if resolved.Description != "" {
item.Description += " · 当前 " + resolved.Description
}
item.Healthy = health.Healthy
item.Checked = health.Checked
item.LatencyMs = health.LatencyMs
item.LastError = health.LastError
item.LastCheckedAt = formatCheckedAt(health.LastCheckedAt)
return item
}
if category == "embed" {
item.ShortModelName = "Emb"
}
return item
}
func formatCheckedAt(t time.Time) string {
if t.IsZero() {
return ""
}
return t.Format(time.RFC3339)
}
// ListChatRoutes 返回可用 chat 路由列表(供前端选择器使用)
func ListChatRoutes(c *gin.Context) {
routes, err := config.GetRoutesByCategory("chat")
if err != nil {
web.Fail(c, web.NewLLMNotConfigured("路由加载失败: "+err.Error()))
return
}
items := []routeItem{autoRouteItem(config.AutoChatRouteID, "chat")}
items = append(items, toRouteItems(routes)...)
web.OK(c, gin.H{"routes": items})
}
// ListEmbedRoutes 返回可用 embedding 路由列表
func ListEmbedRoutes(c *gin.Context) {
routes, err := config.GetRoutesByCategory("embed")
if err != nil {
web.Fail(c, web.NewLLMNotConfigured("路由加载失败: "+err.Error()))
return
}
items := []routeItem{autoRouteItem(config.AutoEmbedRouteID, "embed")}
items = append(items, toRouteItems(routes)...)
web.OK(c, gin.H{"routes": items})
}
@@ -1,51 +0,0 @@
package api
import (
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/web"
"github.com/gin-gonic/gin"
)
// routeItem 路由摘要(返回给前端选择器)
type routeItem struct {
ID string `json:"id"`
Provider string `json:"provider"`
Model string `json:"model"`
BaseURL string `json:"base_url"`
Description string `json:"description"`
}
func toRouteItems(routes []*config.RouteConfig) []routeItem {
items := make([]routeItem, 0, len(routes))
for _, r := range routes {
items = append(items, routeItem{
ID: r.RouteID,
Provider: r.Provider,
Model: r.Model,
BaseURL: r.BaseURL,
Description: r.Description,
})
}
return items
}
// ListChatRoutes 返回可用 chat 路由列表(供前端选择器使用)
func ListChatRoutes(c *gin.Context) {
routes, err := config.GetRoutesByCategory("chat")
if err != nil {
web.Fail(c, web.NewLLMNotConfigured("路由加载失败: "+err.Error()))
return
}
web.OK(c, gin.H{"routes": toRouteItems(routes)})
}
// ListEmbedRoutes 返回可用 embedding 路由列表
func ListEmbedRoutes(c *gin.Context) {
routes, err := config.GetRoutesByCategory("embed")
if err != nil {
web.Fail(c, web.NewLLMNotConfigured("路由加载失败: "+err.Error()))
return
}
web.OK(c, gin.H{"routes": toRouteItems(routes)})
}