# Lingtai C ABI 灵台引擎进程内形态的公共契约。本文件是 `hj_*` 稳定符号、类型与错误码的单一登记处;机器化前以本文件为命名基线,机器化后以 `include/hunjing/lingtai.h` 与生成 Schema 为准。独立服务形态(gRPC)契约见 [Lingtai Service](lingtai-service.md),两种形态共用同一核心与语义;架构语义见[灵台引擎架构](../architecture/lingtai-engine.md)。 ## 1. 适用范围与稳定性 - 消费方:官方 Python/Go/Rust 绑定与经部署者授权的第三方宿主。这是公开稳定契约,适用与 Native API 相同的演进纪律:向后兼容的新增函数不升 major;修改既有签名或语义必须升 major。 - `HjStatus` 错误码同时是服务形态错误映射的源枚举(映射表见 [Lingtai Service](lingtai-service.md));新增错误码须同步评估两种形态。 - 凭据、用户内容与密钥不经 ABI 传递;引擎无网络与持久化能力(只读索引除外),不存在凭据通道。 - 本 ABI 不是 HTTP 分面,不与 `api./v1` 的资源契约混用;引擎产物的字段与枚举复用本目录既有契约。 ## 2. 命名与符号 | 对象 | 规则 | 示例 | | --- | --- | --- | | 函数 | `hj_` 前缀 + `snake_case` | `hj_engine_new` | | 不透明句柄类型 | `Hj` 前缀 | `HjEngine`、`HjStream` | | 状态码枚举 | `HJ_OK` / `HJ_ERR_*` | `HJ_ERR_PARSE_FAILED` | | 宏 | `HJ_` 前缀大写 | `HJ_ABI_VERSION` | | 库文件 | `libhunjing` | `libhunjing.so` / `.dylib` / `.dll` | | 公共头 | 单一头文件 | `include/hunjing/lingtai.h` | - 所有导出函数为 `extern "C"`;结构体不透明(仅前向声明),字段布局不进入契约。 - 除 `hj_*` 外不导出任何符号;C++ 类、STL 类型、异常与 RTTI 不得跨越边界。 ### 2.1 模块标识 六个子系统的稳定模块名(职责详见[灵台引擎架构](../architecture/lingtai-engine.md),文化名见[文化语言体系](../product/cultural-language.md)): | 模块 | 职责摘要 | | --- | --- | | `hj_core` | 版本协商、句柄生命周期、状态转换校验、事件序 | | `hj_stream` | 流事件编码、增量去重、节流与重放缓冲 | | `hj_plan` | 计划 DAG 校验、预算核算、上下文装配计算 | | `hj_recall` | 只读离线混合索引、重排打分、多路合并 | | `hj_transform` | Markdown 规范化为 canonical ContentBlock | | `hj_policy` | Schema/路径/URL 校验、验签、幂等键、决策评估 | ## 3. 版本协商 ```c #define HJ_ABI_VERSION 1 uint32_t hj_abi_version(void); ``` - `HJ_ABI_VERSION` 为当前 major;`hj_abi_version()` 返回引擎构建时的 major。 - 宿主在 `hj_engine_new` 传入所需 major;不一致时返回 `HJ_ERR_UNSUPPORTED_ABI` 且不产生句柄,禁止静默降级运行。 - 引擎实现与 parser 版本可经 `hj_engine_build_info` 查询,供宿主写入 PluginSnapshot、诊断与审计。 ## 4. 生命周期与内存 - 引擎句柄:`hj_engine_new` / `hj_engine_free`;`HjEngine` 线程安全。 - 会话句柄(`HjStream`、`HjTransform`、`HjRecallSession`、`HjPolicyEval`):从 `HjEngine` 派生,单线程亲和;每个句柄有对应 `hj_*_free`。 - 缓冲区:引擎分配的输出缓冲由 `hj_buffer_free` 释放;`hj_buffer_data`/`hj_buffer_len` 读取内容。宿主不得 `free` 引擎指针,引擎不得持有返回后的宿主指针。 - 字符串:UTF-8;输入 NUL 结尾或指针加长度,输出指针加长度。 - 二次释放、句柄复用与跨线程使用会话句柄返回 `HJ_ERR_HANDLE_INVALID`,不得崩溃。 ## 5. `HjStatus` 错误码 | 枚举值 | 语义 | 典型映射 | | --- | --- | --- | | `HJ_OK` | 成功 | — | | `HJ_ERR_INVALID_ARGUMENT` | 参数为空、编码非法或超长 | `validation_failed` | | `HJ_ERR_OUT_OF_MEMORY` | 引擎分配失败 | `internal` + 告警 | | `HJ_ERR_UNSUPPORTED_ABI` | major 版本不匹配 | 启动失败 | | `HJ_ERR_HANDLE_INVALID` | 句柄非法、已释放或跨线程 | `internal` | | `HJ_ERR_REENTRANCY` | 回调内再入引擎 | `internal` | | `HJ_ERR_PARSE_FAILED` | 输入无法规范解析 | `validation_failed` | | `HJ_ERR_LIMIT_EXCEEDED` | 长度/深度/节点/预算超限 | `payload_too_large` / `limit_exceeded` | | `HJ_ERR_POLICY_DENIED` | 策略判定拒绝 | `permission_denied` / `forbidden` | | `HJ_ERR_SIGNATURE_INVALID` | 验签失败或时间窗外的重放 | `invalid_signature` | | `HJ_ERR_INDEX_CORRUPT` | 只读索引校验失败 | 启动失败,要求重建索引 | | `HJ_ERR_BUFFER_TOO_SMALL` | 输出缓冲不足(可重试扩容) | — | | `HJ_ERR_INTERNAL` | 引擎内部错误 | `internal` | - 新增错误码不破坏兼容;绑定层必须对未知码走失败分支,不得当作成功。 - `hj_last_error` 返回线程局部的最近错误消息(UTF-8、脱敏、不含正文与密钥);下一次引擎调用覆盖。 ## 6. 数据边界 - ContentBlock、流事件与策略判定输入输出使用本目录既有 JSON Schema([统一富内容与流式协议](content-blocks-and-streaming.md));引擎输出 canonical JSON:键序确定、无空白、UTF-8,保证 content hash 可跨端复现。 - 媒体字节(图片摘要、向量、波形)经 `hj_buffer` 二进制传递,不进入 JSON。 - 限额(单消息 Block 数、源码长度、节点数、嵌套深度)由宿主配置传入并在 Schema 中保留硬上限;超限返回 `HJ_ERR_LIMIT_EXCEEDED`,引擎不得为完成解析而放宽限额。 ## 7. 回调约定 ```c typedef void (*HjStreamCallback)(void *user_data, const char *event_json, size_t event_len); ``` - 回调在触发调用的同一线程同步执行;回调内禁止调用任何 `hj_*` 函数(`HJ_ERR_REENTRANCY`)。 - `event_json` 仅在回调期间有效;宿主需要保留必须复制。 - 回调抛出的宿主异常不得穿透引擎:绑定层捕获后中止本次调用并返回错误。 ## 8. 官方绑定矩阵 | 语言 | 包名(建议) | 实现 | 错误映射 | | --- | --- | --- | --- | | Python | `hunjing-lingtai` | nanobind 薄封装,no-gil 标记长计算 | `HunjingEngineError` 层级 | | Rust | `hunjing-lingtai-sys` + `hunjing-lingtai` | bindgen 生成 + 安全包装(RAII、`Result`) | `LingtaiError` enum | | Go | `hunjing/lingtai` | cgo,绑定集中在单一包 | `errors` 哨兵值 | - 绑定层不缓存权威状态、不补写业务语义;三端输出必须字节一致(golden 测试)。 - 绑定的内存错误(泄漏/双重释放)由各端测试矩阵覆盖,属于发布门。 ## 9. 禁令清单 - 不得以宿主语言重新实现已登记的引擎能力作为回退路径。 - 不得在 ABI 边界传递凭据、Cookie、诊断令牌或用户正文以外的敏感负载。 - 不得链接未登记的引擎内部符号或依赖头文件未声明的行为。 - 不得绕过 `hj_engine_new` 的版本协商直接 dlsym 猜测符号。 - 不得将引擎错误消息原样透传给最终用户;错误本地化由宿主完成。