From e47de3f74f9827765c7f261ded24dd05c885ad5e Mon Sep 17 00:00:00 2001 From: liruifengv Date: Thu, 28 May 2026 22:06:52 +0800 Subject: [PATCH] docs: document scheduled task tools --- .changeset/cron-tools.md | 6 +++++- docs/en/configuration/data-locations.md | 3 +++ docs/en/configuration/env-vars.md | 1 + docs/en/guides/use-cases.md | 24 ++++++++++++++++++++++++ docs/en/reference/tools.md | 18 ++++++++++++++++++ docs/zh/configuration/data-locations.md | 3 +++ docs/zh/configuration/env-vars.md | 1 + docs/zh/guides/use-cases.md | 24 ++++++++++++++++++++++++ docs/zh/reference/tools.md | 18 ++++++++++++++++++ 9 files changed, 97 insertions(+), 1 deletion(-) diff --git a/.changeset/cron-tools.md b/.changeset/cron-tools.md index 98576443d6..6c667bde4c 100644 --- a/.changeset/cron-tools.md +++ b/.changeset/cron-tools.md @@ -3,4 +3,8 @@ "@moonshot-ai/kimi-code": minor --- -Add session-scoped scheduled prompts so the assistant can register, list, and cancel recurring or one-shot reminders that fire later in the same session. +Add scheduled tasks: + +You can now ask the assistant to remind you at a specific time, run a task on a recurring cron schedule (for example, check a deploy every 5 minutes or run a daily report every weekday at 9am), or come back on its own in a few minutes to continue what it was doing. + +Schedules use the standard 5-field cron syntax. diff --git a/docs/en/configuration/data-locations.md b/docs/en/configuration/data-locations.md index 4cfd54b1c8..9dc695476d 100644 --- a/docs/en/configuration/data-locations.md +++ b/docs/en/configuration/data-locations.md @@ -46,6 +46,8 @@ $KIMI_CODE_HOME (default ~/.kimi-code) │ │ ├── .json │ │ └── / │ │ └── output.log +│ ├── cron/ # Scheduled task persistence +│ │ └── .json │ └── agents/ │ ├── main/ │ │ ├── wire.jsonl @@ -95,6 +97,7 @@ The internal structure of a session directory includes: - `agents/agent-0/`, `agents/agent-1/`, etc.: subagent instance directories, each with its own `wire.jsonl`. Subagent ids are generated by a per-session incrementing counter (`agent-` followed by an integer starting from 0). - `logs/kimi-code.log`: the diagnostic log for this session. It only appears after a recorded diagnostic event; an ordinary conversation may not create this file. - `tasks/`: background task persistence directory. Each task stores its metadata (status, pid, exit code, etc.) in `tasks/.json`, with stdout and stderr written to `tasks//output.log`. Task ids use a `bash-` or `agent-` prefix followed by 8 random alphanumeric characters (for example, `bash-a1b2c3d4`). +- `cron/`: scheduled task persistence directory. Each task scheduled through `CronCreate` is mirrored to `cron/.json`, where `` is 8 lowercase hex characters. `kimi resume` rehydrates these tasks back into the in-memory scheduler. Tasks remain scoped to the resumed session id and do not bleed into new sessions. See [Scheduled tasks](../reference/tools.md#scheduled-tasks) for the tool surface. `sessionId` is restricted to `[A-Za-z0-9._-]+` and cannot be `.` or `..`, preventing path injection. The session list is sorted by `updatedAt` in descending order, where `updatedAt` is the maximum mtime of the directory and its key files. See [Sessions](../guides/sessions.md) for details. diff --git a/docs/en/configuration/env-vars.md b/docs/en/configuration/env-vars.md index 9496c54410..ac8b67bc34 100644 --- a/docs/en/configuration/env-vars.md +++ b/docs/en/configuration/env-vars.md @@ -76,6 +76,7 @@ When neither `KIMI_CODE_OAUTH_HOST` nor `KIMI_OAUTH_HOST` is set, the OAuth auth | `KIMI_CODE_PLUGIN_MARKETPLACE_URL` | Override the plugin marketplace JSON loaded by `/plugins`; useful for dev loopback servers, staging CDN files, or alternate marketplace directories | `https://cdn.kimi.com/kimi-code/plugins/marketplace.json`; also accepts `http://`, `file://` URLs, and local paths | | `KIMI_SHELL_PATH` | Override the absolute path to Git Bash (`bash.exe`) on Windows; only needed when auto-detection fails on Windows | None | | `KIMI_MODEL_MAX_COMPLETION_TOKENS` | Explicit hard cap for `max_completion_tokens` in a single-step LLM request. When unset, Kimi Code uses the safe remaining context window for models with a known context size. Set to `0` or a negative value to disable clamping entirely. **Currently effective only for providers of type `kimi`**; for Anthropic and other providers, use `[models.].max_output_size` instead (see [Config files](./config-files.md#models)) | Unset: computed from remaining context; unknown context falls back to `loop_control.reserved_context_size`, then 32000 | +| `KIMI_DISABLE_CRON` | Disable the scheduled-task tools entirely. Set to `1` to make `CronCreate` reject new schedules and short-circuit the scheduler's tick loop; existing tasks remain on disk but never fire while the variable is set. See [Scheduled tasks](../reference/tools.md#scheduled-tasks) | `1` to disable; unset by default | For example, to disable telemetry on a shared host: diff --git a/docs/en/guides/use-cases.md b/docs/en/guides/use-cases.md index d90cce51a1..d2feb9d075 100644 --- a/docs/en/guides/use-cases.md +++ b/docs/en/guides/use-cases.md @@ -101,6 +101,30 @@ Research the mainstream dependency injection options in TypeScript (tsyringe, in Use `--yolo` or `/yolo` to skip approvals, or set an allow list under [permission configuration](../configuration/config-files.md#permission) for a safer middle ground. +## Scheduled tasks and reminders + +Within an interactive session you can ask the assistant to set a one-shot reminder, run a task on a recurring schedule, or come back to you after a fixed delay. The agent maps the request to a 5-field cron expression in your local timezone and re-injects the prompt into the same session when it fires. + +``` +Remind me at 2:30pm today to check the deploy. +``` + +``` +Every weekday at 9am, summarize the latest CI failures and post the result to me. +``` + +``` +Hourly, poll the production health endpoint and let me know if anything looks off. +``` + +``` +In about 10 minutes, come back and verify the build finished. +``` + +Schedules live inside the session: closing the terminal is fine, and `kimi resume`-ing the same session reloads them and resumes the schedule. They do not carry over into a brand-new session. Recurring tasks auto-expire after seven days — the agent gets a `stale` notice on the final fire and will either let the task end or refresh it depending on your earlier instructions. Use `--yolo` if you want the agent to schedule tasks without approval prompts; otherwise each `CronCreate` asks for confirmation against the exact schedule and prompt. + +To see what is currently scheduled, just ask: `What scheduled tasks are pending?` (the agent runs the read-only `CronList` tool). To cancel one, ask the agent to drop it or quote its 8-character id. The full tool surface is documented under [Scheduled tasks](../reference/tools.md#scheduled-tasks), and the kill switch is `KIMI_DISABLE_CRON=1`. + ## Generating and maintaining documentation ``` diff --git a/docs/en/reference/tools.md b/docs/en/reference/tools.md index f113f20724..fc5cc7595e 100644 --- a/docs/en/reference/tools.md +++ b/docs/en/reference/tools.md @@ -102,3 +102,21 @@ Background task tools manage background tasks started via `Bash` or `Agent`. Whe **`TaskOutput`** returns the status and output of a specified task by `task_id`. The inline preview includes at most the most recent 32 KB of content; the full log is saved on disk, and the tool also returns `output_path` with a prompt to paginate it via `Read` (around 300 lines per page is recommended). Optional `block` (default false) and `timeout` (seconds to wait, default 30, range 0–3600) parameters can be used to wait for the task to finish before returning. In the response, `retrieval_status` is one of `success` / `timeout` / `not_ready`; tasks aborted by an external deadline timeout additionally include `timed_out: true` and `terminal_reason: timed_out`, and tasks explicitly terminated by `TaskStop` additionally include `stop_reason` and `terminal_reason: stopped`. **`TaskStop`** accepts `task_id` and an optional `reason` (reason for stopping, default `Stopped by TaskStop`). It is safe to call on a task that is already in a terminal state — it returns the current status without error. + +## Scheduled tasks + +Scheduled task tools let the agent re-inject a prompt into the current session at a future time, either once (a reminder) or on a recurring cron schedule (a periodic check, daily report, deploy watcher, etc.). Schedules are scoped to the session: they survive `kimi resume` of the same session, but never carry over into a brand-new session. A session is capped at 50 live scheduled tasks. Setting `KIMI_DISABLE_CRON=1` blocks the entire feature — see [Environment variables](../configuration/env-vars.md#runtime-switches). + +| Tool | Default approval | Description | +| --- | --- | --- | +| `CronCreate` | Requires approval | Schedule a prompt to fire at a future time | +| `CronList` | Auto-approved | List scheduled tasks | +| `CronDelete` | Requires approval | Cancel a scheduled task | + +**`CronCreate`** accepts `cron` (a standard 5-field cron expression in the user's local timezone: `minute hour day-of-month month day-of-week`), `prompt` (the text to re-inject when the schedule fires, capped at 8 KB UTF-8), and an optional `recurring` (default `true`; pass `false` for a one-shot reminder that fires once and then auto-deletes). The tool requires the expression to have at least one fire within five years and rejects one-shot tasks whose next fire would land more than ~350 days in the future (typically a pinned day/month that already passed this year). On success it returns an 8-character hex `id`, a human-readable `humanSchedule` (e.g. `every 5 minutes`), the `recurring` flag, and `nextFireAt` (the ISO timestamp of the next post-jitter fire). The approval scope is tied to the exact `(cron, prompt, recurring)` payload — re-approving once does not authorize later schedules. `CronCreate` is also blocked in Plan mode. + +To avoid synchronized fleet-wide fires on round minute marks, the scheduler applies a deterministic per-task jitter: recurring tasks shift forward by up to `min(10% of the period, 15 minutes)`; one-shot tasks landing on `:00` or `:30` shift earlier by up to 90 seconds. If the scheduler sleeps past several ideal fire times (laptop closed, long-running turn, etc.), it delivers only one fire when it wakes up — the prompt is wrapped in a `` envelope carrying `coalescedCount` so the agent reacts to "I missed N checks; only the latest state matters" instead of running the prompt N times. Recurring tasks older than seven days fire one final time with `stale="true"` on the envelope and the system then auto-deletes the task; to keep the schedule running, just call `CronCreate` again. One-shot tasks are never marked stale. + +**`CronList`** is read-only and takes no parameters. It returns one record per live task, each carrying `id`, `cron`, `humanSchedule`, the JSON-encoded `prompt` (truncated to ~200 UTF-8 bytes for context-window safety), `nextFireAt` (the post-jitter ISO timestamp the scheduler will actually fire on), `recurring`, `ageDays`, and `stale`. Records are separated by a line containing `---` in scheduling order. The empty case returns `cron_jobs: 0\nNo cron jobs scheduled.`. Use this to recall pending tasks after a context compaction, or to look up an `id` for `CronDelete`. + +**`CronDelete`** accepts a single `id` — the 8-character hex value returned by `CronCreate` or shown in `CronList`. For a recurring task it stops all future fires immediately; for a one-shot it cancels the pending fire. One-shot tasks that have already fired auto-delete themselves, so calling `CronDelete` on a fired one-shot returns `No cron job with id ...` — a signal that the model should call `CronList` rather than retry with the same id. Deletion is irreversible; recreate the task with `CronCreate` to undo. `CronDelete` is also blocked in Plan mode. diff --git a/docs/zh/configuration/data-locations.md b/docs/zh/configuration/data-locations.md index 460b61f6f9..f755be9f39 100644 --- a/docs/zh/configuration/data-locations.md +++ b/docs/zh/configuration/data-locations.md @@ -46,6 +46,8 @@ $KIMI_CODE_HOME (默认 ~/.kimi-code) │ │ ├── .json │ │ └── / │ │ └── output.log +│ ├── cron/ # 定时任务持久化 +│ │ └── .json │ └── agents/ │ ├── main/ │ │ ├── wire.jsonl @@ -95,6 +97,7 @@ OAuth 凭据以文件形式存放在数据根下的 `credentials/` 子目录, - `agents/agent-0/`、`agents/agent-1/` 等:子 Agent 实例的目录,各自包含 `wire.jsonl`。子 Agent id 由会话内的递增计数器生成(`agent-` 加从 0 起的整数)。 - `logs/kimi-code.log`:该会话的诊断日志。只有发生被记录的诊断事件时才会出现;普通对话不一定产生这个文件。 - `tasks/`:后台任务持久化目录。每个任务在 `tasks/.json` 保存元信息(状态、pid、退出码等),标准输出与标准错误写入 `tasks//output.log`。任务 id 格式为 `bash-` 或 `agent-` 前缀加 8 位随机字母数字(如 `bash-a1b2c3d4`)。 +- `cron/`:定时任务持久化目录。通过 `CronCreate` 安排的每个任务会镜像到 `cron/.json`,其中 `` 是 8 位小写 16 进制字符。执行 `kimi resume` 时这些任务会被重新加载到内存调度器中。任务仅绑定到恢复的会话 id,不会带入新会话。工具表面参见 [定时任务](../reference/tools.md#定时任务)。 `sessionId` 仅允许 `[A-Za-z0-9._-]+` 且不能为 `.` 或 `..`,以避免路径注入。会话列表按 `updatedAt` 倒序排序,`updatedAt` 取目录与各关键文件 mtime 的最大值。详见 [会话管理](../guides/sessions.md)。 diff --git a/docs/zh/configuration/env-vars.md b/docs/zh/configuration/env-vars.md index 3df6961cff..1296f9f3d7 100644 --- a/docs/zh/configuration/env-vars.md +++ b/docs/zh/configuration/env-vars.md @@ -76,6 +76,7 @@ OAuth 流程默认连接 Kimi 官方的认证与托管端点,下列变量可 | `KIMI_CODE_PLUGIN_MARKETPLACE_URL` | 覆盖 `/plugins` 加载的 plugin marketplace JSON,适合 dev loopback server、测试 CDN 文件或替换 marketplace 目录 | `https://cdn.kimi.com/kimi-code/plugins/marketplace.json`;也接受 `http://`、`file://` URL 和本地路径 | | `KIMI_SHELL_PATH` | 覆盖 Windows 上 Git Bash (`bash.exe`) 的绝对路径,仅在 Windows 自动探测失败时需要 | 无 | | `KIMI_MODEL_MAX_COMPLETION_TOKENS` | 单步 LLM 请求 `max_completion_tokens` 的显式硬上限。未设置时,对于已知上下文窗口的模型,Kimi Code 会使用安全的剩余上下文窗口;设为 `0` 或负数则完全禁用 clamp。**目前只对 `kimi` 类型的供应商生效**;Anthropic 等其它供应商请改用 `[models.].max_output_size`(详见 [配置文件](./config-files.md#models)) | 未设置:按剩余上下文计算;未知上下文窗口时回退到 `loop_control.reserved_context_size`,再回退到 32000 | +| `KIMI_DISABLE_CRON` | 整体禁用定时任务工具。设为 `1` 时 `CronCreate` 会拒绝新计划,调度器的 tick 循环也会立即短路;磁盘上已有的任务保留,但只要变量仍然生效就不会触发。详见 [定时任务](../reference/tools.md#定时任务) | `1` 表示禁用;默认未设置 | 例如在共享主机上禁用遥测: diff --git a/docs/zh/guides/use-cases.md b/docs/zh/guides/use-cases.md index 3c70365ba8..b8b3699d85 100644 --- a/docs/zh/guides/use-cases.md +++ b/docs/zh/guides/use-cases.md @@ -101,6 +101,30 @@ src/parser/markdown.ts 目前几乎没有测试。请补一组单元测试,覆 用 `--yolo` 或 `/yolo` 跳过审批,或用 [permission 配置](../configuration/config-files.md#permission) 给特定工具加白名单。 +## 定时任务与提醒 + +在交互式会话内,可以让助手设置一次性提醒、按周期运行某个任务,或者过一段时间后主动回到你这边。Agent 会根据你的请求生成一段本地时区下的 5 段 cron 表达式,并在触发时把 prompt 重新注入到同一个会话。 + +``` +下午 2:30 提醒我去查一下部署。 +``` + +``` +每个工作日上午 9 点,帮我汇总最近的 CI 失败情况,并把结果发我。 +``` + +``` +每小时巡检一次生产环境的健康端点,看到异常就告诉我。 +``` + +``` +大约 10 分钟之后再回来,确认一下构建是否结束。 +``` + +定时计划绑定在会话内:关掉终端没关系,对同一个会话执行 `kimi resume` 时会重新加载这些计划并继续按时触发;但它们不会带入全新的会话。周期任务在 7 天后会自动过期——Agent 会在最后一次触发时收到 `stale` 提示,并根据你之前的指示决定让任务结束还是续期。如果希望 Agent 安排任务时不再询问审批,可以使用 `--yolo`;否则每次 `CronCreate` 都会就具体的时间表与 prompt 内容请求确认。 + +想看当前安排了哪些任务时,直接问就行:「现在有哪些挂起的定时任务?」(Agent 会调用只读的 `CronList` 工具)。要取消某个任务,让 Agent 删除它或者引用对应的 8 位 id 即可。完整的工具表面见 [定时任务](../reference/tools.md#定时任务);整体关停开关是 `KIMI_DISABLE_CRON=1`。 + ## 生成与维护文档 ``` diff --git a/docs/zh/reference/tools.md b/docs/zh/reference/tools.md index 06ef48f76b..4d14b6571e 100644 --- a/docs/zh/reference/tools.md +++ b/docs/zh/reference/tools.md @@ -102,3 +102,21 @@ Plan 模式是一种受约束的工作状态:进入后 `Write` 与 `Edit` 工 **`TaskOutput`** 根据 `task_id` 返回指定任务的状态与输出。内联预览最多包含最近 32 KB 的内容;完整日志保存在磁盘上,工具会一并返回 `output_path` 并提示通过 `Read` 分页读取(建议每页约 300 行)。可选 `block`(默认 false)和 `timeout`(等待秒数,默认 30,取值范围 0–3600)参数可用于等待任务完成后再返回。返回结构中 `retrieval_status` 取 `success` / `timeout` / `not_ready`;任务因超时被外部 deadline 中止时会附带 `timed_out: true` 与 `terminal_reason: timed_out`,被 `TaskStop` 显式终止时会附带 `stop_reason` 与 `terminal_reason: stopped`。 **`TaskStop`** 接受 `task_id` 和可选的 `reason`(停止原因,默认 `Stopped by TaskStop`)。对已处于终止状态的任务也能安全调用,会直接返回当前状态而不报错。 + +## 定时任务 + +定时任务工具允许 Agent 把一段 prompt 在未来某个时间重新注入到当前会话中,既可以是一次性的提醒,也可以是按 cron 周期触发的任务(定期巡检、每日报表、部署监控等)。计划绑定到会话:同一会话执行 `kimi resume` 后仍然有效,但不会带入全新的会话。单个会话最多保留 50 个生效中的定时任务。设置 `KIMI_DISABLE_CRON=1` 可整体禁用该功能,详见 [环境变量](../configuration/env-vars.md#运行时开关)。 + +| 工具 | 默认审批 | 说明 | +| --- | --- | --- | +| `CronCreate` | 需审批 | 安排一个在未来时刻触发的 prompt | +| `CronList` | 自动放行 | 列出已安排的定时任务 | +| `CronDelete` | 需审批 | 取消已安排的定时任务 | + +**`CronCreate`** 接受 `cron`(用户本地时区下标准的 5 段 cron 表达式:`minute hour day-of-month month day-of-week`)、`prompt`(触发时要重新注入的文本,UTF-8 编码上限 8 KB)以及可选的 `recurring`(默认 `true`;传 `false` 表示一次性提醒,触发后自动删除)。工具会校验表达式在未来 5 年内至少有一次触发,并拒绝那些下次触发会落在 350 天之后的一次性任务(通常意味着指定的日/月在今年已经过去)。成功时返回 8 位 16 进制 `id`、人类可读的 `humanSchedule`(如 `every 5 minutes`)、`recurring` 标记,以及 `nextFireAt`(下次抖动后触发时间的 ISO 时间戳)。审批范围与 `(cron, prompt, recurring)` 这组精确载荷绑定——一次性批准不会授权后续的其它计划。`CronCreate` 在 Plan 模式下同样会被拦截。 + +为了避免整批用户在整点同时触发,调度器会按任务 id 做确定性抖动:周期任务向后偏移 `min(周期的 10%, 15 分钟)`;一次性任务若恰好落在 `:00` 或 `:30`,则向前提前最多 90 秒。如果调度器错过了若干理想触发时刻(笔记本合盖、长时间运行的轮次等),唤醒后只会触发一次——prompt 会被包裹在 `` 信封里并附带 `coalescedCount`,让 Agent 按「我错过了 N 次检查,只看最新状态」处理,而不是把 prompt 重复执行 N 次。周期任务存活超过 7 天后会以 `stale="true"` 的信封做最后一次触发,随后系统自动删除;想继续保留这条计划时,直接再调用一次 `CronCreate` 即可。一次性任务永远不会被标记为 stale。 + +**`CronList`** 是只读工具,不接受任何参数。它为每个生效中的任务返回一条记录,字段包括 `id`、`cron`、`humanSchedule`、JSON 编码的 `prompt`(出于上下文窗口安全考虑,截断到约 200 UTF-8 字节)、`nextFireAt`(抖动后调度器实际会触发的 ISO 时间戳)、`recurring`、`ageDays` 和 `stale`。记录之间用一行 `---` 分隔,按调度时间排列。空列表返回 `cron_jobs: 0\nNo cron jobs scheduled.`。上下文压缩后想要回忆挂起的任务,或者要找 `CronDelete` 所需的 `id`,都可以用这个工具。 + +**`CronDelete`** 只接受一个 `id`——即 `CronCreate` 返回或 `CronList` 中展示的 8 位 16 进制值。对周期任务,未来所有触发立即停止;对一次性任务,挂起的那次触发会被取消。已经触发过的一次性任务会自动删除,因此对已触发过的一次性任务再次调用 `CronDelete` 会返回 `No cron job with id ...`——这是提示模型应该先调用 `CronList` 而不是用同一个 id 重试。删除不可撤销,需要还原时只能再次 `CronCreate`。`CronDelete` 在 Plan 模式下同样会被拦截。