Skip to content

fix(kap-server): show only the scheduled prompt in cron-fired user messages - #4780

Open
wbxl2000 wants to merge 2 commits into
mainfrom
fix/cron-message-text
Open

wbxl2000 wants to merge 2 commits into
mainfrom
fix/cron-message-text

Conversation

@wbxl2000

@wbxl2000 wbxl2000 commented Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator

Requirement or Bug

定时任务触发的那一轮,开头的 user_message.text 是写给模型的内部包装:

<cron-fire jobId="…" cron="0 3 * * *" recurring="true" coalescedCount="1" stale="false">
<prompt>
nightly report
</prompt>
</cron-fire>

任务 id、cron 表达式、是否重复这些信息已经结构化地放在 origin({ kind: "cron", job_id, schedule, recurring, coalesced_count, stale })里。所以每个按 KAP 渲染对话的客户端都得自己再解析一遍这段 XML,才能显示用户写的那句提示词。code-app 现在就在 userMessageText.ts 里维护着一份 extractCronPrompt。

Bug Reproduction Steps

  1. 让 agent 用 CronCreate 建一个定时任务,等它触发。
  2. 订阅这个会话:这一轮开头的 user_message.text 是整段 <cron-fire>…</cron-fire>,而不是提示词本身。

Root Cause

定时任务触发时,引擎用 renderCronFireXml 把提示词包进 <cron-fire> 交给模型。kap-server 的 userMessageItem 把文本原样放进 text;它对附件提示、媒体标签都做了剥离,唯独没有处理这层包装。

Code Changes

 userMessageItem(..., origin, content)
   presented = originOf(origin)
-  text = joined text parts
+  text = presented.kind === 'cron' ? prompt inside a complete <cron-fire> envelope : joined text parts

只有文本恰好是 renderCronFireXml 生成的完整包装(首行 <cron-fire …>、结尾 </prompt>\n</cron-fire>)时才拆,提示词里自己带的 <prompt> 标签原样保留;不是完整包装时(例如没有包装的旧数据),文本保持原样。

过渡期的一个边角情况:在 CLI 自带的 dist-web 更新之前,旧客户端还会对文本再跑一遍自己的解析器。如果定时任务的提示词里本身就带 <prompt>…</prompt>,显示时会被多拆一层(只影响显示,给模型的内容不变)。code-app bump 子模块时会删掉客户端的解析器。

Behavior Changes and Affected Users

Behavior Before After Who relies on the old behavior Escape hatch
定时任务触发轮的 user_message.text 整段 <cron-fire> XML 只有提示词 无:code-app 的解析对两种形状都适用;TUI 和 VS Code 不走这条路径 不需要
没有包装的定时任务消息 原样 不变 — —
给模型的上下文 带包装 不变,只改了下发给客户端的条目 — —

受影响模块:packages/kap-server/src/services/conversation/conversationItems.ts。

测试:test/services/conversation.test.ts 里定时任务的用例改用真实的 <cron-fire> 包装文本,断言 text 是提示词本身;提示词里嵌套的 <prompt> 标签原样保留;没有包装的消息保持原样。

code-app bump 子模块之后,可以删掉客户端的 extractCronPrompt。

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue (external PRs: issue must have a maintainer's /approve).
  • I have added tests that prove my feature works.
  • The behavior-change table above is complete, and every removed behavior or flipped default is named in the changeset and either has an escape hatch or was explicitly approved by a maintainer in this PR.
  • Ran gen-changesets skill, or this PR needs no changeset. 现有客户端已经自己剥掉包装,用户看不到变化,不写。
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 62b8e72

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-09T18:14:22.687847Z 62b8e72 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@pkg-pr-new

pkg-pr-new Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@62b8e72
npx https://pkg.pr.new/@moonshot-ai/kimi-code@62b8e72

commit: 62b8e72

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 740bbc8dae

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

placement,
origin: presented,
text: text.join('\n'),
text: presented.kind === 'cron' ? cronPromptOf(text.join('\n')) : text.join('\n'),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid double-stripping prompts in existing web clients

When a scheduled prompt itself contains <prompt>\n...\n</prompt> (for example, because it asks the agent to process that XML), the server now unwraps it once, but the shipped web client still calls its equivalent extractor for every cron item (apps/kimi-code/dist-web/assets/index-3waulFY5.js:162-169). Previously that client received the outer <cron-fire> envelope, so its single extraction returned the complete original prompt; with this change, its second extraction silently discards everything outside the prompt's inner tags. Preserve the old payload for existing clients, or make extraction require a complete cron envelope before changing the server-side shape.

AGENTS.md reference: AGENTS.md:L121-L123

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

已在 62b8e72 收紧服务端的拆包:只有文本恰好是 renderCronFireXml 生成的完整包装时才拆,提示词里自己带的 <prompt> 标签原样保留,并加了嵌套标签的用例。旧版 dist-web 对这种提示词还会多拆一层,这是过渡期内只影响显示的边角情况(给模型的内容不变)。code-app bump 子模块时会删掉客户端的解析器,之后 CLI 的 web dist 同步进来就消失了。这一点已写进 PR 描述,是否接受这个过渡期由维护者决定。

This branch has not been deployed

No deployments
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