尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Flue Valkey 持久化实战:用 @flue/redis 适配器把 Agent 会话状态接入 Valkey
Flue Valkey 持久化实战用 flue/redis 适配器把 Agent 会话状态接入 Valkey【免费下载链接】flueThe sandbox agent framework.项目地址: https://gitcode.com/GitHub_Trending/flue1/flueFlue 的 Node 目标项目可以通过官方flue/redis适配器把 Agent 的规范会话流、不可变附件与已接受的提交持久化到 Valkey配置方式是在源码根目录落一个实现自定义 runner 的db.ts。本篇以仓库中的 Valkey 数据库蓝图blueprints/database--valkey.md为主体结合 packages/redis 的源码实现完整讲解从部署选型、db.ts编写、启动迁移到验证与升级的全流程。读完后你应当能独立完成一个可运行、可验证、可升级的 Valkey 持久化集成并理解迁移钩子、inspectServer检查与keyPrefix隔离在底层是如何执行的。蓝图定位这是 flue add 返回给编码代理的实现指南在展开细节前先说明这篇文档在 Flue 仓库中的角色。blueprints/ 目录存放的是flue add与flue update两个 CLI 命令返回的 Markdown 实现指南——Blueprint 是写给 AI 编码代理的指南不是 npm 包也不是运行时抽象CLI 负责拉取并输出指南由编码代理去修改用户项目。按 blueprints/README.md 的命名规则database--valkey.md对应的 slug 是valkey即flue add database valkey/flue update database valkey会返回这份完整指南。该蓝图的 JSON frontmatter 为{ kind: database, version: 1, website: https://valkey.io }其中version: 1标识完整蓝图契约的版本见文末 Upgrade Guide。所有database类型的蓝图产出的都是一个位于源码根目录、默认导出PersistenceAdapter的db.ts而不是sandboxes/下的文件。蓝图开篇明确划定了支持边界Valkey 实现了本适配器所用的 Redis 协议与命令面因此flue/redis可用于 Valkey但该蓝图仅针对 Valkey 提供支持不要据此推断所有自称Redis 兼容的服务都受支持。前置检查一运行时目标与部署形态先确认项目不是 Cloudflare 目标db.ts适配器是仅面向 Node 目标的持久化手段。Cloudflare 目标自动使用 Durable Object SQLite并在构建期直接拒绝项目自有的db.ts。如果项目面向 Cloudflare应停止操作并告知用户没有可添加的内容。packages/redis/README.md 的 Target support 一节与蓝图表述一致该适配器仅支持 Node.jsCloudflare 项目使用 Durable Object SQLite。Valkey 部署形态的硬性要求蓝图要求使用持久化的独立 Valkey 服务器或托管的单分片single-shard端点且必须满足maxmemory-policy noeviction禁止逐出Valkey Cluster 与纯缓存cache-only配置不受支持按恢复目标启用 AOF显式 fsync 策略和/或持久化快照。这里有一个容易误解的点noeviction只保证已确认的写入不被内存压力逐出并不保证写入在服务端整体丢失后仍然存活——跨服务端丢失的持久性必须由 AOF/快照策略提供。为什么不支持 Cluster从 key 命名结构看packages/redis/src/redis-keys.ts 中的RedisKeys类揭示了原因Flue 的 key 采用前缀:种类:base64url 编码段的结构如submission:base64url(id)、session-unsettled:base64url(sessionKey)且一次业务操作往往横跨多个独立 key 的原子脚本。这类 key 分布并不是为 Cluster 哈希槽设计的 schema跨 key 的 Lua 原子操作在分片拓扑下无法保证落在同一节点。因此蓝图与 packages/redis/README.md 均明确仅支持独立服务器与托管单分片端点。前置检查二检查项目现状并安装依赖蓝图要求的检查步骤阅读项目内的本地指令AGENTS.md及同类文件探测项目使用的包管理器按顺序选择第一个存在的源码根目录root/.flue/→root/src/→root/检查是否已存在db.ts若已存在替换前必须先与用户确认检查项目的密钥secret约定。随后用项目的包管理器安装两个依赖flue/redis与官方redis^5.12.1node-redis客户端。需要强调flue/redis不捆绑任何生产客户端项目自己拥有凭证、TLS、超时、重连行为与拓扑选择。packages/redis/package.json 中redis仅作为该包的 devDependency仓库开发环境使用^6.1.0出现不会进入运行时产物packages/redis/README.md 的示例安装命令为pnpm add flue/redis redis。创建 db.ts完整的 runner 实现在选定的源码根目录写入如下完整 runner作为db.ts的内容。首行// flue-blueprint: database/valkey1是蓝图生成的主文件标记用于后续flue update时识别受蓝图管理的文件标记规范见 blueprints/README.md// flue-blueprint: database/valkey1 import { redis } from flue/redis; import { createClient } from redis; const client createClient({ url: process.env.VALKEY_URL }); await client.connect(); export default redis({ command: (command, args []) client.sendCommand([command, ...args.map(String)]), eval: (script, keys, args []) client.eval(script, { keys, arguments: args.map(String), }), pipeline: async (commands) { const multi client.multi(); for (const { command, args [] } of commands) { multi.addCommand([command, ...args.map(String)]); } const results await multi.exec(); for (const result of results) { if (result instanceof Error) throw result; } return results; }, close: () client.close(), });redis(runner, options?)工厂函数在 packages/redis/src/redis-adapter.ts 中定义接收 runner 与可选的RedisOptions返回一个PersistenceAdapter。runner 各字段的契约定义在 packages/redis/src/redis-runner.ts字段类型说明command(command, args)必填执行归一化的 Redis 命令返回原始响应eval(script, keys, args)必填执行 Lua 脚本keys与args严格分离对应KEYS/ARGVpipeline(commands)可选批量暂存大型不可变代generation时使用未提供时适配器会退化为逐条command串行执行见 redis-adapter.tsclose()必填客户端生命周期收尾三个实现要点值得结合源码展开1.String()强转是无损的。适配器永远不会把二进制参数透传给 runner——附件字节在存储边界就已完成 base64 编码packages/redis/src/attachment-store.ts 中encodeBytes/decodeBytes使用 base64 跨 runner 接缝读取时还通过 digest 校验兜底任何落盘损坏因此 runner 把每个参数经String()强转不会丢失任何信息。RedisArgument类型本身就是string | numberredis-runner.ts。2. pipeline 的每命令一个归一化结果契约。node-redis 的multi().exec()会按[error, result]元组返回其中任何一项为Error即代表该命令失败。蓝图 runner 在返回前遍历结果、抛出第一个Error恰好满足这一契约适配器侧也会二次校验结果数量与错误形态redis-adapter.ts但 runner 仍负责把驱动特有的失败形态归一化。3. RESP2/RESP3 双协议兼容由适配器消化。Valkey 与不同版本的 node-redis 可能返回不同 RESP 协议的响应形状例如HGETALL在 RESP2 下是扁平的 field/value 数组、在 RESP3 下是 map。适配器内置的hash()归一化同时接受两种形状packages/redis/src/conversation-store.ts 有明确注释因此 runner 无需感知协议版本差异。凭证规则不要硬编码或凭空发明连接串。从项目的密钥系统中读取VALKEY_URL或其既有等价项绝不提交凭证到仓库。启动迁移migrate() 与格式版本机制Flue 会发现db.ts并在服务器启动时调用适配器的migrate()钩子——没有独立的迁移命令。migrate()的完整行为可以在 packages/redis/src/redis-adapter.ts 中逐行印证它做三件事检查服务器inspectServer未禁用时见下节幂等地初始化格式版本元数据 key读取flue:metahash 中的format_version字段。若缺失先探测旧字段schema_version——若其值为8Nightly 时代遗留存储形状与 format 1 逐字节一致则直接改标签为format_version: 1并删除旧字段不做任何数据重写若旧字段为其他值则拒绝。若两字段都缺失则用SCANCOUNT 100分页检查前缀下是否已有数据有数据但无版本标记的旧存储按unversioned拒绝确认为空库才用HSETNX落版本标记。先写新字段、再删旧字段保证中断不会留下无标记的存储。拒绝来自更新格式的数据已记录的format_version与当前版本不一致尤其是更大值意味着由更新的 Flue 写入时抛出PersistedFormatVersionError。当前运行时格式版本为1定义在 packages/runtime/src/format-version.ts。inspectServerCONFIG GET 与 INFO 双通道验证默认启用inspectServer时启动期会验证两项部署属性任一无法验证即启动失败TypeErrorCluster 已禁用先CONFIG GET cluster-enabled失败则回退到INFO cluster并匹配cluster_enabled:1/0检测到yes/1直接报 Redis Cluster is not supportedmaxmemory-policy为noeviction先CONFIG GET maxmemory-policy失败则回退到INFO memory并匹配maxmemory_policy:行。实现见 redis-adapter.ts 的 inspectServer()。inspectServer: false的适用条件仅当托管单分片服务商同时拒绝CONFIG与INFO两条检查命令时才使用且前提是你已独立核实过Cluster 关闭 noeviction这两项要求。关闭检查等于把部署正确性责任完全移交给运维侧验证步骤必须相应补偿见下文第 3 条。keyPrefixFlue 命名空间隔离通过redis(runner, { keyPrefix: ... })的第二个参数隔离 Flue 的 key默认前缀为flueredis-keys.ts 中RedisKeys构造器会去掉尾部冒号并拒绝空前缀。建议为每个应用或租户使用稳定且唯一的前缀或者直接使用独立的 Valkey database。两个关键行为前缀变更只是让 Flue 指向一个独立的新空命名空间不会迁移已有数据生产清理走的是维护中的 set/sorted set从不扫描整个 keyspacepackages/redis/README.md Storage model。What gets stored存储模型与边界蓝图明确列出适配器存储的内容边界存储的规范canonical追加-only 会话流——它是唯一的事实记录sole transcript读取时从流头开始完整回放回放加速与持久化日志压缩是推迟项当前不做不可变外部附件——以 base64 文本写入 hash 并附带 digest读取时校验attachment-store.ts 的PUT脚本采用EXISTS先检 HSETSADD的首写者胜语义同 id 重复写入时校验 ref 与字节一致性不一致抛AttachmentConflictError已接受的直发direct与调度dispatched提交及恢复日志recovery journals——提交生命周期状态queued/running/joining/joined/terminalizing/settled 等以 hash 存权威元数据、以 sorted set 维护顺序准入admission、认领claim、租约lease等状态迁移由 Lua 脚本原子化redis-adapter.ts 中admitSubmissionScript、claimSubmissionScript、lifecycleScript等脚本族。不存储的sandbox 文件、外部 API 副作用、凭证、以及任何应用业务数据。会话在实例生命周期内只追加没有按会话删除的能力整实例级别的流/附件删除方法是低层原语不属于公开编排接口。从 packages/redis/README.md 的 Storage model 一节还可以补充一个实现事实Redis Lua 在后续命令失败时不会回滚已执行的命令因此脚本会先校验 key 类型、尽量在权威状态之前预留索引容量并在正常操作中以权威 hash 为准修复索引noeviction大幅限制了部分迁移的风险但多命令脚本执行中内存耗尽仍需运维级恢复——为最大暂存代staging generation及其索引保留足够的内存余量。验证清单完整五步蓝图给出的验证步骤应逐条执行且第 5 条是红线对配置好的 Node 目标做类型检查与构建vite build确认db.ts被 Flue 发现将VALKEY_URL指向一个**一次性throwaway**的持久化独立或托管单分片 Valkey 部署且已配置noeviction启动服务器并确认迁移成功。若你禁用了inspectServer必须独立核验 Cluster 关闭与逐出策略为noeviction创建状态、重启 Flue 服务器、确认状态重新加载。另外单独测试所选的 AOF/快照恢复——进程重启只能证明进程内可重读不能证明跨 Valkey 服务端丢失的持久性不要使用生产数据库做验证。更新既有集成与 Upgrade Guide当对一个已有集成执行更新flue update database valkey返回同一份完整指南时蓝图要求的操作是检查现有实现并与当前完整蓝图逐段比对应用所有相关变更并保留自定义部分然后在主标记文件即db.ts中补上或更新标记// flue-blueprint: database/valkeyN当标记缺失时这一比对是强制要求。这一无标记时的更新契约规范同样定义在 blueprints/README.md。Version 1 — 2026-06-14Initial version.首个版本无历史差异可展示。小结与适用前提适用前提Flue 项目的Node 目标Valkey 为独立部署或托管单分片noeviction 按恢复目标配置的 AOF/快照交付物只有一个文件源码根目录的db.ts默认导出redis(runner, options?)的结果首行带蓝图标记运行时行为迁移、格式版本守卫、服务器检查、原子提交生命周期全部由flue/redis在 packages/redis/src/redis-adapter.ts 中实现db.ts只负责把官方redis客户端桥接成 runner深入阅读路径packages/redis/README.md部署要求与存储模型、packages/redis/src/redis-runner.tsrunner 契约、packages/runtime/src/format-version.ts格式版本规则、blueprints/README.md蓝图机制。【免费下载链接】flueThe sandbox agent framework.项目地址: https://gitcode.com/GitHub_Trending/flue1/flue创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Tandoor 相关工具与生态导览:recipe-scrapers 深度集成与周边应用盘点

Tandoor 相关工具与生态导览:recipe-scrapers 深度集成与周边应用盘点

Tandoor 相关工具与生态导览:recipe-scrapers 深度集成与周边应用盘点 【免费下载链接】recipes Application for managing recipes, planning meals, building shopping lists and much much more! 项目地址: https://gitcode.com/GitHub_Trending/re/recipes …

📅 2026/9/16 12:48:18
VMD最佳模态数怎么选?基于中心频率相近原则的MATLAB自动定阶法

VMD最佳模态数怎么选?基于中心频率相近原则的MATLAB自动定阶法

简介:VMD(变分模态分解)算法是信号处理与故障诊断中的常用分解工具,这份资源面向使用MATLAB开展模态分解、中心频率分析的研究者与工程师,重点解决VMD分解阶数难以确定的问题——通过观察各模态中心频率的相近程度&…

📅 2026/9/16 12:48:18
MATLAB实现极化码CA-SCL译码器的完整指南

MATLAB实现极化码CA-SCL译码器的完整指南

简介:本资源为极化码在高斯信道下CA-SCL译码算法的完整MATLAB仿真实现,面向电子信息工程、计算机与数学等专业的本科生及研究生,适用于课程设计、期末大作业与毕业设计等实践环节。代码基于参数化编程思想构建,支持灵活调整码长、…

📅 2026/9/16 12:43:17
MORE NEWS

更多资讯

📰

STC15单片机超声波测距OLED显示实战:从原理到原理图设计

简介:这份面向STC15单片机初学者的超声波测距项目,集成了测距算法、OLED显示与硬件原理图,适用于嵌入式课程设计、竞赛备赛或实际避障模块开发,也可作为毕业设计参考。方案基于IAP15系列8051内核MCU,通过HC-SR04类超声…

📰

C#对象映射实战:反射、特性与表达式树应用

1. 项目背景与核心目标最近在重构一个老旧的.NET项目时,我遇到了一个经典问题:如何在不同的数据模型之间进行高效、安全的属性映射。手动编写每个属性的赋值代码不仅枯燥乏味,还容易出错。这时候很自然地想到了AutoMapper这个业界标杆&#x…

📰

半导体设备技术突破与智能化发展趋势

1. 半导体设备技术突破现状分析最近业内确实出现了一些值得关注的半导体设备技术进展,主要集中在以下几个方向:1.1 光刻技术的新突破在极紫外光刻(EUV)领域,最新的进展包括:光源功率提升至500W以上&#xf…

📰

LTspice元器件库本质:路径、符号与模型三要素协同机制

1. 为什么LTspice导入元器件库是每个仿真老手的“必修课”而不是“选修课”LTspice导入一个元器件库文件——这七个字背后,藏着无数电子工程师、硬件爱好者、学生党在深夜调试电路时摔键盘的真实瞬间。我第一次被逼着搞懂这个操作,是在帮客户复现一个开关…

📰

EITtext_EIT:Python实现行内实体标签解析与转换实战

简介:面向电阻抗成像(EIT)逆问题研究者的完整求解代码包,聚焦吉洪诺夫正则化、Landweber迭代、L1稀疏重构与共轭梯度(CGLS)等经典与前沿算法,适合医学成像、地质探测及无损检测领域的硕博生与工…

📰

Qt+OpenCV+C++实战:从零构建行车辅助系统核心功能

简介:这份完整的行车辅助系统源码基于Qt、OpenCV与C构建,主要面向毕业设计、课程设计及实际项目开发场景,适合具备一定C基础、希望在图形界面与计算机视觉方向深入实践的开发者。整个资源包共279个文件,约48.7MB,其中包…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬