ocra

嵌入 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_USAGEocra 无法执行的命令行(CLI 的用法错误)
INPUT_INVALID交给 ocra 却无法读取的输入,例如 SARIF 日志或一组 commit id
ACCESS_DENIED访问策略拒绝了某个路径:密钥文件、git 内部文件、ocra 写入处的符号链接
PLUGIN_INVALID无法加载的插件、重复注册或在启动后注册,或者没有任何插件注册过的名字
VCS_GIT_FAILEDgit 命令失败
VCS_API_FAILEDGitHub 或 GitLab API 失败或返回了意外的内容;GitHubApiError 和 GitLabApiError 带有 HTTP status
VCS_REF_UNKNOWN仓库里没有、也无法拉取的 commit 或 ref
VCS_NOT_READY平台还没准备好这次改动,例如还没有 diff 的 Merge Request;稍后重试
RUNTIME_START_FAILEDagent 运行时无法启动(没有 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 各个包之间共用的部分。它不是约定:任何版本(包括补丁版本)都可能修改或删除它导出的内容。请只依赖主入口。

在 GitHub 上编辑

本页目录