diff --git a/.claude/skills/hugagent-backend-dev/references/api-envelope.md b/.claude/skills/hugagent-backend-dev/references/api-envelope.md index 841012ce..a0d9525c 100644 --- a/.claude/skills/hugagent-backend-dev/references/api-envelope.md +++ b/.claude/skills/hugagent-backend-dev/references/api-envelope.md @@ -78,4 +78,8 @@ return error_response(code=20001, message="Bad request", status_code=400) 1. **路由中只用 `success_response` / `created_response` / `paginated_response`** 2. **错误通过抛 `AppException` 子类,由全局 handler 转 `error_response`** 3. **trace_id 默认自动生成,无需手动传** -4. **SSE 端点(流式聊天)不使用信封,直接发 SSE 事件** +4. **SSE 端点不使用信封**:用 `sse_response(generator, extra_headers=...)` 返回(自带 `Cache-Control: no-cache`、 + `X-Accel-Buffering: no` 等 `SSE_HEADERS`);聊天回合的 SSE 输出统一走 `api/transports/run_sse.py`,不要自写一套 +5. **License 402** 只来自 `edition_ee/licensing/features.py` 的 `FeatureNotLicensed`(40201)/ `SeatLimitExceeded`(40202), + 路由与服务层不要手搓 402 +6. 时间字段序列化用 `.isoformat()`(模型存的是带时区的 UTC),不要输出无时区字符串 diff --git a/.claude/skills/hugagent-backend-dev/references/architecture.md b/.claude/skills/hugagent-backend-dev/references/architecture.md index 5fda6ac0..306f4283 100644 --- a/.claude/skills/hugagent-backend-dev/references/architecture.md +++ b/.claude/skills/hugagent-backend-dev/references/architecture.md @@ -1,129 +1,164 @@ # 后端架构参考 -## 请求流转 +## 1. 顶层布局与依赖方向 ``` -Browser → Nginx (:3000 /api/ proxy) → FastAPI (api/app.py) - → api/middleware/ (CORS → Logging → Error Handler → license_gate) - → api/routes/v1/*.py (路由层;CE 注册表 api/routes/v1/__init__.py,EE 注册表 edition_ee/routes/registry.py) - → core/services/*.py (服务层 — 业务逻辑) - → core/db/repository/ (仓库层 — 数据访问,按领域分文件) - → core/db/models/ (ORM 包 → PostgreSQL/SQLite) +src/backend/ +├── api/ HTTP 协议层:app.py(组装)、deps.py、middleware/、routes/v1/(CE_ROUTERS)、transports/run_sse.py、startup/ +├── core/ 内核:领域逻辑与可复用运行时(不导入 features / integrations / personal_agent / orchestration) +├── orchestration/ 模式编排:plans/、loops/、automations/、workers/(周期任务与恢复) +├── features/ 可安装的产品功能模块(各自 README + extension.py + models.py + api/) +├── integrations/ 外部系统集成:channels(IM 机器人框架)、dingtalk、lark、email、yida、api +├── personal_agent/ Personal Agent 模块(同样经 extension.py 接入) +├── edition_ee/ 商业版专属:路由注册表、License、Team/RBAC、EE 表、KB provider、EE 服务(CE 树物理删除) +├── extensions/ 随包资源:skills/、agents/、plugins/(default + marketplace)、mcp_servers/;根路径唯一来源 paths.py +├── prompts/ 提示词装配运行时 + prompt_text/ 文件兜底 +├── hugagent_cli/ 命令行客户端 +├── alembic/ 迁移(EE 主链;CE 用独立 ce_0001 基线) +└── tests/ pytest(按领域子目录:api/ chat/ core/ features// infra/ llm/ orchestration/ …) ``` -## 分层职责 +``` +api ──► orchestration ──► core + │ │ ▲ + └──► features / integrations / personal_agent ──┘ (通过 core.harness.registry 注册钩子接入) +edition_ee ──► core / features (CE 派生树中不存在) +``` + +- **core 永远不导入功能模块的实现**。功能模块在 `extension.setup()` 里调用 `core.harness.registry.register_*` 把能力挂进来; + 关闭时什么也不注册,core 的行为等同于未安装。 +- **不保留转发垫片**:模块搬家时直接改所有调用方的 import,不留旧路径 re-export(ADR 20261021)。 +- 单个模块 ≤ 500 行(存量超限文件已登记为例外,不要新增)。 + +## 2. core/ 子包职责 + +| 子包 | 职责 | +|---|---| +| `agent_runtime/` | 一次普通智能体回合:`runner.astream_chat_workflow` 选主智能体 / 直连路径;`prepare_*`(建 agent、组装输入)、`stream_*`(模型与工具事件 → 既有事件协议)、`*_state`(单轮有类型状态)、`integrations/`(记忆、压缩、本体证据/修复、演化) | +| `runs/` | 持久化执行所有权:租约 / 心跳、取消、事件日志与续播(`events/`)、看门狗、工具副作用账本(`tool_effects/`)、恢复 | +| `chat/` | 会话与消息读写、模式(modes)、分叉、引用、追问、压缩;`runtime/`(聊天 worker:消费回合事件、在 runs 租约下持久化输出、排队 / 插话 / 暂停 / 恢复);`operations/`、`projection/` | +| `llm/` | AgentScope 适配与智能体装配:`factory/`(build / assembly / tools / prompts)、`runtime/`(流式循环、钩子适配、工具执行、人机交互)、`citations/`(锚点发号)、`mcp/`、`subagents/`、`tools/`、`tool_permissions/`、提示词版本池 | +| `models/` | 模型供应商与选择:chat_models、providers、failover、reasoning effort、embedding / reranking、vision、用量 | +| `capabilities/` | 能力生命周期:`catalog/`、`skills/`、`plugins/`(含插件资源)、`mcp/`、`agents/`、manifest 协议 | +| `harness/` | 宿主接缝:`registry/`(功能模块注册钩子的唯一入口)、执行清单、观测事件、日志写入、用量 | +| `auth/` | `backend.py`(`get_current_user` / `UserContext`)、`bearer.py`(mock/remote Bearer 异步校验 + 共享缓存)、session、本地账号、API Key、能力位、权限接口 | +| `db/` | `engine.py`(Base / SessionLocal / `get_db` / 线程预算)、`threads.py`(`run_db` / `run_in_session` / `off_loop`)、`models/`(核心 ORM 包)、`repository/`、`utc_datetime.py`、各类升级 / 修复脚本 | +| `config/` | `settings.py`(`settings` 冻结 dataclass:deploy / auth / sso / db / llm / memory / storage / kb / redis / server / sandbox / edition / branding …)、`catalog.json`、`mcp_config.py`、`display_names.py`、`runtime_env.py` | +| `infra/` | `responses.py`、`exceptions.py`、`logging.py`、`time.py`(`utc_now`)、`background.py`(`spawn`)、redis、metrics、限流 / 熔断、leader 选举、加密、脱敏 | +| `files/` | 产物(artifacts)、内容解析(content)、空间文件(spaces)、存储协议(storage:local / s3 / oss) | +| `projects/` | 项目、项目环境、指令、本地工作区、个人项目作用域 | +| `memory/` | 分层记忆(L1 画像 / L2 向量 / L3 图谱)、抽取流水线、outbox、脱敏、TTL | +| `ontology/` | 本体治理:schema、校验、运行时闸门、输出评审、修订 | +| `evolution/` | 协同进化共享契约与证据(控制面在 EE) | +| `jobs/` | 后台作业运行时(作业 SDK、监督、通知、文件) | +| `sandbox/` | 沙箱协议 / 工厂 / providers(script_runner、opensandbox、cube[EE])、runner 进程服务、进程 / 会话 / 工作区 / 权限 / OS 隔离 | + +## 3. 功能模块(features / integrations / personal_agent) + +`features/installed.py::INSTALLED_FEATURES` 是全量安装清单(CE 由 `ce/overlay/src/backend/features/installed.py` 覆盖)。 + +| 模块 | 内容 | +|---|---| +| `features/automation` | 定时任务:调度、执行、投递目标、通知、远程副作用 | +| `features/knowledge` | 自建知识库:解析、分块、向量、资产索引、Wiki;外部 provider 接缝 | +| `features/marketplace` | 技能 / 智能体 / MCP 市场:目录、安装、发布、版本、导出 | +| `features/workbench` | 可扩展工作台:应用目录、外部应用 / 嵌入 / 外部认证、插件 UI、资源实例、偏好、诊断、迁移 | +| `features/hosted_apps` | 托管业务应用(SQL / MCP):部署、数据、发布、资源 | +| `features/sites` | 站点托管与发布(静态服务、访问密码、打包、本机发布) | +| `features/desktop` | 桌面双端:能力桥、网关、本机能力、登录桥接、可观测性 | +| `features/evaluation` | 评测沙箱(严格 OpenSandbox) | +| `features/distillation` · `security_console` · `datasources` · `sandbox_ops` | EE:技能 / 人格蒸馏、安全台、数据源、沙箱运维 | +| `integrations/channels` + `dingtalk` / `lark` / `email` / `yida` | 入站渠道机器人框架与各平台适配 | +| `personal_agent` | Personal Agent:会话、渠道、调度、投递、设备连接、工作区人格 | + +模块约定: ``` -┌─────────────────────────────────────────┐ -│ Routes (api/routes/v1/) │ ← HTTP 入口、参数校验、响应包装 -│ - 依赖注入: auth, db │ -│ - Pydantic 请求模型 │ -│ - _to_dict() 转换函数 │ -│ - 调用 Service │ -├─────────────────────────────────────────┤ -│ Services (core/services/) │ ← 业务逻辑、权限校验、审计 -│ - 构造函数接收 db: Session │ -│ - 内部创建 Repository │ -│ - 幂等操作 (ensure_xxx) │ -│ - 抛 AppException │ -├─────────────────────────────────────────┤ -│ Repository (core/db/repository/) │ ← 数据访问抽象(包,10 个领域文件) -│ - CRUD 操作 │ -│ - 分页查询 │ -│ - 软删除过滤 │ -│ - 不含业务逻辑 │ -├─────────────────────────────────────────┤ -│ Models (core/db/models/) │ ← ORM 定义(包,17 个领域文件) -│ - SQLAlchemy declarative │ -│ - 索引、约束、关系 │ -│ - EE 专属表登记 edition_ee/db/edition_tables.py │ -│ - Alembic 迁移 │ -└─────────────────────────────────────────┘ +features// +├── README.md 负责什么、公开入口、依赖方向、版本差异 +├── extension.py NAME + setup() -> bool;可选 register_tools / register_gateway_contributions / +│ register_catalog_options / register_retrieval_context +├── models.py ORM(按安装清单加载,与运行开关无关) +├── edition.py (可选)CE/EE 差异唯一入口,CE overlay 只覆盖它 +├── service.py / repository.py / <领域>.py +└── api/ 路由文件(多数进 CE_ROUTERS / EE_ROUTERS,可关闭的由 setup() 内 register_router 挂载) ``` -## 聊天流式请求流转 +## 4. 启动与路由装配(api/app.py) + +1. `orchestration.configuration.register_configuration()`、`features.register_run_capabilities()`、 + `register_model_credentials()`、`integrations.register_credentials()` +2. 挂 health、`api/routes` 文件下载路由 +3. `iter_edition_routers(CE_ROUTERS)` 全部 include;`iter_edition_routers(EE_ROUTERS)` include 并附加 + `edition_router_dependencies(policy_key)`(License 能力位,未授权 402) +4. `register_product_tools()` / `register_catalog_options()` / `register_package_sources()` / `register_resource_owners()` +5. `load_extensions(INSTALLED_FEATURES)`:先 `load_models`,再逐个 `.extension.setup()`;然后挂 + `core.harness.registry.routers()` 里登记的模块路由 +6. `sites_serve_router`(静态站点兜底)→ 登录路由 → mock SSO(按登录模式)→ 本地模式前端静态托管(最后) + +注册表规则: + +- `CE_ROUTERS`(`api/routes/v1/__init__.py`):二元组 `(module, attr)`;短名解析为 `api.routes.v1.`, + 含点号的写绝对路径(`"features.sites.api.sites"`)。**顺序即注册顺序**,同前缀族的先后有语义(例:`plugin_ui` 必须在 + `plugins` 之前,否则 `/v1/plugins/{slug}` 会吞掉 `/v1/plugins/ui-contributions`) +- `EE_ROUTERS`(`edition_ee/routes/registry.py`):三元组 `(module, attr, policy_key)`;`policy_key` 取 + `edition_ee/licensing/features.py::Feature` 的值(`content_admin` / `audit` / `multi_tenancy` / `system_config` / + `billing` / `model_gateway` / `evolution_control` …);`None` 仅用于 License 失效时也必须可达的入口(登录、换证) +- `api.edition.EE_ROUTERS` 是懒加载接缝;CE overlay 把它换成空表 +- **不要**在 `app.py` 手工 `include_router()` + +## 5. 一次聊天回合的流转 ``` -POST /v1/agents/responses - → api/routes/v1/chats/__init__.py - → orchestration/chat_run_executor.py # ChatRun + Redis Stream(后台 run,SSE 跟随,断线续播) - → orchestration/workflow.py # 流式编排主入口 - → core/chat/modes.py # 解析对话模式 ChatModeSpec(standard/turbo/市场模式;装配契约) - → orchestration/memory_integration.py # 检索分层记忆并注入(user-role 冻结块,600ms 预算) - → core/llm/factory/build.py # 构建 AgentScope 2.0 ReActAgent(按 ChatModeSpec 收窄工具面) - → core/llm/mcp/manager.py # MCP 客户端池(streamable-http → mcp 容器) - → core/config/mcp_config.py # MCP server 定义(端口真源 mcp_servers/_ports.py) - → core/llm/middlewares.py # AS2 中间件(动态模型、文件上下文、CitationAnchorMiddleware、OntologyGateMiddleware) - → prompts/prompt_runtime.py # 装配系统提示词(DB 版本池优先,prompt_text/ 兜底) - → orchestration/streaming.py # StreamingAgent:把 AS2 事件流映射为内部块事件 - → orchestration/citation_anchor.py # 引用锚点唯一发号(AnchorAllocator,e1/e2/…,经中间件回注工具结果) - → core/memory/service.py # 流结束后后台保存记忆(L1/L2/L3) - → orchestration/followups.py # 流结束后后台生成追问建议(写入消息 extra_data) +POST /v1/agents/responses api/routes/v1/agent_responses.py(+ chats/ 子路由) + → 准入与回合登记 core/chat/runtime/admission.py · core/runs(租约、事件日志) + → 聊天 worker core/chat/runtime/worker.py(消费事件、按顺序持久化输出) + → core/agent_runtime/runner.astream_chat_workflow + → prepare_main / prepare_direct 建 agent、组装输入(模式 core/chat/modes.py、记忆 integrations/memory.py) + → core/llm/factory/build.py AgentScope agent:模型选择、工具集、MCP(core/llm/mcp)、技能、提示词 + → stream_main / stream_direct 模型与工具事件 → 事件协议(core/llm/runtime/streaming.py、stream_events.py) + → core/llm/citations/ 引用锚点发号(e1/e2…) + → 结束后:本体评审、记忆 / 演化结算、追问(core/chat/runtime/followups.py) + → SSE 输出 api/transports/run_sse.py(跟随事件日志;续播 GET /v1/chats/stream/{run_id}/subscription) ``` -> `orchestration/strategy.py` 仍在但已退化为占位符(两个分支都返回 MainOnlyStrategy),不再是主链路环节。 - -**平级编排入口**(不走普通 chat run 的独立驱动): - -| 入口 | 文件 | 说明 | -|------|------|------| -| 自主循环 | `orchestration/autonomous_loop.py` + `loop_planner.py` / `loop_evaluator.py` + `subagents/loop_reviewer.py` | driver 持有需求台账 feature_list.json,逐条注入 + 只读 reviewer 验收;路由 `v1/loops.py` | -| 批量执行 | `orchestration/batch_orchestrator.py` | batch_confirm 确认后逐行执行 | -| 计划模式 | `orchestration/subagents/plan_mode.py` | plan_generate / plan_execute run | -| 渠道入站 | `core/channels/`(protocol/registry/manager/inbound/outbound) | IM 消息归一为 InboundMsg 后复用聊天编排,回复经 markdown.py 降级回发 | -| 定时任务 | `orchestration/schedulers/`(automation / distillation_cron / evolution / memory_ttl) | croniter 调度 | - -SSE 事件(前端解析真源 `src/frontend/src/hooks/chatStream.ts`): - -- 生命周期:`run_started`(首帧,携带续播 run_id)、`meta`、`error`、`end` / `data: [DONE]`(终止)、心跳为 SSE 注释行 -- 正文/思考:`content`(delta 增量;别名 ai_message/text/delta)、`content_replace`、`thinking`、`compaction_notice`、`steer_applied` -- 工具:`tool_call_start`、`tool_call_delta`(参数流式)、`tool_call`、`tool_result`、`tool_pending`、`model_progress`(活性信号) -- 交互确认:`batch_confirm`、`file_confirm`、`design_pick` -- 计划/子智能体:`plan_update`、`subagent_event` -- 本体治理:`ontology_activation` / `ontology_gate` / `ontology_review` / `ontology_repair` / `ontology_revision` / `ontology_revision_thinking` - -断线续播:`GET /v1/chats/stream/{run_id}`。追问建议(follow_up_questions)流结束后后台生成,也可能以 `follow_up` 事件流内直送。 - -## 模块索引 - -| 模块 | 路径 | 职责 | -|------|------|------| -| App 入口 | `api/app.py` | FastAPI 实例、中间件;路由按注册表自动注册 | -| CE 路由注册表 | `api/routes/v1/__init__.py` | **CE_ROUTERS 单一真源**(二元组);re-export EE_ROUTERS | -| EE 路由注册表 | `edition_ee/routes/registry.py` | **EE_ROUTERS 单一真源**(三元组,带 license 能力位) | -| 依赖注入 | `api/deps.py` | require_admin(ADMIN_TOKEN)、require_config(CONFIG_TOKEN)、require_admin_or_config、require_system_settings、require_super_admin | -| 用户认证 | `core/auth/backend.py` | get_current_user / UserContext(桌面桥接 → session → API-Key → mock/remote) | -| 健康检查 | `api/health.py` | /health, /ready, /live | -| Schema | `api/schemas.py` | 请求/响应 Pydantic 模型 | -| 路由 | `api/routes/v1/` | 66 个路由文件 | -| 技能引擎 | `core/capabilities/skills/` | SKILL.md 解析、多源加载、{dir} 沙箱路径注入 | -| 生成物 | `core/files/artifacts/` | 注册与下载(store.py,local/oss 双模) | -| 认证 | `core/auth/` | backend.py, session.py, sso.py, permissions_iface.py(CE/EE 接缝) | -| 渠道 | `core/channels/` | 入站机器人框架:钉钉/飞书/企微/微信 adapter;加渠道 = 写 adapter + registry.py 注册 | -| 聊天 | `core/chat/` | context.py, tool_log.py | -| 配置 | `core/config/` | settings.py + catalog 五件套(catalog.json/catalog.py/loader/resolver/migration)+ mcp_config.py | -| 内容 | `core/files/content/` | 内容块、file_parser.py | -| 数据库 | `core/db/` | engine.py, models/(17 领域文件), repository/(10 领域文件), model_extensions.py, edition_tables.py(垫片) | -| 进化 | `core/evolution/` | GCE 共享契约(Episode/候选/结算);控制面在 edition_ee/evolution | -| 基础设施 | `core/infra/` | exceptions, responses, logging, metrics, 限流, Redis, crypto | -| 知识库 | `core/kb/` | 分块、向量化、混合检索 + wiki/(LLM-Wiki 管线)+ wiki_router.py + external_provider.py(外接接缝) | -| License | `core/licensing/` | features.py(能力位+402)、manager.py(状态机) | -| LLM | `core/llm/` | agent_factory(含 turbo 参数), chat_models, middlewares, mcp_manager/mcp_pool, offloader, subagent_tool, tools/ | -| 记忆 | `core/memory/` | service.py(mem0)、pipeline.py、profile.py(L1)、sanitizer.py、audit.py | -| 本体 | `core/ontology/` | Domain Pack 校验、运行时选取、工具闸(schemas/validator/revision/toolkit) | -| 沙箱 | `core/sandbox/` | protocol.py + script_runner / opensandbox / cube 三实现 | -| 服务 | `core/services/` | 70+ 业务服务(user/chat/chat_mode/channel/loop/kb/plugin/prompt_version/marketplace…) | -| 存储 | `core/files/storage/` | protocol, local, s3, oss | -| 编排 | `orchestration/` | workflow, chat_run_executor, streaming, citation_anchor, autonomous_loop, followups, batch_orchestrator, schedulers/, subagents/ | -| 提示词 | `prompts/` | prompt_runtime + provider + prompt_text/{default,code_exec,distillation,plan_mode,subagents,turbo}/ | -| MCP 服务器 | `mcp_servers/` | 12 个 server 目录、11 个在役(端口 9100–9114,真源 _ports.py;9105/9109-9111 为退役保留位) | -| 技能资产 | `skill_bundles/` | default/(5 内置)+ marketplace/(40+ 可安装) | -| EE 树 | `edition_ee/` | EE 专属路由/模型/KB provider(dify/fastgpt/weknora)/evolution 控制面;CE 派生树物理删除 | - -## 新路由注册步骤 - -1. 创建 `api/routes/v1/my_feature.py`(EE 专属则放 `edition_ee/routes/`),文件内定义 `router = APIRouter(prefix="/v1/xxx", tags=["Xxx"])` -2. 注册进对应注册表: - - 通用功能 → `api/routes/v1/__init__.py` 的 `CE_ROUTERS` 加 `("my_feature", "router")` - - 企业版功能 → `edition_ee/routes/registry.py` 的 `EE_ROUTERS` 加 `("edition_ee.routes.my_feature", "router", "")`(能力位 `None` 表示显式豁免 feature 守卫) -3. **不要**在 `api/app.py` 手工 `include_router()` —— app 启动时经 `iter_edition_routers()` 按表自动注册,模块缺失(CE 派生树物理删除了 EE 文件)会被静默跳过 +平级编排入口(不走普通回合): + +| 入口 | 位置 | +|---|---| +| 计划模式 | `orchestration/plans/`(generate_run / execute_run / mode) | +| 自主循环 | `orchestration/loops/`(driver / planner / reviewer / requirements / recovery) | +| 定时任务派发 | `orchestration/automations/` + `features/automation` | +| 周期任务 / 恢复 | `orchestration/workers/`(`_worker_base.py`、run_recovery、memory_ttl、evolution、蒸馏 cron) | +| 渠道入站 | `integrations/channels/`(归一为入站消息后复用聊天回合) | + +## 6. 数据访问与事件循环 + +- 同步 SQLAlchemy Session 的每次查询都是阻塞 I/O。 +- **只用 Session 不 await 的路由写 `def`**(FastAPI 线程池执行);`def` 路由里没有事件循环,不能 `create_task` / `get_running_loop`。 +- **要 await 网络的 async 代码不持有 Session**:每段 DB 工作写成同步函数,用 `await run_in_session(fn, ...)`(新开并关闭会话) + 或 `await run_db(fn, ...)`(已有会话)在线程里跑;需要 async 接口的纯 DB 函数用 `@off_loop` 包装。 +- 线程池与连接池按 `core.db.engine.thread_budget()` 同一预算配置(`apply_thread_budget()`)。 +- 跨请求存活的工作:落库交给 worker(`orchestration/workers/_worker_base.py`);事件循环上的临时任务用 `core.infra.background.spawn(coro, name=...)`。 +- 守卫测试:`tests/test_no_blocking_async_routes.py`、`tests/test_no_event_loop_in_sync_routes.py`、 + `tests/infra/test_no_session_on_event_loop.py`(全仓零例外:任何 async 函数都不收 `db` / `Session` / `Depends(get_db)`、 + 不调 `SessionLocal()`、不 `with … as db`;测试里覆盖 `get_db` 时同时用 `tests/db_support.py` 让 `run_in_session` 指向同一个库)。 + +## 7. 模块索引(常用入口) + +| 主题 | 路径 | +|---|---| +| 应用组装 | `api/app.py`、`api/lifecycle.py`、`api/startup/` | +| 路由注册表 | `api/routes/v1/__init__.py`(CE)、`edition_ee/routes/registry.py`(EE)、`core/harness/registry`(模块路由) | +| 依赖注入 | `api/deps.py`(require_admin / require_config / require_admin_or_config / require_system_settings / require_ontology_governance / require_super_admin / console_actor) | +| 认证 | `core/auth/backend.py`(get_current_user / UserContext)、`core/auth/bearer.py` | +| DB | `core/db/engine.py`(get_db)、`core/db/threads.py`、`core/db/models/`、`core/db/repository/` | +| 信封 / 异常 | `core/infra/responses.py`、`core/infra/exceptions.py`、`api/middleware/error_handler.py` | +| 配置 | `core/config/settings.py`、`core/config/catalog.json` | +| 智能体回合 | `core/agent_runtime/`、`core/llm/factory/`、`core/llm/runtime/` | +| 运行与续播 | `core/runs/`、`core/chat/runtime/`、`api/transports/run_sse.py` | +| MCP 服务 | `extensions/mcp_servers/`(`registry.py`、`_ports.py` 端口稳定契约、`_launcher.py`)、`core/config/mcp_config.py` | +| 技能 / 插件 / 智能体资源 | `extensions/{skills,plugins,agents}/{default,marketplace}`、`core/capabilities/` | +| 提示词 | `prompts/prompt_runtime.py`(DB 版本池优先,`prompt_text/` 兜底)、`core/llm/prompt_*.py` | +| License | `edition_ee/licensing/`(features / deps / gate / manager)、`api/middleware/edition.py` | +| CE 派生 | `ce/manifest.yaml`(排除)、`ce/overlay/`(覆盖接缝文件) | diff --git a/.claude/skills/hugagent-backend-dev/references/error-codes.md b/.claude/skills/hugagent-backend-dev/references/error-codes.md index 18149924..73d26851 100644 --- a/.claude/skills/hugagent-backend-dev/references/error-codes.md +++ b/.claude/skills/hugagent-backend-dev/references/error-codes.md @@ -35,6 +35,8 @@ |------|------|----------------|------| | 40001 | 404 | `ResourceNotFoundError` | 资源未找到 | | 40002 | 404 | `EndpointNotFoundError` | API 端点不存在 | +| 40201 | 402 | `FeatureNotLicensed`(`edition_ee/licensing/features.py`) | License 未授权该能力(EE 路由能力位守卫) | +| 40202 | 402 | `SeatLimitExceeded`(同上) | 席位不足 / License 无效,无法新增用户 | | 41001 | 409 | `ResourceAlreadyExistsError` | 资源已存在 | | 41002 | 409 | `ConcurrentModificationError` | 并发修改冲突 | | 42001 | 429 | `RateLimitExceededError` | 速率限制 | diff --git a/.claude/skills/hugagent-backend-dev/scripts/scaffold_feature.sh b/.claude/skills/hugagent-backend-dev/scripts/scaffold_feature.sh index 313654df..ff2ca623 100755 --- a/.claude/skills/hugagent-backend-dev/scripts/scaffold_feature.sh +++ b/.claude/skills/hugagent-backend-dev/scripts/scaffold_feature.sh @@ -1,83 +1,108 @@ #!/usr/bin/env bash # -# 后端新功能脚手架生成器 +# 后端功能模块脚手架:生成 features// 完整骨架 # # 用法: -# bash .claude/skills/hugagent-backend-dev/scripts/scaffold_feature.sh +# bash .claude/skills/hugagent-backend-dev/scripts/scaffold_feature.sh # # 示例: # bash .claude/skills/hugagent-backend-dev/scripts/scaffold_feature.sh bookmark Bookmark bookmarks # -# 生成文件: -# - src/backend/api/routes/v1/s.py (路由) -# - src/backend/core/services/_service.py (服务) -# - src/backend/tests/test_.py (测试) +# 生成: +# src/backend/features//__init__.py +# src/backend/features//README.md 职责、公开入口、依赖方向 +# src/backend/features//extension.py NAME + setup() +# src/backend/features//models.py ORM(UTCDateTime + utc_now + JSONType) +# src/backend/features//repository.py +# src/backend/features//service.py +# src/backend/features//api/__init__.py +# src/backend/features//api/s.py 路由(同步 def + run_in_session 示例) +# src/backend/tests/features//__init__.py +# src/backend/tests/features//test_.py # -# 注意: model 和 repository 需手动合并到对应领域文件中 -# - core/db/models/<领域>.py ← 添加 ORM 类(并在包 __init__.py re-export) -# - core/db/repository/<领域>.py ← 添加 Repository 类 -# - api/routes/v1/__init__.py ← 注册进 CE_ROUTERS / EE_ROUTERS 注册表 -# - 运行: alembic revision --autogenerate -m "add ${table_name} table" +# 只建新文件,已存在的文件跳过;不改任何注册表(手动步骤见脚本末尾输出)。 +# 不是所有新功能都该进 features/:先按 SKILL.md「放哪里」判断。 set -euo pipefail -FEATURE="${1:?Usage: $0 }" -FEATURE_CAP="${2:?Usage: $0 }" -TABLE="${3:?Usage: $0 }" +FEATURE="${1:?Usage: $0 }" +FEATURE_CAP="${2:?Usage: $0 }" +TABLE="${3:?Usage: $0 }" +FEATURE_UPPER="$(echo "$FEATURE" | tr '[:lower:]' '[:upper:]')" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" TEMPLATE_DIR="$SCRIPT_DIR/../templates" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../../" && pwd)" BACKEND="$PROJECT_ROOT/src/backend" +PKG="$BACKEND/features/$FEATURE" +TESTS="$BACKEND/tests/features/$FEATURE" -echo "=== HugAgentOS Backend Scaffold ===" -echo "Feature: $FEATURE / $FEATURE_CAP" -echo "Table: $TABLE" -echo "" - -# Route file -ROUTE_FILE="$BACKEND/api/routes/v1/${FEATURE}s.py" -if [ ! -f "$ROUTE_FILE" ]; then +render() { # render