diff --git a/.changeset/web-plan-review-card.md b/.changeset/web-plan-review-card.md new file mode 100644 index 000000000..bb363cd2e --- /dev/null +++ b/.changeset/web-plan-review-card.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": minor +--- + +Show the plan body and approach choices in the plan review card when exiting plan mode in the web UI. diff --git a/apps/kimi-web/src/api/daemon/eventReducer.ts b/apps/kimi-web/src/api/daemon/eventReducer.ts index 77d8831f2..f1f68cc14 100644 --- a/apps/kimi-web/src/api/daemon/eventReducer.ts +++ b/apps/kimi-web/src/api/daemon/eventReducer.ts @@ -43,6 +43,10 @@ export interface KimiClientState { activeSessionId?: string; messagesBySession: Record; approvalsBySession: Record; + /** Preserved `plan_review` displays keyed by toolCallId. Plan content survives + * approval resolution so the ExitPlanMode tool card can keep rendering the + * plan (approved / rejected / revised) instead of losing it. */ + planReviewByToolCallId: Record; questionsBySession: Record; tasksBySession: Record; goalBySession: Record; @@ -58,6 +62,7 @@ export function createInitialState(): KimiClientState { activeSessionId: undefined, messagesBySession: {}, approvalsBySession: {}, + planReviewByToolCallId: {}, questionsBySession: {}, tasksBySession: {}, goalBySession: {}, @@ -77,6 +82,7 @@ function cloneState(s: KimiClientState): KimiClientState { sessions: [...s.sessions], messagesBySession: { ...s.messagesBySession }, approvalsBySession: { ...s.approvalsBySession }, + planReviewByToolCallId: { ...s.planReviewByToolCallId }, questionsBySession: { ...s.questionsBySession }, tasksBySession: { ...s.tasksBySession }, goalBySession: { ...s.goalBySession }, @@ -454,6 +460,21 @@ export function reduceAppEvent( if (!exists) { next.approvalsBySession[sid] = [...list, event.approval]; } + // Preserve a plan_review display so the plan stays visible in the + // ExitPlanMode tool card after the approval resolves. + const display = event.approval.display as + | { kind?: unknown; plan?: unknown; path?: unknown } + | null + | undefined; + if (display?.kind === 'plan_review' && typeof display.plan === 'string' && display.plan.length > 0) { + next.planReviewByToolCallId = { + ...next.planReviewByToolCallId, + [event.approval.toolCallId]: { + plan: display.plan, + path: typeof display.path === 'string' ? display.path : undefined, + }, + }; + } break; } diff --git a/apps/kimi-web/src/components/chat/ApprovalCard.vue b/apps/kimi-web/src/components/chat/ApprovalCard.vue index a17cf5781..30f281eaa 100644 --- a/apps/kimi-web/src/components/chat/ApprovalCard.vue +++ b/apps/kimi-web/src/components/chat/ApprovalCard.vue @@ -1,9 +1,10 @@