Skip to content

feat: add remote path mappings for split PMHQ deployments#784

Open
kkkzbh wants to merge 2 commits into
LLOneBot:mainfrom
kkkzbh:codex/remote-path-mappings
Open

feat: add remote path mappings for split PMHQ deployments#784
kkkzbh wants to merge 2 commits into
LLOneBot:mainfrom
kkkzbh:codex/remote-path-mappings

Conversation

@kkkzbh

@kkkzbh kkkzbh commented Jun 17, 2026

Copy link
Copy Markdown

Summary

这个 PR 增加了一个通用的 remotePathMappings 配置,用于支持 LLBot 进程和 PMHQ/QQ 运行在不同文件系统命名空间时的媒体路径映射。

典型场景是:PMHQ 运行在容器中,返回 /root/.config/QQ/... 这类容器内路径;LLBot 运行在宿主机进程中,直接对该路径执行 copyFilestatcreateReadStream 会失败。现在 LLBot 可以通过显式配置把 PMHQ 返回的远端路径映射到 LLBot 本地可访问路径,同时在消息元素中继续保留 PMHQ/QQ 需要的原始路径。

Motivation

我们在部署中采用了“LLBot 宿主机进程 + PMHQ 容器”的运行方式。

这样做的背景是:早期 LLBot 和 PMHQ 都运行在 Podman 容器中,但实际运维中遇到过一些和业务无关的容器层问题,例如:

  • LLBot 容器必须通过 Podman 网络 DNS 解析 pmhq:13000
  • podman-compose / rootless Podman 下网络附着、服务别名、host loopback 暴露和部署验证比较容易产生不确定性。
  • LLBot 本身只是 Node 协议适配服务,但放在容器里后,需要额外处理容器网络、端口转发、运行时配置重写、健康检查和部署 verifier。
  • Koishi 和 LLBot 都是普通宿主机后端进程,把 LLBot 放在宿主机后,Koishi 可以直接连接 127.0.0.1:3001,LLBot 也可以直接连接 PMHQ 暴露到宿主机的 127.0.0.1:${PMHQ_PORT},整体运行边界更清晰。

同时,PMHQ 仍然适合保留在容器中,因为它承载的是 QQ 客户端运行时、登录态、Xvfb/图形环境和 QQ 数据目录。这个部分更需要容器隔离,也更适合独立重启和排障。

这个运行方式清理了网络和部署层的不确定性,但也暴露出一个新的边界:LLBot 和 PMHQ 不再共享同一个文件系统命名空间。PMHQ 返回的 /root/.config/QQ/... 对 PMHQ 容器是正确路径,但对宿主机 LLBot 进程不是可直接访问路径。

因此,这个 PR 的目标不是为某个部署脚本写死特殊逻辑,而是让 LLBot 正式支持“远端运行时路径”和“本地进程路径”不同的部署拓扑。

Design

这个 PR 采用显式配置,而不是自动探测容器环境。

新增配置示例:

{
  "remotePathMappings": [
    {
      "name": "pmhq-qq-root",
      "remotePrefix": "/root/.config/QQ",
      "localPrefix": "/var/lib/containers/storage/volumes/qqbot-stack_qq_volume/_data",
      "remoteStyle": "posix",
      "localStyle": "posix"
    }
  ]
}

设计原则:

  • LLBot 只提供通用路径映射能力,不内置 Podman、Docker 或某个部署项目的探测逻辑。
  • 部署系统负责决定 remotePrefixlocalPrefix 的实际值。
  • 默认 remotePathMappings: [],未配置时保持现有同命名空间行为。
  • 映射支持 posixwin32 路径风格。
  • 使用最长前缀匹配,并检查路径边界,避免误匹配类似 /root/.config/QQ2 的路径。
  • 本地文件系统操作使用映射后的本地路径。
  • 发送给 PMHQ/QQ 的消息元素仍保留 PMHQ 返回的远端路径。

Changes

  • 新增 remotePathMappings 顶层配置。
  • 新增通用路径映射工具。
  • NTQQFileApi.uploadFile() 复制文件时使用本地映射路径,但返回的消息路径保持 PMHQ 原路径。
  • 图片、视频、语音、文件上传中的本地读写路径统一经过映射处理。
  • 视频缩略图写入和读取区分本地路径与远端路径。
  • 自动删除、Satori 清理、WebUI 文件/语音代理接入同一映射能力。
  • set_config schema 补充 remotePathMappings 字段。
  • 增加路径映射和富媒体上传相关单元测试。

Why this belongs in LLBot

PMHQ 返回的是它自身运行环境中的 QQ 数据目录路径,这对 PMHQ 来说是合理的。真正同时需要理解“PMHQ 返回路径”和“LLBot 本地可访问路径”的组件是 LLBot,因为 LLBot 会:

  • 调用 PMHQ 获取媒体目标路径。
  • 把待发送文件复制到该目标位置。
  • 构造图片、视频、语音等消息元素。
  • 对媒体文件执行 stat、hash、缩略图生成、createReadStream 等本地操作。

因此,这个能力放在 LLBot 的文件 API 层更合适。它把部署拓扑中的路径边界显式建模,而不是要求每个部署项目去修改打包后的 llbot.js 或在外部做文本 patch。

Compatibility

默认配置为空数组,因此现有 LLBot 和 PMHQ 运行在同一文件系统命名空间的部署方式不会受到影响。

对于容器化 PMHQ + 宿主机 LLBot 的部署,部署系统可以在生成配置时写入合适的映射。这个 PR 不假设具体容器运行时,也不依赖 Podman/Docker API。

Testing

  • npx vitest run --config vitest.config.ts test/unit
  • npx vite build

Summary by Sourcery

添加可配置的远程到本地路径映射,并在 NTQQ 文件/媒体处理链路中统一应用,以便在 PMHQ 运行于独立文件系统命名空间时,LLBot 仍能正常工作。

新功能:

  • 引入顶层配置项 remotePathMappings,支持 POSIX 和 Windows 路径风格,用于将远程 QQ/PMHQ 路径映射到本地可访问路径。

增强改进:

  • NTQQFileApi 内对所有媒体上传、哈希计算、流式传输、缩略图生成以及自动文件清理流程中规范化并应用远程/本地路径映射,同时在消息负载中保留原始远程路径。
  • 在运行时配置 schema 和默认配置中暴露 remotePathMappings,并新增共享的 pathMapping 工具,用于双向路径转换,供核心消息处理逻辑和 WebUI 代理路由共用。

测试:

  • NTQQFileApi 的路径映射行为以及通用的 pathMapping 工具添加单元测试。
Original summary in English

Summary by Sourcery

Add configurable remote-to-local path mappings and apply them across NTQQ file/media handling so LLBot can operate when PMHQ runs in a separate filesystem namespace.

New Features:

  • Introduce a top-level remotePathMappings configuration supporting POSIX and Windows path styles for mapping remote QQ/PMHQ paths to locally accessible paths.

Enhancements:

  • Normalize and apply remote/local path mappings inside NTQQFileApi for all media uploads, hashing, streaming, thumbnail generation, and automatic file cleanup while preserving remote paths in message payloads.
  • Expose remotePathMappings in runtime configuration schema and default configuration, and add a shared pathMapping utility for bidirectional path conversion used by core messaging and WebUI proxy routes.

Tests:

  • Add unit tests for NTQQFileApi path mapping behavior and for the generic pathMapping utility.

新功能:

  • 添加顶层的 remotePathMappings 配置,支持 POSIX 和 Windows 风格的路径前缀,并支持最长前缀匹配。

改进:

  • 将远程到本地路径映射集成到 NTQQFileApi 中,使所有媒体上传、哈希计算、流式传输、缩略图生成、删除以及 WebUI/Satori 代理操作都使用本地可访问路径,同时在消息负载中保留远程路径。
  • 在运行时配置模式(schema)和默认配置中暴露 remotePathMappings,并添加共享的 pathMapping 工具,用于双向路径转换。

测试:

  • NTQQFileApi 的路径映射行为以及通用的 pathMapping 工具添加单元测试。
Original summary in English

Summary by Sourcery

添加可配置的远程到本地路径映射,并在 NTQQ 文件/媒体处理链路中统一应用,以便在 PMHQ 运行于独立文件系统命名空间时,LLBot 仍能正常工作。

新功能:

  • 引入顶层配置项 remotePathMappings,支持 POSIX 和 Windows 路径风格,用于将远程 QQ/PMHQ 路径映射到本地可访问路径。

增强改进:

  • NTQQFileApi 内对所有媒体上传、哈希计算、流式传输、缩略图生成以及自动文件清理流程中规范化并应用远程/本地路径映射,同时在消息负载中保留原始远程路径。
  • 在运行时配置 schema 和默认配置中暴露 remotePathMappings,并新增共享的 pathMapping 工具,用于双向路径转换,供核心消息处理逻辑和 WebUI 代理路由共用。

测试:

  • NTQQFileApi 的路径映射行为以及通用的 pathMapping 工具添加单元测试。
Original summary in English

Summary by Sourcery

Add configurable remote-to-local path mappings and apply them across NTQQ file/media handling so LLBot can operate when PMHQ runs in a separate filesystem namespace.

New Features:

  • Introduce a top-level remotePathMappings configuration supporting POSIX and Windows path styles for mapping remote QQ/PMHQ paths to locally accessible paths.

Enhancements:

  • Normalize and apply remote/local path mappings inside NTQQFileApi for all media uploads, hashing, streaming, thumbnail generation, and automatic file cleanup while preserving remote paths in message payloads.
  • Expose remotePathMappings in runtime configuration schema and default configuration, and add a shared pathMapping utility for bidirectional path conversion used by core messaging and WebUI proxy routes.

Tests:

  • Add unit tests for NTQQFileApi path mapping behavior and for the generic pathMapping utility.

@sourcery-ai

sourcery-ai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

审阅者指南

引入可配置的远程路径到本地路径映射层,并将其整合到 NTQQ 文件/媒体处理的各个环节中,使 LLBot 在 PMHQ 运行于独立文件系统命名空间时仍能正常工作,同时在协议载荷中保留远程路径。

使用远程路径映射进行媒体上传的时序图

sequenceDiagram
  actor User
  participant SendElement as SendElement.Video
  participant NTFileApi as NTQQFileApi
  participant PathMap as PathMappingUtils
  participant PMHQ
  participant FS as FileSystem

  User->>SendElement: sendVideo(filePath)
  SendElement->>NTFileApi: uploadFile(filePath, Video)
  NTFileApi->>PMHQ: getRichMediaFilePath(md5, fileName, type, subType)
  PMHQ-->>NTFileApi: mediaPath (remote)
  NTFileApi->>PathMap: remotePathToLocal(mediaPath)
  PathMap-->>NTFileApi: localMediaPath
  NTFileApi->>FS: copyFile(filePath, localMediaPath)
  FS-->>NTFileApi: ok
  NTFileApi-->>SendElement: { path: mediaPath, localPath: localMediaPath }

  SendElement->>FS: getVideoInfo(localPath)
  SendElement->>PathMap: remotePathToLocal(thumbFilePath)
  PathMap-->>SendElement: localThumbFilePath
  SendElement->>FS: mkdir(dirname(localThumbFilePath))
  SendElement->>FS: copyFile(thumbSource, localThumbFilePath)
  SendElement->>FS: stat(localThumbFilePath), getMd5HexFromFile(localThumbFilePath)
Loading

文件级改动

Change Details Files
添加可配置的远程→本地路径映射和规范化工具,并在配置默认值与 schema 中暴露这些配置。
  • 定义 PathStyle 和 RemotePathMapping 类型,并在全局 Config 接口中新增 remotePathMappings 字段,默认值为空数组。
  • 创建共享的 pathMapping 工具模块,用于规范化映射、执行最长前缀匹配,并在 posix 和 win32 风格下实现远程→本地、本地→远程双向路径映射。
  • 从公共 utils barrel 中重新导出新的 pathMapping 工具,并将 remotePathMappings 接入默认运行时配置和 JSON 配置模板。
  • 扩展 SetConfigAction schema,使其接受包含 name、prefixes 和 style 字段的 remotePathMappings 对象数组。
src/common/types.ts
src/common/utils/pathMapping.ts
src/common/utils/index.ts
src/main/config/defaultConfig.ts
src/main/config/default_config.json
src/onebot11/action/llbot/system/Config.ts
将路径映射集成到 NTQQFileApi 中,使所有文件系统操作都使用本地路径,而协议元素继续保留远程路径。
  • 向 NTQQFileApi 注入配置,存储归一化后的 RemotePathMappings 列表,并在 llob/config-updated 事件上更新它。
  • 在 NTQQFileApi 上新增辅助方法 remotePathToLocal 和 localPathToRemote,并委托给共享的映射工具实现。
  • 在上传文件时,像原来一样计算 PMHQ 媒体路径,但通过 remotePathToLocal 派生出 localMediaPath,使用本地路径执行 copyFile,并同时返回 path(远程)和 localPath。
  • 对所有图片、视频以及通用文件的上传方法(群聊和 C2C),在传给 PMHQ 或用于哈希、流式传输、大小计算之前,将输入的 filePath 和 thumbPath 通过 remotePathToLocal 转换。
src/ntqqapi/api/file.ts
确保缩略图生成、自动删除、Satori 清理以及 WebUI 代理均在映射后的本地路径上运行,而不是远程路径。
  • 在 SendElement 的视频处理逻辑中,使用 uploadFile 返回的 localPath 调用 getVideoInfo,对生成的缩略图路径通过 remotePathToLocal 做映射后再进行目录创建、复制、stat 和 MD5 计算,同时在消息元素映射中保留原始 thumbPath。
  • 在 NTQQ 核心服务中,将 deleteAfterSentFiles 和 autoDeleteFile 中的路径通过 remotePathToLocal 映射后再执行 unlink 和日志记录,这样清理操作就针对本地文件系统执行。
  • 在 Satori MessageEncoder 中,对 deleteAfterSentFiles 中的路径通过 remotePathToLocal 映射后再执行 unlink。
  • 在 WebUI 的 webqq 代理路由中,将传入的 filePath 查询参数通过 remotePathToLocal 映射后再进行规范化/访问校验,适用于通用文件和音频代理端点。
src/ntqqapi/entities.ts
src/ntqqapi/core.ts
src/satori/message.ts
src/webui/BE/routes/webqq/proxy.ts
添加单元测试以验证路径映射行为以及 NTQQFileApi 的集成。
  • 为通用的 pathMapping 工具编写测试,覆盖规范化、前缀匹配、posix/win32 行为,以及无映射时的回退逻辑。
  • 为 NTQQFileApi 添加测试,确保其遵守配置的 remotePathMappings,在文件系统操作中使用本地路径,同时在面向协议的字段中保留远程路径。
test/unit/pathMapping.test.ts
test/unit/ntqqFileApi.test.ts

可能关联的问题

  • #Docker 私聊文件发送失败:该 Issue 中富媒体发送失败的根源在于路径命名空间不一致,而本 PR 中的 remotePathMappings 正是为此提供通用修复方案

提示与命令

与 Sourcery 交互

  • 触发一次新的审查: 在 pull request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub Issue: 在审查评论下回复,要求 Sourcery 从该评论创建 Issue。你也可以直接在审查评论下回复 @sourcery-ai issue 来从该评论创建 Issue。
  • 生成 pull request 标题: 在 pull request 标题的任意位置写上 @sourcery-ai,即可随时生成标题。你也可以在 pull request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 pull request 概要: 在 pull request 正文中任意位置写上 @sourcery-ai summary,即可在该位置生成 PR 概要。你也可以在 pull request 中评论 @sourcery-ai summary 来在任意时间(重新)生成概要。
  • 生成审阅者指南: 在 pull request 中评论 @sourcery-ai guide,即可在任意时间(重新)生成审阅者指南。
  • 一次性解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,即可标记所有 Sourcery 评论为已解决。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 忽略所有 Sourcery 审查: 在 pull request 中评论 @sourcery-ai dismiss,即可忽略所有已有的 Sourcery 审查。尤其在你希望从头开始一次新的审查时很有用——别忘了再评论 @sourcery-ai review 来触发新的审查!

自定义你的使用体验

打开你的 仪表盘 以:

  • 启用或禁用审查功能,例如由 Sourcery 生成的 pull request 概要、审阅者指南等。
  • 修改审查语言。
  • 添加、删除或编辑自定义审查指令。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

Introduce a configurable remote-to-local path mapping layer and integrate it across NTQQ file/media handling so LLBot can operate correctly when PMHQ runs in a separate filesystem namespace, while preserving remote paths in protocol payloads.

Sequence diagram for media upload using remote path mappings

sequenceDiagram
  actor User
  participant SendElement as SendElement.Video
  participant NTFileApi as NTQQFileApi
  participant PathMap as PathMappingUtils
  participant PMHQ
  participant FS as FileSystem

  User->>SendElement: sendVideo(filePath)
  SendElement->>NTFileApi: uploadFile(filePath, Video)
  NTFileApi->>PMHQ: getRichMediaFilePath(md5, fileName, type, subType)
  PMHQ-->>NTFileApi: mediaPath (remote)
  NTFileApi->>PathMap: remotePathToLocal(mediaPath)
  PathMap-->>NTFileApi: localMediaPath
  NTFileApi->>FS: copyFile(filePath, localMediaPath)
  FS-->>NTFileApi: ok
  NTFileApi-->>SendElement: { path: mediaPath, localPath: localMediaPath }

  SendElement->>FS: getVideoInfo(localPath)
  SendElement->>PathMap: remotePathToLocal(thumbFilePath)
  PathMap-->>SendElement: localThumbFilePath
  SendElement->>FS: mkdir(dirname(localThumbFilePath))
  SendElement->>FS: copyFile(thumbSource, localThumbFilePath)
  SendElement->>FS: stat(localThumbFilePath), getMd5HexFromFile(localThumbFilePath)
Loading

File-Level Changes

Change Details Files
Add configurable remote-to-local path mappings and normalization utilities, and expose them in configuration defaults and schema.
  • Define PathStyle and RemotePathMapping types and add remotePathMappings to the global Config interface with a default of an empty array.
  • Create a shared pathMapping utility module that normalizes mappings, performs longest-prefix matching, and maps paths in both remote→local and local→remote directions for posix and win32 styles.
  • Re-export the new pathMapping utilities from the common utils barrel and wire remotePathMappings into the default runtime configuration and JSON config template.
  • Extend the SetConfigAction schema to accept an array of remotePathMappings objects with name, prefixes, and style fields.
src/common/types.ts
src/common/utils/pathMapping.ts
src/common/utils/index.ts
src/main/config/defaultConfig.ts
src/main/config/default_config.json
src/onebot11/action/llbot/system/Config.ts
Integrate path mapping into NTQQFileApi so all filesystem operations use local paths while protocol elements keep remote paths.
  • Inject config into NTQQFileApi, store a normalized list of RemotePathMappings, and update it on llob/config-updated events.
  • Add helper methods remotePathToLocal and localPathToRemote on NTQQFileApi that delegate to the shared mapping utilities.
  • When uploading files, compute the PMHQ media path as before but derive a localMediaPath via remotePathToLocal, use the local path for copyFile, and return both path (remote) and localPath.
  • For all image, video, and generic file upload methods (group and C2C), convert input filePath and thumbPath via remotePathToLocal before passing them to PMHQ or using them for hashing, streaming, or size calculation.
src/ntqqapi/api/file.ts
Ensure thumbnail generation, auto-deletion, Satori cleanup, and WebUI proxies operate on mapped local paths instead of remote ones.
  • In SendElement video handling, use localPath from uploadFile for getVideoInfo, map generated thumbnail paths through remotePathToLocal for directory creation, copying, stat, and MD5 calculation while preserving the original thumbPath in the message element map.
  • In the NTQQ core service, map deleteAfterSentFiles and autoDeleteFile paths through remotePathToLocal before unlinking and logging, so cleanup operates on local filesystems.
  • In the Satori MessageEncoder, map paths in deleteAfterSentFiles via remotePathToLocal before unlinking.
  • In WebUI webqq proxy routes, map incoming filePath query parameters through remotePathToLocal before normalization/access checks for both generic file and audio proxy endpoints.
src/ntqqapi/entities.ts
src/ntqqapi/core.ts
src/satori/message.ts
src/webui/BE/routes/webqq/proxy.ts
Add unit tests to validate path mapping behavior and NTQQFileApi integration.
  • Create tests for the generic pathMapping utilities, covering normalization, prefix matching, posix/win32 behavior, and unmapped fallbacks.
  • Add tests for NTQQFileApi to ensure it respects configured remotePathMappings and uses local paths for filesystem operations while retaining remote paths in protocol-facing fields.
test/unit/pathMapping.test.ts
test/unit/ntqqFileApi.test.ts

Possibly linked issues

  • #Docker 私聊文件发送失败: Issue 的 rich media 发送失败源于路径命名空间不一致,PR 的 remotePathMappings 正是为此提供通用修复方案

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@kkkzbh kkkzbh marked this pull request as ready for review June 17, 2026 17:51

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并留下了一些总体反馈:

  • RemotePathMapping.name 字段在类型定义中是可选的,但在 SetConfigAction 的 schema 中被当作必填字段;建议在 schema 中也将其设置为可选,以保持运行时校验与类型定义及 JSON 配置示例的一致性。
  • NTQQFileApi 中,remotePathMappingssetRemotePathMappings 里会被归一化一次,但 remotePathToLocal/localPathToRemote 会将它们传给 mapRemotePathToLocal/mapLocalPathToRemote,而这些函数会重新调用 normalizeRemotePathMappings;建议增加接受已归一化映射的变体,以避免每次调用时重复归一化。
给 AI Agents 的提示词
Please address the comments from this code review:

## Overall Comments
- The `RemotePathMapping.name` field is typed as optional but enforced as required in the `SetConfigAction` schema; consider making it optional in the schema as well to keep runtime validation consistent with the type definition and the JSON config example.
- In `NTQQFileApi`, `remotePathMappings` are normalized once in `setRemotePathMappings`, but `remotePathToLocal`/`localPathToRemote` pass them to `mapRemotePathToLocal`/`mapLocalPathToRemote`, which re-run `normalizeRemotePathMappings`; consider adding variants that accept pre-normalized mappings to avoid repeated normalization on each call.

## Individual Comments

### Comment 1
<location path="src/onebot11/action/llbot/system/Config.ts" line_range="28-34" />
<code_context>
     ffmpeg: Schema.string(),
     musicSignUrl: Schema.string(),
     msgCacheExpire: Schema.number(),
+    remotePathMappings: Schema.array(Schema.object({
+      name: Schema.string(),
+      remotePrefix: Schema.string(),
+      localPrefix: Schema.string(),
+      remoteStyle: Schema.union(['posix', 'win32']),
+      localStyle: Schema.union(['posix', 'win32']),
+    })),
     rawMsgPB: Schema.boolean()
</code_context>
<issue_to_address>
**suggestion (bug_risk):** `RemotePathMapping.name` is typed as optional but required by the schema, which may cause confusion.

In `common/types.ts`, `RemotePathMapping` has `name?: string`, but this schema requires `name: Schema.string()`. That lets TS callers omit `name` while config validation will reject it. Please either make `name` required in the type or mark it optional in the schema (e.g. `Schema.string().optional()`), so the type and schema stay consistent.

```suggestion
    remotePathMappings: Schema.array(Schema.object({
      name: Schema.string().optional(),
      remotePrefix: Schema.string(),
      localPrefix: Schema.string(),
      remoteStyle: Schema.union(['posix', 'win32']),
      localStyle: Schema.union(['posix', 'win32']),
    })),
```
</issue_to_address>

Sourcery 对开源项目免费——如果你觉得我们的 review 有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的 review。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • The RemotePathMapping.name field is typed as optional but enforced as required in the SetConfigAction schema; consider making it optional in the schema as well to keep runtime validation consistent with the type definition and the JSON config example.
  • In NTQQFileApi, remotePathMappings are normalized once in setRemotePathMappings, but remotePathToLocal/localPathToRemote pass them to mapRemotePathToLocal/mapLocalPathToRemote, which re-run normalizeRemotePathMappings; consider adding variants that accept pre-normalized mappings to avoid repeated normalization on each call.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `RemotePathMapping.name` field is typed as optional but enforced as required in the `SetConfigAction` schema; consider making it optional in the schema as well to keep runtime validation consistent with the type definition and the JSON config example.
- In `NTQQFileApi`, `remotePathMappings` are normalized once in `setRemotePathMappings`, but `remotePathToLocal`/`localPathToRemote` pass them to `mapRemotePathToLocal`/`mapLocalPathToRemote`, which re-run `normalizeRemotePathMappings`; consider adding variants that accept pre-normalized mappings to avoid repeated normalization on each call.

## Individual Comments

### Comment 1
<location path="src/onebot11/action/llbot/system/Config.ts" line_range="28-34" />
<code_context>
     ffmpeg: Schema.string(),
     musicSignUrl: Schema.string(),
     msgCacheExpire: Schema.number(),
+    remotePathMappings: Schema.array(Schema.object({
+      name: Schema.string(),
+      remotePrefix: Schema.string(),
+      localPrefix: Schema.string(),
+      remoteStyle: Schema.union(['posix', 'win32']),
+      localStyle: Schema.union(['posix', 'win32']),
+    })),
     rawMsgPB: Schema.boolean()
</code_context>
<issue_to_address>
**suggestion (bug_risk):** `RemotePathMapping.name` is typed as optional but required by the schema, which may cause confusion.

In `common/types.ts`, `RemotePathMapping` has `name?: string`, but this schema requires `name: Schema.string()`. That lets TS callers omit `name` while config validation will reject it. Please either make `name` required in the type or mark it optional in the schema (e.g. `Schema.string().optional()`), so the type and schema stay consistent.

```suggestion
    remotePathMappings: Schema.array(Schema.object({
      name: Schema.string().optional(),
      remotePrefix: Schema.string(),
      localPrefix: Schema.string(),
      remoteStyle: Schema.union(['posix', 'win32']),
      localStyle: Schema.union(['posix', 'win32']),
    })),
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/onebot11/action/llbot/system/Config.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant