@empyria/restate

中文文档
0.4.31发布于 2026/11/01MITES Module

Restate.dev用于Empyria纳米服务框架的助手

中文使用文档
文档目录10 节
  1. 要求
  2. 安装
  3. 使用
  4. 模块
  5. 代理人: @empyria/restate/agent
  6. 重复工作
  7. 服务和注册端点
  8. 塑造代理
  9. 脚本
  10. 许可证

@empyria /重申

Restate.dev 助手的 Empyria,构建一个纳米服务框架 主要在Bun上:一个Admin API客户端,一个通用的动态调度服务,非驱动的 工作流调度,以及支持状态的输入/输出模式验证。

目标重状态服务器 1.7.x 和 @restatedev/restate-sdk 1.17.x.

要求

  • 包子 >=1.4.0 或node . js >=26
  • 简单的ESM,没有构建步骤,没有TypeScript

这两个要求都来自 @empyria /分类 和 @empyria /常见这个包裹 取决于和哪个使用本机 Temporal 全局用于所有日期/时间处理。

安装

bun add @empyria/restate

使用

import { createRestateAdmin, withValidation, cronJob, cronJobInitiator } from '@empyria/restate'

const admin = createRestateAdmin({
    restateAdminURL: 'http://localhost:9070',
    restateURL: 'http://localhost:9071',
})

const services = await admin.listServices()

所有的东西都是从包根目录通过 index.js。个人 模块下 lib/ 如果只需要一个,也可以直接导入:

import { checkServiceHandler } from '@empyria/restate/lib/Admin.js'

模块

模块目的
lib / Admin.jsRestate管理API客户端——服务/处理程序发现、部署注册和拆除、工作流/消息调度; defineWorkflow/defineService/defineObject 构造定义器,和 setupRestate 用于连接具有健康检查和正常关闭的端点。
lib / Caller.jsCallerServiceDef -一个通用的Restate服务,当目标在编译时不知道时,它通过名称调度对任何其他服务的任何处理程序的调用。
lib / Cron.jscronJobInitiator/cronJob -重播服务实现非驱动的、重播安全的重复作业调度 croner.
lib / Pubsub.jsdefinePubsub (在端点上注册一个公共订阅虚拟对象), pubsubPublisher (从处理程序内部发布到它,在进程中), pubsubClient (通过网络从其他任何地方发布/拉取/订阅)-薄包装 @restatedev/pubsub/@restatedev/pubsub-client.
lib / Validation.jswithValidation 封装一个带有输入/输出JSON模式验证的工作流处理程序 @empyria/common.
lib / Endpoint.jsserveEndpoint -在HTTP/2上提供服务/工作流,而不注册自身或在退出时删除其部署(对于注册地址的主管)。

代理人: @empyria/restate/agent

作为重构构建块的LLM代理(以前是 @empyria/restate-llm). 单独的条目 点,所以根导入永远不会加载AI SDK。它需要可选的对等依赖项:

bun add ai @ai-sdk/openai-compatible @ai-sdk/provider
模块目的
lib /代理/ Agent.jsdefineAgent -构建服务/对象及其 ask handler:已验证的I/O; loadContext 它只记录技能索引、会话内存(对象状态或外部 historyStore)、步骤/令牌预算、调用重试策略。 createAgentService 是否已弃用? AgentService 快捷方式。
lib /代理/ Loop.jsrunAgentLoop -一次一轮;每个LLM调用和工具调用都是它自己的持久步骤。期刊模式的回应,从来没有提示或以前的历史。
lib /代理/ Tools.js工具规格和执行:块工具(ctx.genericCall),执行工具(有界) ctx.run 使用幂等键),通过带有超时的可唤醒对象进行批准, load_skill, final_answer.
lib /代理/ Skills.js技能体不会出现在日志中: load_skill 记录 {name, sha256}, expandSkillRefs 将主体放回每个LLM步骤中。一个调用中的散列不匹配是终止的;跨会话回合使用当前主体。
lib /代理/ Errors.jstoRestateLLMError (AI SDK错误→终端/ RetryableError / transient)以及LLM步骤、工具步骤和代理调用的默认重试策略。
lib /代理/ Model.jscreateModel - openai兼容端点(如Bifrost)的AI SDK模型。

重复工作

cronJob (虚拟对象)在cron调度上运行目标处理程序:每次运行发送目标,然后调度 从当前时间开始的下一个,因此重新启动或中断永远不会导致运行积压。注册 cronJob 在你的 端点,然后使用以下任意一种创建作业:

  • cronJobInitiator.create(request):每次调用一个带有随机ID的新作业(适用于用户创建的作业);
  • ensureCronJob({restateURL, id, cronExpression, service, method, key?, payload?}): 幂等的,对于代码 从应用程序开始。 这份工作很稳定 id 你给它,所以每次开始时调用它不会增加一秒 作业:同样的请求不会改变任何东西,一个改变的请求(另一个调度、目标或有效负载)会替换挂起的请求 以相同的身份运行一旦端点注册,调用它,例如from setupRestate的 registrationCallbackFn.
  • getCronJob({restateURL, id}):作业的请求和下次运行,或 null 当它不存在时;
  • cancelCronJob({restateURL, id}):取消挂起的运行,清除作业和 把它读回来:只有当 工作真的没了,不然就丢了。可以安全地重复,而且是为了一份从未存在过的工作。

Cron表达式是 croner 模式(五个字段,或者六个,用于测试)。将目标处理程序发送到 payload 作为它的输入,或者当没有输入时没有输入。

服务和注册端点

setupRestate({ restateAdminURL, serviceURL: 'https://agent-service.internal:9080', services }) 接受一个完整的URL 地址重述到达端点在。它被注册为给定的,并且端点侦听其端口(80或443) URL没有或声明方案的默认值),因此方案是必需的(没有单独的主机或端口选项); 通过 port 当端点侦听URL中的另一个端口时(服务或代理后面的容器)。这个 运行状况端点在此之后侦听端口,除非 healthPort 是集。

它提供服务,注册部署,并在SIGINT/SIGTERM上再次删除它。正在运行的调用是 将它们固定在部署上,因此删除它们会束缚它们:重新启动的进程无法完成它们,它们只能 死亡。对于在同一地址重新启动的进程,通过 keepDeploymentOnShutdown: true 和 forceRegistration: true: 当相同的地址再次注册时(根据Restate 1.7进行检查),运行时,Restate保留部署ID 在新流程上继续调用,并且 force 更新现有的服务和处理程序 重新注册会保留旧的处理程序列表)。只有兼容的更改才安全:调用已删除的或 重命名的处理程序无法恢复。

在不注册的情况下服务:当其他东西拥有注册(一个只注册一次进程地址并重启进程的管理器)时,使用 serveEndpoint({port, services}) 相反,它只是服务。已经在部署上运行的调用被固定到它的 地址,因此部署必须在进程停止后继续运行,并返回到相同的地址。

塑造代理

defineAgent 基本选项之外的选项:

选项做
tools 作为一个函数tools: (input) => ({...}) 根据已验证的请求为依赖于该请求的工具构建工具。它在任何 ctx.run 每次执行和重放,必须是纯粹的。无效映射最终导致请求失败(500)。
output 作为一个函数output: (input) => schema | undefined 为每个请求选择答案的JSON模式(规则与 tools:纯I/O); undefined 表示该请求的自由文本回答。与任何 output,模型的答案将根据模式进行检查:错误的答案将交给模型来纠正,而永远不会正确的模型将在 maxSteps.
respond(result, input)形状是什么 ask 从循环结果返回 {text, output?, steps, totalTokens, trace}. 搭配 responseSchema,在Restate记录成形值之前对其进行验证。
label(input)然后读取终端故障 [label] message因此,一次失败的运行说明了它在做什么。保留代码和元数据;取消、超时和可重试错误不受影响。
limits.maxInputBytes最大请求(JSON字节,默认64 KB);较大的一个最终被拒绝(413)。

键控块工具。 块工具调用另一个重构构建块。它的 key(args, meta) 和 input(args, meta) 钩子从模型的参数和每次调用的幂等键中决定目标键和参数 (meta.idempotencyKey,对于每个工具调用都是唯一的)。对多个呼叫都相同的键(如: lock:<resource>) 让一个虚拟对象一次一个地运行这些调用,并将其余的持久地排队;由等幂键构建的键 使每个调用独立。 input 添加模型不能控制的内容,例如调用者或允许的文件夹。 两个钩子都不能在运行前抛出:validate,而不能在它们内部抛出。

工具调用的大小上限。 工具参数和结果被记录下来并重播,所以每个工具都有 maxInputBytes (默认16 KB)和 maxOutputBytes (默认32 KB)。过大的参数不能运行 模型被告知原因;过大的结果将被模型看到的错误所取代。对于一个 execute 工具的 检查发生在它自己的内部 ctx.run,所以大的值永远不会被记录。

多么好的记录啊。 每一个 llm-step-N 小日志 meta (model, finishReason, inputTokens, outputTokens, durationMs),而不是提示或回复。循环返回与 trace (每个步骤一个条目,包含所要求的工具名称),并记录一个 ctx.console 每一步行,保持不变 重播时沉默。

配置。 readLlmEnv(process.env) 返回 {LLM_BASE_URL, LLM_API_KEY?, MODEL_ID} 失败了 命名丢失的设置并且从不打印值的终端500。

测试代理。 @empyria/restate/testing 出口 fakeCtx (一个日志 run, genericCall, awakeable,状态和捕获 console)和模型-结果帮助器 textResult, toolCallResult 和 sequence,无需加载AI SDK。

错误策略:最终(被拒绝或超时)批准失败的工具,被调用者的 TerminalError(执行工具重试失败)返回模型作为错误结果, 所以代理可以适应。暂时错误留给Restate重试和取消 总是传播。

没有官方的Restate Admin API客户端(直接针对已发布的API进行验证) @restatedev/restate-sdk/-clients 包) lib/Admin.js 手写的包装纸保留了吗 与实时管理API的OpenAPI规范(<admin-url>/openapi)。

每个导出的函数都直接用JSDoc记录在其源文件中——悬停 VSCode或Zed中的函数显示其参数和返回类型,不需要任何额外的内容 工具,因为两个编辑器都从plain读取JSDoc .js 自动文件。

测试在 测试/,每个模块一个文件,与源文件分开。他们 模拟 fetch 和Restate SDK客户端,而不是需要一个实时服务器 例外是 setupRestate,它绑定实际端口并安装进程信号处理程序 并且故意没有经过测试(见 AGENTS.md)。

脚本

bun run format       # check formatting (oxfmt)
bun run format:fix   # apply formatting
bun run lint         # lint (oxlint)
bun run lint:fix     # lint and fix
bun run test         # run tests with coverage

许可证

MIT©Imre Fazekas

版本与发布记录

@empyria/restate 共发布 53 个版本,首次发布于 2026/08/16;过去 12 个月发布了 53 个版本。

版本发布日期距今
0.4.31latest2026/11/012 天前
0.4.302026/10/295 天前
0.4.292026/10/258 天前
0.4.282026/10/259 天前
0.4.272026/10/2311 天前
0.4.262026/10/1815 天前

关于 @empyria/restate 的常见问题

@empyria/restate 是什么?

Restate.dev用于Empyria纳米服务框架的助手

如何安装 @empyria/restate?

在项目目录运行 npm install @empyria/restate,或使用 pnpm add / yarn add / bun add。

@empyria/restate 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/empyria__restate 是否存在。

@empyria/restate 支持 ESM 还是 CommonJS?

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

@empyria/restate 需要什么版本的 Node.js?

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

@empyria/restate 可以商用吗?

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

@empyria/restate 还在维护吗?

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