diff --git a/.changeset/web-copy-user-message.md b/.changeset/web-copy-user-message.md
new file mode 100644
index 000000000..22b4803f5
--- /dev/null
+++ b/.changeset/web-copy-user-message.md
@@ -0,0 +1,5 @@
+---
+"@moonshot-ai/kimi-code": patch
+---
+
+Add a copy button to user messages in the web chat.
diff --git a/apps/kimi-web/src/components/chat/ChatPane.vue b/apps/kimi-web/src/components/chat/ChatPane.vue
index 5217731cc..f0876a539 100644
--- a/apps/kimi-web/src/components/chat/ChatPane.vue
+++ b/apps/kimi-web/src/components/chat/ChatPane.vue
@@ -385,6 +385,20 @@ function copyAssistantRun(index: number): void {
}).catch(() => {/* ignore */});
}
+function copyUserMessage(turn: ChatTurn): void {
+ const text = turn.text;
+ if (!text.trim()) return;
+ void copyTextToClipboard(text).then((ok) => {
+ if (!ok) return;
+ copiedTurn.value = turn.id;
+ if (copiedTimer !== null) clearTimeout(copiedTimer);
+ copiedTimer = setTimeout(() => {
+ copiedTimer = null;
+ copiedTurn.value = null;
+ }, 1400);
+ }).catch(() => {/* ignore */});
+}
+
function isStreamingRenderBlock(turn: ChatTurn, block: { sourceIndex: number }): boolean {
if (turn.id !== streamingTurnId.value) return false;
return block.sourceIndex === turnBlocks(turn).length - 1;
@@ -497,6 +511,21 @@ function isStreamingRenderBlock(turn: ChatTurn, block: { sourceIndex: number }):
+