14 KiB
智能体 · 生成与发布 API
Base URL:http://127.0.0.1:8180(网关)
需求 / 能力说明见:智能体-生成发布-能力说明.md
业务用语:模块。API 路径仍为
/api/v1/apps/...。
智能体默认无需配置app_slugs:启用「生成发布」后可自由发布自建模块;app_slugs仅在需要白名单限制时填写。
禁止在已发布模块的业务库查用户 / 权限。账号绑定只走「首次登记」。
总览
| 步骤 | 方法 | 路径 | 鉴权 |
|---|---|---|---|
| 首次登记 | POST | /api/v1/auth/agent/register |
公开 + register_secret |
| 换票 | POST | /api/v1/auth/token |
公开(client_credentials) |
| 列模块 | GET | /api/v1/apps |
Bearer + 「读取模块」(管理=全部;智能体默认不限制) |
| 登记在建 | PUT | /api/v1/apps/{slug}/draft |
Bearer + 「发布模块」 |
| 读蓝图 | GET | /api/v1/apps/{slug}/blueprint |
Bearer + 「读取模块」 |
| 列模型 | GET | /ai/api/v1/llm/providers |
公开 |
| 生成 | POST | /api/v1/apps/generate |
网关可公开 |
| 发布 | POST | /api/v1/apps/{slug}/publish |
Bearer + 「发布模块」 |
| 公开读(加密路径) | GET | /api/v1/public/m/{token}/blueprint |
公开 |
| 导入 | POST | /api/v1/apps/{slug}/{resource}/import |
Bearer + row.import |
| 抽查 | GET | /api/v1/apps/{slug}/{resource} |
Bearer + row.read |
决策树:
GET /apps(本账号可见模块)
├─ 选中已有模块 slug
│ → GET blueprint(避开已有 page id/route)
│ → generate(生成新页面)
│ → publish mode=add_pages|auto
│ → import
└─ 无合适模块
→ generate(完整多页蓝图)
→ publish mode=create|auto(自定新 slug,无需预授权)
→ import
0. 首次登记
POST /api/v1/auth/agent/register(公开)
宿主第一次接入时调用。必须上传:
| 宿主侧 | API 字段 | 必填 | 说明 |
|---|---|---|---|
| 宇恒 ID | host_key |
是 | 稳定唯一标识,幂等绑定 |
| 名称 | name |
是 | 控制台显示名 |
| — | tenant_id |
否 | 默认 1 |
| — | register_secret |
是 | 与平台注册密钥一致 |
{
"name": "宇恒节点显示名",
"host_key": "<宇恒ID>",
"tenant_id": 1,
"register_secret": "dev-only-change-me"
}
响应含 client_id / client_secret(只返回一次),status 为 pending。
管理员在控制台选角色「生成发布」并启用后即可换票。可访问模块可留空(留空=可自由发布自建模块)。
同一 host_key:pending 重连会轮换 secret;已 active 再 register → 409。
1. 换票
POST /api/v1/auth/token(公开)
{
"grant_type": "client_credentials",
"client_id": "agt_xxx",
"client_secret": "明文密钥"
}
取 access_token。后续列模块 / 读蓝图 / 发布 / 导入须:
Authorization: Bearer <access_token>
权限与模块授权
| 权限 | 用途 |
|---|---|
| 「发布模块」 | 发布模块(必选) |
| 「读取模块」 | 列模块、读蓝图(必选) |
row.import |
灌数(必选) |
row.read |
抽查(建议) |
storage.write / storage.read |
素材(建议) |
推荐角色:生成发布(publisher)。
app_slugs:可选白名单。
- 留空(推荐默认):不限制,智能体可自定 slug 生成/发布
- 填写若干 slug 或
*:仅允许列表内(*=全部)
生成接口经网关可公开;发布与导入须鉴权(角色权限),不强制后台预授权模块。
2. 列出模块(先选目标)
GET /api/v1/apps
需 Bearer + 「读取模块」。
| 调用方 | 可见范围(scope) |
|---|---|
| 管理账号(非 agent) | all:本租户全部(含在建) |
智能体(app_slugs 空或含 *) |
open:不限制 |
| 智能体(配置了白名单) | granted:仅白名单 |
curl -s http://127.0.0.1:8180/api/v1/apps \
-H "Authorization: Bearer <access_token>"
{
"scope": "all",
"items": [
{
"app_id": "...",
"slug": "settlement",
"name": "沉降观测",
"status": "draft",
"status_label": "在建",
"building": true,
"page_count": 4,
"entity_count": 2,
"updated_at": "2026-07-24T08:00:00Z",
"created_at": "2026-07-24T08:00:00Z"
}
]
}
| 情况 | 下一步 |
|---|---|
| 有目标模块(含在建) | 记下 slug → 读蓝图 / 继续生成 → publish |
| 没有 | 选定新 slug → generate → PUT .../draft 登记在建 → publish 上线 |
2.1 登记在建模块
生成蓝图后、正式发布前:
PUT /api/v1/apps/{slug}/draft
Body:{ "blueprint": { ... } }
需 「发布模块」。不跑 DDL;状态为 draft(在建)。已发布模块不可用本接口覆盖。
3. 读取已发布/在建蓝图
GET /api/v1/apps/{slug}/blueprint
需 Bearer + 「读取模块」 + 该模块已授权。
用途:
- 生成新页面前,收集已有
pages[].id/route,避免冲突 - 发布后自检
4. 列出大模型(可选)
GET /ai/api/v1/llm/providers(公开)
兼容:http://127.0.0.1:8180/ai/api/v1/llm/providers
{
"default": "deepseek",
"providers": [
{
"id": "deepseek",
"label": "DeepSeek",
"configured": true,
"default_model": "deepseek-chat",
"models": [{ "id": "deepseek-chat", "label": "deepseek-chat" }]
}
]
}
5. 生成蓝图 / 生成新页面
POST /api/v1/apps/generate
(网关转发 AI;兼容 POST /ai/api/v1/apps/generate)
Content-Type: multipart/form-data
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
prompt |
string | 建议 | 需求描述。已有模块时写清:目标 slug、要新增哪些页面、勿复用已有 id/route |
storage_mode |
string | 否 | schema_per_app(默认)或 database_per_app |
llm_provider |
string | 否 | 默认 deepseek |
llm_model |
string | 否 | 空则用厂商默认 |
excel |
file | 否 | xlsx / csv / json |
data_file |
file | 否 | 同 excel |
images |
file[] | 否 | 界面截图 |
layout_files |
file[] | 否 | 页面 HTML/MHTML |
# 示例:为已有模块生成新页面
curl -s http://127.0.0.1:8180/api/v1/apps/generate \
-F "prompt=目标模块 settlement。已有 page id: dash_main, list_records。请新生成「测点筛选」列表+新建表单,id/route 勿冲突。" \
-F "storage_mode=schema_per_app" \
-F "llm_provider=deepseek" \
-F "llm_model=deepseek-chat" \
-F "excel=@./settlement.xlsx" \
-F "images=@./board_a.png"
成功响应要点:
{
"draft": {
"version": "1.0",
"meta": { "slug": "settlement", "name": "..." },
"entities": [],
"apis": {},
"pages": [],
"storage": {},
"security": {}
},
"warnings": [],
"confidence": 0.86,
"require_confirm": true,
"llm_provider": "deepseek",
"llm_model": "deepseek-chat",
"fidelity": { "skipped": false, "target": 95, "final_score": 96, "passed": true },
"generate_log": { "run_id": "...", "lines": [] }
}
| 字段 | 说明 |
|---|---|
draft |
蓝图;发布时提交(可微调) |
draft.meta.slug |
新建模块时用此 slug;已有模块发布时以路径 {slug} 为准 |
draft.pages |
禁止只生成 1 个 page;数量不设上限 |
draft == null |
生成失败,看 warnings / generate_log |
页面约定
| type | 用途 |
|---|---|
list |
列表(建议 actions 含 import) |
form_create |
新建表单 |
form_edit |
编辑表单 |
dashboard |
看板 |
detail |
详情 |
每个 page 必须有独立 id / title / route / entity。
"layout": {
"columns": ["sku", "qty", "status"],
"actions": ["create", "edit", "delete", "export", "import", "refresh"]
}
已有模块:draft 应主要是新生成的 pages(及对应 entities / apis),不要把旧页面再写一遍。
新建模块:draft 为完整多页蓝图。
6. 发布(宿主 → 建站平台)
宿主(宇恒)侧「发布」应把建站蓝图与展示元数据 POST 到本建站平台;平台落库建站,并按用户/智能体 ID 加密出文件路径,回执给宿主表格展示。
POST /api/v1/apps/{slug}/publish
Headers:
Authorization: Bearer <access_token>Content-Type: application/json
Path {slug} = 选定的目标模块(新建时为新 slug)。blueprint.meta.slug 会对齐到路径 slug。
默认无需预授权;仅当账号配置了 app_slugs 白名单时才校验。
{
"mode": "auto",
"blueprint": { },
"host_meta": {
"module_name": "whm123",
"publish_style": "immediate",
"host_base_url": "https://whm123.yuheng.com"
}
}
| 字段 | 说明 |
|---|---|
mode |
见下表 |
blueprint |
建站蓝图(必填) |
host_meta.module_name |
宿主表格「模块名称」 |
host_meta.publish_style |
immediate → 立即发布上线 |
host_meta.host_base_url |
宿主访问域名;有则作为回执 access_url |
mode |
含义 |
|---|---|
auto(默认) |
模块已存在 → 发布新生成的页面;不存在 → 新建模块 |
add_pages |
必须已存在;发布草稿中的新页面 |
create |
必须不存在;新建模块 |
replace |
整份覆盖(慎用) |
日常用 auto 或显式 add_pages / create。
加密访问路径
平台用当前账号的 用户/智能体 ID(owner_id) + 租户 + 模块 slug,加密生成逻辑文件路径:
access_path:如m/ajzm1_...(路径中无明文 slug / 用户 id)access_url:优先宿主host_base_url;否则{PublicBaseURL}/api/v1/public/{access_path}/blueprint
公开读取蓝图(无需登录):
GET /api/v1/public/m/{token}/blueprint
其中 {token} 为 access_path 去掉前缀 m/ 的段。
宿主「AI 表格数据」字段映射
| 宿主表格 | 取自发布响应 |
|---|---|
| 模块名称 | module_name |
| 发布方式 | publish_style(immediate → 立即发布上线) |
| 访问地址 | access_url(或宿主自拼域名 + access_path) |
| 发布时间 | published_at |
| 状态 | status = published → 已发布 |
下一步仍是:灌数 → 打开模块。
已有模块(auto / add_pages)
- 保留该模块已有 pages / entities / apis
- 发布草稿中新生成的 page(
id、route不可冲突) - 新 entity / resource 一并加入;已有 entity 只追加新字段
- 若没有任何新 page / entity / resource → 400
新建模块时 blueprint 至少含
meta.slug/meta.nameversion(如"1.0")storage:{ "mode": "schema_per_app", "engine": "postgres" }security:{ "visibility": "private", "roles": [], "row_policies": [] }apis.base_path=/api/v1/apps/{slug}entities/apis/pages
curl -s http://127.0.0.1:8180/api/v1/apps/settlement/publish \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"mode":"create","host_meta":{"module_name":"whm123","publish_style":"immediate","host_base_url":"https://whm123.yuheng.com"},"blueprint":{...}}'
响应示例:
{
"app_id": "...",
"slug": "settlement",
"schema_name": "app_t1_settlement",
"status": "published",
"publish_mode": "created",
"module_name": "whm123",
"publish_style": "immediate",
"access_path": "m/ajzm1_...",
"access_url": "https://whm123.yuheng.com",
"published_at": "2026-07-24T02:00:00Z",
"owner_id": 3,
"endpoints": ["GET /api/v1/apps/settlement/blueprint", "..."],
"ddl": [],
"memory_mode": false
}
publish_mode |
含义 |
|---|---|
created |
新建了模块 |
pages_added |
向已有模块发布了新页面 |
replaced |
整份覆盖 |
| HTTP | 原因 |
|---|---|
| 401 | token 无效 |
| 403 | 缺 「发布模块」;或配置了白名单但不含该 slug |
| 400 | 蓝图非法 / page id 冲突 / mode 与是否存在不一致 |
7. 导入业务数据(发布后必做)
发布只建表,不自动灌数。
POST /api/v1/apps/{slug}/{resource}/import
Content-Type: multipart/form-data
需 Bearer + row.import + 模块授权。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
file |
file | 是 | xlsx / csv / json |
resource = apis.resources[].path(无前导 /),如 records。
curl -s "http://127.0.0.1:8180/api/v1/apps/settlement/records/import" \
-H "Authorization: Bearer <access_token>" \
-F "file=@./settlement.xlsx"
{ "inserted": 120, "skipped": 0, "errors": [] }
抽查:
GET /api/v1/apps/{slug}/{resource}?page=1&page_size=5(需 row.read)
确认 total > 0,否则任务未完成。
8. 推荐调用顺序
0. POST /api/v1/auth/agent/register 宇恒ID(host_key) + 名称(name)
1. (管理员)启用 + 角色 publisher(模块白名单可选,默认留空)
2. POST /api/v1/auth/token
3. GET /api/v1/apps 先选模块(仅本账号可见)
4. GET /api/v1/apps/{slug}/blueprint 仅已有模块:避让已有 page
5. POST /api/v1/apps/generate 生成新页面 或 完整蓝图
6. POST /api/v1/apps/{slug}/publish mode=auto | add_pages | create
7. POST /api/v1/apps/{slug}/{resource}/import
8. GET /api/v1/apps/{slug}/{resource}?page=1&page_size=5
不要:查业务库用户表;行级增删改(除 import);admin/audit;对已有模块默认 replace。
语义:已有模块上是 生成新页面再发布;新建模块自定 slug 即可,无需后台预授权。