news 2026/9/15 20:21:48

CloudCLI UI 如何给 Claude 会话设置定时发送的消息并确认它按时触发

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CloudCLI UI 如何给 Claude 会话设置定时发送的消息并确认它按时触发

CloudCLI UI 如何给 Claude 会话设置定时发送的消息并确认它按时触发

【免费下载链接】claudecodeuiUse Claude Code, OpenCode, Cursor CLI, and Codex on mobile and web with CloudCLI (aka Claude Code UI). CloudCLI is a free open source webui/GUI that helps you manage your Claude Code session and projects remotely.项目地址: https://gitcode.com/GitHub_Trending/cl/claudecodeui

场景是:你已经有一个 CloudCLI(Claude Code UI)里的 Claude Code 会话,想把一条消息留给它、让它在稍后指定时间自动发出并执行,而不是现在立即发送。CloudCLI 内置了 scheduled messages 功能:在聊天输入框上直接指定发送时间,服务端把消息存入数据库,到点后由服务端定时器为这个会话发起一次聊天回合——不需要浏览器开着,也不需要你再手动操作。

本文的主路径是纯 UI 操作,另附服务端轮询机制说明和 REST 接口核对方式,用于确认消息确实按时触发。

准备条件

  • 一个已运行的 CloudCLI 服务端。自托管方式(见 docs/README.md 的 Quick Start)要求 Node.js v22+,然后执行:
npx @cloudcli-ai/cloudcli

或全局安装后使用:

npm install -g @cloudcli-ai/cloudcli cloudcli
  • 启动后打开http://localhost:3001,进入某个已存在的会话。调度接口会校验sessionId,指向不存在的会话会返回 404(SESSION_NOT_FOUND),所以目标会话必须是 CloudCLI 已经发现的会话。

在聊天输入框上调度一条消息

  1. 打开目标会话,在底部输入框里输入要稍后发送的消息内容,不要点发送
  2. 点击发送按钮旁边的时钟图标按钮。该按钮的 aria-label 是 “Schedule this message”(见 ScheduleMessagePopover.tsx)。
  3. 弹出菜单标题为 “Send later”,提供四档快捷时间:In 15 minutesIn an hourIn 8 hoursTomorrow;每档会显示按当前时间换算后的具体时刻。
  4. 也可以在下方 “Or pick a time” 处用datetime-local控件挑选精确到分钟的时间,然后点击Schedule确认。

时间选择时由浏览器按本地时区解析成一个绝对时刻再提交,服务端存的是这一个明确的时间点——之后你换到另一台设备或另一个时区,到点触发不会跟着漂移(这一点在 ScheduleMessagePopover.tsx 的注释和 scheduled-messages.service.ts 中都有说明)。

判断调度是否成功

成功后有两个可见结果:

  1. 输入框被清空。调度成功等价于一次“发送”,消息已经离开输入框(见 ChatInterface.tsx 中handleScheduleMessage的处理)。
  2. 输入框上方出现一条 “Scheduled for <时间>” 的待发送卡片。这张卡片由 ScheduledMessageList.tsx 渲染,只展示pendingfailed两种状态的消息。

调度时当前输入框里选择的模型、effort、permissionMode 会作为options一起存入,到点触发时原样带回去({ model, effort, permissionMode },见 ChatInterface.tsx;测试用例 scheduled-messages.test.ts 中 “the composer settings it was scheduled with travel with it” 覆盖了这一点)。

如果只是想确认服务端已收到,可以用 REST 接口核对(接口定义见 scheduled-messages.routes.ts):

  • GET /api/scheduled-messages?sessionId=<sessionId>— 返回该会话的全部调度消息,数组中每条含idsessionIdcontentscheduledForstatusfailureReason等字段;
  • GET /api/scheduled-messages(不带参数)— 返回当前用户名下所有pending消息。

这些路由挂载在需要登录鉴权的路径下(server/index.ts 中app.use('/api/scheduled-messages', authenticateToken, ...)),请求要带浏览器会话同一套凭据;前端统一以Authorization: Bearer <token>附带,见 api.ts。响应外层是{ success: true, data: [...] },前端读取的就是data数组。

到点后发生了什么

确认“按时触发”之前,先了解服务端的触发机制(scheduled-message-dispatcher.service.ts):

  • 服务端以30 秒为周期轮询数据库(POLL_INTERVAL_MS = 30_000),找出所有到期的pending消息;
  • 到期消息在同一条数据库事务里被“认领”为sent,再逐个执行,因此重叠的轮询不会把同一条消息发两次;
  • 触发不依赖浏览器:调度消息发起的 run 以connection: null运行,即使没有任何浏览器连着这个会话也会照常执行(01-websocket-transport.md 中明确提到 “a scheduled message firing with no browser attached”);
  • 如果到点时该会话正好有一个进行中的 run,进行中的 run 会被中断(interruptActiveRun: true),定时消息按预定时间落地,而不是被记成“没发——会话忙”;
  • 如果到点时服务端没在运行,消息不会丢:定时表在数据库里,服务恢复后的第一次轮询会把错过的消息补发。

验证消息确实按时发出

  1. 看会话记录。过了选定时间(加上至多 30 秒的轮询间隔)后,该会话的 transcript 中应出现这条消息作为用户消息,并跟随模型的回复;你不需要开着这个标签页,重新打开会话即可看到已执行的记录。
  2. 查状态字段。用上面的GET /api/scheduled-messages?sessionId=<sessionId>查看status:正常流程是pendingsent
  3. 失败会显式留痕。若触发时 run 未能启动(例如会话已删除、provider 不可用)或启动后失败,服务端不会静默丢弃,而是把状态改为failed并写入failure_reason(截断到 500 字符);此时输入框上方会出现一条 “Not sent — <原因>” 的红色卡片,点 × 可关闭(关闭走同一取消接口,状态变为cancelled)。
  4. 取消待发消息。在 “Scheduled for …” 卡片上点 ×,即调用DELETE /api/scheduled-messages/<id>。已发出(sent)的消息不允许再取消,会返回 409(SCHEDULED_MESSAGE_NOT_PENDING);已取消的消息到点不会再发(对应测试 “a cancelled message never fires”)。

限制与边界

以下约束来自服务端校验与实现,调度前值得注意:

  • 消息内容必须非空,且不超过 100,000 字符(否则 400:CONTENT_REQUIRED/CONTENT_TOO_LONG);
  • scheduledFor必须是可解析的时间戳,且距当前不超过365 天(否则 400:SCHEDULE_TOO_FAR_AHEAD);
  • 时长按分钟粒度选择(快捷项为 15 分钟/1 小时/8 小时/明天,自定义项为分钟级选择器),而服务端 30 秒轮询一次,所以实际发出时刻会在选定时间之后至多约半分钟内;
  • 触发会中断该会话上正在进行的 run——如果你希望某个长任务不被打断,避开它的运行时间窗来设时间。

相关源码

  • 路由与鉴权:scheduled-messages.routes.ts
  • 调度校验(长度、365 天、会话存在性、取消):scheduled-messages.service.ts
  • 到期轮询、认领与补发逻辑:scheduled-message-dispatcher.service.ts
  • 数据库层(状态pending/sent/failed/cancelled、事务认领):scheduled-messages.db.ts
  • 前端调度弹层、列表与接口封装:ScheduleMessagePopover.tsx、ScheduledMessageList.tsx、useScheduledMessages.ts
  • 行为测试(补发、去重、中断进行中 run、失败留痕、跨用户隔离):scheduled-messages.test.ts

【免费下载链接】claudecodeuiUse Claude Code, OpenCode, Cursor CLI, and Codex on mobile and web with CloudCLI (aka Claude Code UI). CloudCLI is a free open source webui/GUI that helps you manage your Claude Code session and projects remotely.项目地址: https://gitcode.com/GitHub_Trending/cl/claudecodeui

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 20:21:21

滑模控制MATLAB实现:边界层与趋近律的工程化抖振抑制

简介&#xff1a;本资源是一套面向自动化、控制工程专业本科生及初学者的滑模变结构控制&#xff08;SMC&#xff09;MATLAB仿真源码包&#xff0c;专为课程设计与期末大作业打造&#xff0c;解决理论理解难、代码实现无从下手、仿真调试耗时等典型痛点。压缩包共359个文件&…

作者头像 李华
网站建设 2026/9/15 20:20:54

抖音视频批量去水印保存:douyin-downloader 三步上手指南

抖音视频批量去水印保存&#xff1a;douyin-downloader 三步上手指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback su…

作者头像 李华
网站建设 2026/9/15 20:19:20

CSV转Fluent Profile完整指南:格式、转换与导入避坑

做CFD的人多半都遇到过这个需求&#xff1a;手里有一份实测数据或者上游软件导出的结果&#xff0c;格式是CSV&#xff0c;想把它作为Fluent里的Profile&#xff08;数据表&#xff09;喂给边界条件或初始条件用。我最早接触这件事是在处理一个通风管道入口的速度分布&#xff…

作者头像 李华
网站建设 2026/9/15 20:18:16

TFT多变量时序预测实战:原理、PyTorch实现与经验

做过多变量时序预测的朋友&#xff0c;应该都经历过这样的阶段&#xff1a;拿到一堆特征&#xff0c;不管三七二十一先上个LSTM再说。训练半天&#xff0c;loss降了&#xff0c;结果一上测试集&#xff0c;要么滞后严重&#xff0c;要么变量稍微多一点就直接崩溃。我也一样&…

作者头像 李华
网站建设 2026/9/15 20:17:52

Axmol 引擎系列教程之 - 如何切换引擎依赖库镜像

众所周知&#xff0c;为了国际化&#xff0c;Axmol 引擎托管到 Github&#xff0c; 然而&#xff0c;由于一些原因&#xff0c;在中国大陆访问 Github 间歇性地阻断。为了中国大陆用户可以顺利访问&#xff0c;Axmol 维护者在 Gitee 下为 Axmol 引擎的主仓库&#xff1a;https:…

作者头像 李华