@civitai/agent-runner

中文文档
0.1.1发布于 2026/11/01MITTypeScriptES Module构建来源已验证

A durable runner for 's remote mode: replies run as DBOS workflows on Postgres, served over the chat's runner protocol (start, events, stop, patch).

原始使用文档
文档目录8 节
  1. Install
  2. What a deployment provides
  3. Run grants must say what they are
  4. Sketch
  5. Durable names: do not change them casually
  6. Test support
  7. Development
  8. License

@civitai/agent-runner

The server side of <civitai-chat>'s remote mode. Instead of running an assistant reply in the page, the page starts a run on a runner, follows its events over SSE, and can stop it. The run keeps going if the page closes or reloads. This package is that runner:

  • Each reply runs as a DBOS workflow on Postgres. When the process crashes, the reply picks up from its last saved progress, on whichever replica recovers it.
  • It serves the chat's runner protocol v1 (@civitai/components-chat/runner-protocol) over HTTP: start, look up, stop, stop by idempotency key, patch a conversation, and read a run's events from any offset.
  • A viewer can have one active run at a time.

Civitai's own assistant runner is built on it. The package knows nothing about Civitai's accounts, tokens or models. A deployment supplies those through a few interfaces.

Install

pnpm add @civitai/agent-runner @civitai/components-chat

@civitai/components-chat is a peer dependency, because the page and the runner have to speak the same protocol. You need Node 22 or later and a Postgres database that DBOS can use.

What a deployment provides

Everything the runner needs from outside comes through the interfaces in interfaces.ts:

InterfaceWhat it does
AuthenticatorTurns a request's headers into the user id it acts for.
GrantVerifierChecks the run grant a start or a patch carries (header x-run-grant).
GrantStoreKeeps a run's grant while the run lives, in your own table and never in DBOS.
ConversationStoreLoads and atomically updates the saved conversation, the chat's v2/v3 metadata.
ModelProviderSupplies the language model a reply uses. A real one mints its credential per request.
ToolProviderOpens the tools for a reply. The runner closes them on Stop or when the reply ends.

The runner never hands a credential to the model, tool or store seams. Anything passed into a DBOS workflow or returned from a step is persisted in Postgres, so a token must never cross those seams as an argument or a return value.

Run grants must say what they are

A RunGrant carries a required preview flag:

  • preview: false is a run grant. It is good for a start or a patch.
  • preview: true is a preview grant. It is good only on a route that asks for one, through grantFor(request, conversationId, undefined, true).
  • A grant with no boolean preview is neither. It is refused everywhere, and the run API logs the refusal. Runner.start also refuses anything other than a run grant, before it keeps the grant.

The rule fails closed, so a verifier that forgets the flag cannot let its preview grants start runs.

Sketch

import { buildRunApp, loggerOptions, Runner } from '@civitai/agent-runner';

const runner = new Runner({
  models, // ModelProvider
  tools, // ToolProvider
  store, // ConversationStore
  grants: grantStore, // GrantStore
  log,
  wallClockMs: 10 * 60 * 1000,
  stopGraceMs: 20_000,
});

const app = buildRunApp({
  service: runner,
  authenticator, // Authenticator
  grants: grantVerifier, // GrantVerifier
  logger: loggerOptions('info'), // never logs request headers
});

runner.register(); // once per process, before launch
await runner.launch({ databaseUrl, executorId: 'replica-1', workerConcurrency: 8 });
await app.listen({ port: 8080, host: '0.0.0.0' });

buildRunApp also takes routes, for a deployment's own routes served beside the run API. They are handed the same authed, grantFor and refuse helpers the run API uses. It also takes patchRefusal and basePath.

Durable names: do not change them casually

A run that a restarted process recovers is replayed against what DBOS recorded for it. The workflow names (reply, reply-stop-marker), the queue (replies), the application version (WORKFLOW_VERSION, reply-1), the journal stream (events) and the order of the calls a reply makes are therefore part of the contract. test/reply-dbos-calls.pg.test.ts reads them back from DBOS's own tables and compares them with a golden record. That record is byte-identical to the one the runner was verified against before it moved into this package. If you change any of them, bump WORKFLOW_VERSION with the change.

@dbos-inc/dbos-sdk is pinned to an exact version for the same reason.

Test support

@civitai/agent-runner/test-support exports the fakes the suites use: a scripted model, fake tools, a bearer authenticator, a file-backed conversation store, an SSE reader, and freshDatabase for a throwaway Postgres database (it reads ASSISTANT_RUNNER_TEST_DATABASE_URL).

Development

pnpm --filter @civitai/agent-runner typecheck
pnpm --filter @civitai/agent-runner build

The suites run in CI, in the agent-runner job, against a Postgres service. Outside CI, the Postgres-backed suite skips unless ASSISTANT_RUNNER_TEST_DATABASE_URL points at a server where it may create and drop databases. In CI, a missing URL fails the suite instead of skipping it. test/core-boundary.test.ts fails when anything under src/ imports a file outside it, or imports a package that package.json does not declare.

License

MIT

版本与发布记录

@civitai/agent-runner 共发布 3 个版本,首次发布于 2026/10/28;过去 12 个月发布了 3 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.1.1latest2026/11/012 天前
0.1.02026/10/286 天前
0.0.0-stage2026/10/286 天前

关于 @civitai/agent-runner 的常见问题

@civitai/agent-runner 是什么?

用于远程模式的持久运行程序:应答作为Postgres上的DBOS工作流运行,通过聊天的运行程序协议(start, events, stop, patch)提供服务。

如何安装 @civitai/agent-runner?

在项目目录运行 npm install @civitai/agent-runner,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@civitai/components-chat(>=0.25.0 <1.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@civitai/agent-runner 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@civitai/agent-runner 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@civitai/agent-runner 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@civitai/agent-runner 可以商用吗?

@civitai/agent-runner 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@civitai/agent-runner 还在维护吗?

最新版本 0.1.1 发布于 2026/11/01(2 天前);至今共发布 3 个版本,其中过去 12 个月发布了 3 个;首次发布于 2026/10/28。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。