嵌入 ocra
在你自己的程序里用 @open-cr-agent/core 的 review() 运行审查流水线。
ocra 首先是一个库。ocra 命令只是 @open-cr-agent/core 里 review() 的一个调用方;你的程序可以是另一个:一个机器人、你自己的 CI 步骤、一个定时审查的服务。同样的阶段、信任规则、花费上限和报告都适用。
一次完整的调用
import {
correctnessReviewerPlugin,
coverageGaps,
review,
securityReviewerPlugin,
sessionJsonlPlugin,
startPlugins,
toReportOutput,
} from "@open-cr-agent/core";
import { opencodeRuntimePlugin } from "@open-cr-agent/runtime-opencode";
import { localGitPlugin } from "@open-cr-agent/vcs-local";
// 1. 插件注册适配器、运行时、审查员、规则、工具和事件监听。
const registry = await startPlugins(
[localGitPlugin, opencodeRuntimePlugin, correctnessReviewerPlugin, securityReviewerPlugin, sessionJsonlPlugin],
{
env: process.env,
settings: { "session-jsonl": { dir: ".ocra/sessions", id: "my-run" } },
warn: (message) => console.warn(message),
},
);
// 2. 改动从哪里来,agent 由什么运行。
const vcs = registry.createVcs("local", {
cwd: process.cwd(),
target: { mode: "range", from: "main", to: "HEAD" },
});
const runtime = registry.createRuntime("opencode", {
models: {
top: ["google/gemini-3.1-pro-preview"],
standard: ["google/gemini-3.5-flash", "google/gemini-flash-lite-latest"],
light: ["google/gemini-flash-lite-latest"],
},
env: process.env,
});
// 3. 审查。
try {
const report = await review({
vcs,
runtime,
reviewers: registry.reviewers,
rules: registry.rules,
maxCostUsd: 2,
onEvent: (event) => registry.emit(event),
});
const { notReviewed, nothingReviewed } = coverageGaps(report);
console.log(JSON.stringify(toReportOutput(report)));
if (nothingReviewed || notReviewed > 0) process.exitCode = 3;
} finally {
await runtime.dispose?.();
}startPlugins 执行插件的生命周期(插件)并返回一个冻结的注册表;createVcs 和 createRuntime 按名字构造插件注册的适配器和运行时;registry.emit 把每个事件交给监听者,这里是会话日志。上面的插件和设置就是 CLI 用的那一套;CLI 读取的 .ocra/config.json 是命令行的便利功能,不属于库。
review() 接受什么
ReviewOptions 按稳定性页的说法,在 ocra 还是 0.x 时是一份约定:次版本可能改变它,变更日志会说明如何适配。下面这些字段属于约定:
| 选项 | 含义 |
|---|---|
vcs | 这次改动的 VcsAdapter:diff 和文件从哪里来,publish 把审查发到哪里 |
runtime | 每次运行一个隔离审查任务的 AgentRuntime |
reviewers | 要运行的审查员(默认只有 correctness);可以用注册表里的,也可以是你自己的 ReviewerDefinition |
reviewerOverrides | 按审查员设置 enabled、minTier |
rules | 按路径生效的审查规则(RepoRule[]),注册表里的加上你自己的 |
readTrusted | 从哪里读取 AGENTS.md、.ocra/rules.json 和 .ocra/memory.json。默认是被审查的版本;审查 PR 时传入一个读取可信 base 的函数,改动就改不了它们 |
selection | 审查哪些文件:include、exclude、maxPatchChars |
concurrency、taskTimeoutMs、runTimeoutMs | 并行任务数(4)、单个任务的超时(10 分钟)和整次运行的超时(25 分钟) |
verify、judge | 对照 diff 核查问题,以及跨审查员合并、过滤和重新定级(默认都开启) |
maxCostUsd、maxTasks | 花费上限(--max-cost-usd)和任务数上限 |
fullReview | 即使平台报告了上次审查以来的改动,也审查所有文件 |
ultra | 以成本换召回率(模式) |
sarif | 解析好的 SARIF 日志(parseSarifLog),其中落在改动上的结果加入审查(SARIF 输入) |
signal | 一个 AbortSignal:运行会停下,保留已发现的问题并写出部分报告 |
onEvent | 在运行过程中接收每个 ReviewEvent |
runId | 在报告、事件和发布的内容里标识这次运行;不传则自动生成。CLI 传入它的会话 id |
provenance | { ocraVersion, configHash, sampling? }:传入后,报告的 provenance 会加上启用的审查员和辅助阶段所发系统提示词的哈希,以及运行时实际应用的采样设置(sampling 是你向运行时要求的设置;stableHash() 可以给你自己的配置算哈希) |
0.2 及以前,ReviewOptions 还带有 bundling、grouper、relocate 和 abortGraceMs;它们是调优和测试钩子,从来不是约定,现在已不在其中。
它返回什么
一个 ReviewReport:改动、风险档位、结论和总结、每个文件的覆盖情况、分组、任务、问题、核查否决和 Judge 的决定、与上次审查的对比、用量和警告。读取它时要知道两件事:
- 对外发布的是
toReportOutput(report),不是报告本身。它是 CLI 写出的带版本号的 JSON,由reportOutputSchema和公开的 JSON Schema 描述;内部报告里的字段可能会变。 - 不完整的审查不算通过。
coverageGaps(report)给出有多少选中的文件没被审查、是否什么都没审到;report.unverifiedCriticals是没人能核查的 critical 数量。CLI 的退出码就是由这些算出来的;用审查结果做门禁的程序应当照做,永远不要只看verdict就当作通过。
vcs.publish(report) 像 --publish 一样按平台的信任规则发布审查,没能发出去的部分以警告返回。
事件(onEvent)是进度、会话日志和终端输出的来源。它们的形状不是约定:监听者应当容忍新的事件类型和字段。
错误
review() 只在运行无法开始时 reject:没有审查员、.ocra/rules.json 或 .ocra/memory.json 无效,或者 VCS 适配器读不到改动。任务开始运行之后,任务失败、辅助调用失败、模型配额用尽和触及花费上限都会记录在报告里(任务结果、覆盖情况、警告),而不是抛出;按上文用 coverageGaps(report) 读取它们。
ocra 的各个包抛出的都是 OcraError(或它的子类),带有 code;isOcraError(error, code?) 可以判断,OCRA_ERROR_CODES 列出全部代码。如果错误源于另一个错误(JSON 解析错误、读取失败),那个错误就是 cause。请按代码分支,不要按消息:消息是给人看的,措辞可能会改。插件提供的适配器或运行时可能抛出它自己的错误,所以调用方也要处理不是 OcraError 的错误。
| 代码 | 含义 |
|---|---|
CONFIG_INVALID | 无法使用的配置:选项、.ocra/config.json 及其 extends、.ocra/rules.json、.ocra/memory.json、模型名、没有审查员、某个档位没有模型 |
CONFIG_CREDENTIALS_MISSING | 运行需要的令牌或模型密钥没有设置 |
INPUT_USAGE | ocra 无法执行的命令行(CLI 的用法错误) |
INPUT_INVALID | 交给 ocra 却无法读取的输入,例如 SARIF 日志或一组 commit id |
ACCESS_DENIED | 访问策略拒绝了某个路径:密钥文件、git 内部文件、ocra 写入处的符号链接 |
PLUGIN_INVALID | 无法加载的插件、重复注册或在启动后注册,或者没有任何插件注册过的名字 |
VCS_GIT_FAILED | git 命令失败 |
VCS_API_FAILED | GitHub 或 GitLab API 失败或返回了意外的内容;GitHubApiError 和 GitLabApiError 带有 HTTP status |
VCS_REF_UNKNOWN | 仓库里没有、也无法拉取的 commit 或 ref |
VCS_NOT_READY | 平台还没准备好这次改动,例如还没有 diff 的 Merge Request;稍后重试 |
RUNTIME_START_FAILED | agent 运行时无法启动(没有 OpenCode 可执行文件、服务没有起来) |
RUNTIME_FAILED | 一次模型调用在它链上的每个模型都失败了(CompletionError,带有这些尝试花掉的 usage) |
RUNTIME_INVALID_OUTPUT | 模型的回答不符合预期的 schema |
BUDGET_EXHAUSTED | 达到了花费上限(SpendLimitReached,即正在运行的任务被停止的原因) |
INTERNAL | 不变量被破坏或对象被误用,例如一个 OpenCode 运行时被用于两次运行:ocra 或其调用方的 bug |
子类保留各自的名字,供 instanceof 使用:@open-cr-agent/core 的 CompletionError、SpendLimitReached、AccessDeniedError、SarifError 和 PluginError,@open-cr-agent/vcs-local 的 GitError,平台适配器的 GitHubApiError 和 GitLabApiError。ocra 不会把令牌或模型密钥写进错误消息,两种运行时在引用模型供应商的回答之前也会把其中的密钥去掉。
这些代码是一份约定,遵循 0.x 规则:次版本可能新增代码,重命名或删除代码时变更日志会说明。CLI 在以退出码 2 结束运行时会打印错误代码,例如 ocra [CONFIG_INVALID]: .ocra/config.json is invalid: …。
PR 与 Merge Request
githubPlugin(@open-cr-agent/vcs-github)和 gitlabPlugin(@open-cr-agent/vcs-gitlab)注册 github 和 gitlab 适配器。它们 createVcs 的选项(仓库、编号、令牌的变量名、是否发布)还没有作为库的约定写入文档;仓库里的 packages/cli/src/review/target.ts 展示了 CLI 如何构造它们,包括作为 readTrusted 传入的可信 base 读取函数。在本页列出它们之前,请把这些形状当作内部实现。
信任
嵌入 ocra 的程序就是信任边界。插件会执行代码,所以只加载你信任的插件,绝不加载被审查的代码树指定的插件;模型密钥通过 env 传入,运行时只转发配置的供应商需要的变量(安全);审查 PR 时通过 readTrusted 从 base 版本读取指南、规则和 memory。无论谁调用,审查本身只给 agent 只读工具,没有 shell。
公开 API
每个包的主入口就是它的公开 API,是一份遵循 0.x 规则的约定:
@open-cr-agent/core:review()和ReviewOptions;它返回的内容(ReviewReport、Finding以及组成它们的类型)、coverageGaps()、toReportOutput()及ReportOutput、reportOutputSchema、reportJsonSchema()和REPORT_VERSION;parseSarifLog();插件接口(OcraPlugin及其上下文、startPlugins()、PluginRegistry、内置的审查者插件和sessionJsonlPlugin);插件实现的约定(VcsAdapter、AgentRuntime及它们用到的类型、ToolDefinition、ReviewerDefinition、RepoRule);以及错误模型。@open-cr-agent/vcs-local:localGitPlugin、LocalTarget、LocalGitOptions和GitError。vcs-github和vcs-gitlab:githubPlugin和gitlabPlugin,以及它们的 API 错误。runtime-opencode和runtime-direct:opencodeRuntimePlugin和directRuntimePlugin。@open-cr-agent/vcs-platform是 ocra 各平台适配器共用的部分,还不是约定。
每个名字和每个类型的形状都记录在该包的 API 报告里,位于仓库的 etc/ 目录;入口变了而报告没变时,CI 会失败。
@open-cr-agent/core/internal,以及另外几个包的 /internal 入口,是 ocra 各个包之间共用的部分。它不是约定:任何版本(包括补丁版本)都可能修改或删除它导出的内容。请只依赖主入口。