Edit Service(services/ifc)
services/ifc/ 是 Python FastAPI 服务,基于 ifcopenshell 和 ifcdiff,默认端口 8100。它提供 IFC 脚本沙箱执行、版本快照、ScriptMap 定位和语义 diff。原 L1 直改链路已退役,端点返回 410。DXF 侧的同构服务见 CAD Edit Service。
运行与配置
bash
cd services/ifc
uv sync
VIEWER_DATA_DIR="$(cd ../data && pwd)" uv run uvicorn app.main:app --port 8100| 环境变量 | 默认 | 说明 |
|---|---|---|
VIEWER_DATA_DIR | ../data | 与 Go dataDir 同目录,必须一致 |
AIIFC_FLOWS_DIR | ../../skills/aiifc/references/docs/flows | aiifc skill 的 flows 目录,沙箱契约校验依赖其中的 script_lib.py |
EDIT_SERVICE_PORT | 8100 | 监听端口 |
EDIT_SERVICE_MAX_MODELS | 8 | 内存模型缓存上限 |
依赖全部来自 PyPI 官方发布,uv sync 直接安装。沙箱相关环境变量见沙箱执行环境。
编辑 API
模型 id 匹配 ^m_[0-9a-f]{16}$,对应文件 {VIEWER_DATA_DIR}/uploads/{id}.ifc。
| 端点 | 语义 |
|---|---|
GET/PUT /models/{id}/script | 读当前脚本,或暂存一次编辑(整体替换或只改 PARAMS) |
GET /models/{id}/script/params | 提取 PARAMS,不执行脚本 |
POST /models/{id}/script/undo|redo|discard | 暂存导航与放弃 |
POST /models/{id}/script/run | 沙箱试运行,预览用,不产生版本 |
POST /models/{id}/script/save | 晋升大版本;有 bootstrap 时响应带 alignment |
GET /models/{id}/scripts · POST .../rollback · .../diff · .../staging/diff | 版本列表、回退、脚本 diff、暂存步 diff |
GET /models/{id}/script/locate?guid= | guid 定位到脚本调用点 |
POST /models/{id}/script/edit-call | libcst 标量改写,非法输入 422 零副作用 |
GET /models/{id}/versions · POST /models/{id}/diff · .../diff/upload | 版本列表、语义 diff、上传对比 |
GET/DELETE /models/{id}/pending · GET /models/{id}/history | 只读保留项,用途见下 |
PUT/DELETE /models/{id}/entities/{guid} · POST /models/{id}/commit | 已退役,返回 410 |
pending 在直改退役后只作运行簿记;history 只增,新记录来自外部修改登记。
完整契约见 IFC 编辑 API。
实现要点
- 沙箱执行、暂存、版本、diff 这些领域逻辑的单一事实源在共享包
aibim_sandbox,本服务只留薄适配层,详见沙箱执行环境。 app/ifc_materialize.py负责按需重建历史版本 IFC,结果进 LRU 缓存。重建产物只保证语义相等,比较一律走 diff。app/route_common.py统一请求解析;业务校验住在各verify*函数里,这是仓库 AGENTS.md 的硬规则。app/registry.py做模型缓存、原子保存和每路径文件锁。app/diffing.py适配 IfcDiff:只比较属性和属性集,changed 的字段级明细自算,快照间结果缓存。
测试
bash
cd services/ifc
uv run --group dev pytest独立部署与移植
这个服务可以脱离 Go server、web、converter、PostgreSQL 单独部署,也可以整体搬到新宿主。它是和 aiifc skill 配对的服务端:skill 产出脚本,它负责执行、存版本和算 diff。
移植的最小步骤:
- 拷贝
services/ifc/和skills/aiifc/,沙箱执行需要后者 flows 里的script_lib.py。 - 在
services/ifc/下执行uv sync。 - 把
VIEWER_DATA_DIR配成绝对路径,指向你的模型数据根目录。 - 启动服务,打开
/docs的 Swagger UI 自检。
其他组件都是可缺省的:
| 缺少的组件 | 还能做什么 | 少了什么 |
|---|---|---|
| Go server | 全部编辑、diff、版本端点直连可用 | 统一 envelope、对外入口、鉴权、XKT 重转、浏览器桥接 |
| web | 纯 API 调用不受影响 | 可视化界面 |
| converter | 编辑与 diff 完全可用 | IFC 转 XKT 的渲染链路 |
| PostgreSQL | 默认文件存储即可 | Issue 等数据的 PG 持久化 |
数据约定只有一条:任何组件按同一个 VIEWER_DATA_DIR 写 uploads/{id}.ifc,编辑服务就能使用它。
两点边界要注意。8100 直连没有鉴权,务必只监听 127.0.0.1,要对外请走 Go server;provenance 的 AI、UI、USER 是调用方自报的声明字段,服务端只校验枚举。另外暂存链在内存里,服务重启会丢掉未试运行的暂存,大版本是落盘持久的。