Skip to content

feat(tui): show message timestamps and response duration - #2795

Open
suntp wants to merge 21 commits into
MoonshotAI:mainfrom
suntp:feat/show-message-timestamp
Open

feat(tui): show message timestamps and response duration#2795
suntp wants to merge 21 commits into
MoonshotAI:mainfrom
suntp:feat/show-message-timestamp

Conversation

@suntp

@suntp suntp commented Aug 11, 2026

Copy link
Copy Markdown

Related Issue

Resolve #2705

Problem

Message timestamps used an indented layout that reduced transcript width, and assistant messages did not report total response duration. More importantly, reopening a session could reconstruct message timing from the current wall clock or an outer replay-record fallback, producing incorrect timestamps and elapsed durations. Legacy journals without timing must remain distinguishable and render without fabricated values.

What changed

  • Render user and assistant timestamps in single-line message headers and show assistant response duration.
  • Add the reloadable show_timestamp preference to ~/.kimi-code/tui.toml.
  • Restore replay timing from persisted journal records while keeping missing legacy timing undefined.
  • Keep timing as replay/display metadata so it does not enter model-facing conversation history.
  • Add live, replay, legacy-compatibility, SDK, and v2 transcript coverage.
  • Document the TUI preference in both English and Chinese.

The change is scoped to the CLI and replay pipeline; it does not alter the product Web transcript or message API behavior.

Why the core changes are required

The TUI cannot recover authoritative historical timing by itself. During replay, using the current wall clock fabricates a new timestamp, while using only the outer replay-record time can associate a message with the wrong journal event. Either fallback can make a reopened conversation show incorrect input/output times and response durations.

The journal message records are the source of truth for createdAt and completedAt. This PR preserves those optional fields while core reconstructs the session, carries them through replay metadata, and leaves them undefined for journals written by older versions. The TUI only formats the values it receives: historical sessions retain their original timing, and legacy sessions without timing display no timestamp or duration.

Terminal output

The screenshot below is rendered with the current TUI message components and covers all compatibility cases:

  1. A new live session shows the time and assistant duration.
  2. A historical session with persisted timing retains its original full timestamp and duration.
  3. A legacy session without timing fields remains readable and does not invent timing from the current clock.

Kimi Code TUI showing new, historical, and legacy message timing behavior

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

Validation

  • pnpm lint (0 errors)
  • Typecheck: CLI, SDK, agent-core, agent-core-v2, kap-server, transcript, and vis-web
  • Full tests: agent-core, agent-core-v2, CLI, kap-server, transcript, and vis-web
  • Targeted replay tests for timed and legacy sessions
  • Real persisted-session replay smoke test
  • pnpm --dir docs build
  • git diff --check

suntp added 18 commits August 5, 2026 23:48
@changeset-bot

changeset-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 7addf06

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

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

…estamp

# Conflicts:
#	apps/kimi-code/src/tui/commands/config.ts
#	apps/kimi-code/src/tui/commands/reload.ts
#	apps/kimi-code/src/tui/config.ts
#	apps/kimi-code/src/tui/types.ts
#	apps/kimi-code/test/tui/commands/update-preferences.test.ts
#	apps/kimi-code/test/tui/config.test.ts
@suntp
suntp marked this pull request as ready for review August 11, 2026 03:37

@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: 161c082bad

ℹ️ 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".

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

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

return block;
}

const showTimestamp = this.state.appState.showTimestamp ?? true;

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 Initialize the timestamp preference at startup

When tui.toml contains show_timestamp = false, createInitialAppState never copies input.tuiConfig.showTimestamp alongside the other preferences, so this fallback resolves to true on every normal launch. Timestamps therefore remain enabled until the user manually invokes /reload-tui or /reload; initialize appState.showTimestamp from the loaded TUI config.

Useful? React with 👍 / 👎.

host.setAppState({
editorCommand: config.editorCommand,
disablePasteBurst: config.disablePasteBurst,
showTimestamp: config.showTimestamp,

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 Update mounted messages when reloading the preference

When show_timestamp is changed and /reload-tui or /reload is invoked after messages exist, this only updates appState. UserMessageComponent and AssistantMessageComponent capture the setting in their constructors, their new setShowTimestamp methods are never called, and theme invalidation does not change that field; consequently old messages retain the previous visibility while new messages use the reloaded value. Propagate the setting to mounted message components or rebuild the transcript.

Useful? React with 👍 / 👎.

this._pendingAgentGroup = null;
this._pendingReadGroup = null;
const isReplaying = state.appState.isReplaying ?? false;
const timestamp = createdAt ?? (isReplaying ? undefined : Date.now());

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 Use the persisted step start for live response duration

For responses with model latency or thinking before the first assistant.delta, appendAssistantDelta creates the component here and stamps Date.now(), whereas replay derives createdAt from the persisted step.begin record. The same response therefore reports a shorter duration while live and a longer duration after reopening the session. Capture the turn.step.started time for the live block, or use an equivalent timing boundary consistently in both live rendering and replay.

Useful? React with 👍 / 👎.

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.

feat(tui): show message timestamps and response duration

1 participant