Visitar URL original
feat(feedback): disclose submitted files, attach request_id, and drop text-only option by 7Sageer · Pull Request #4876 · MoonshotAI/kimi-code · GitHub
Skip to content

feat(feedback): disclose submitted files, attach request_id, and drop text-only option - #4876

Open
7Sageer wants to merge 2 commits into
feat-custom-registry-endpointsfrom
feat-feedback-improvements
Open

7Sageer wants to merge 2 commits into
feat-custom-registry-endpointsfrom
feat-feedback-improvements

Conversation

@7Sageer

@7Sageer 7Sageer commented Nov 12, 2026 •

Copy link
Copy Markdown
Collaborator

Requirement or Bug

Stacked on #4875 (feat-custom-registry-endpoints).

用户在 TUI 执行 /feedback 提交问题时,过去默认首选项是 No attachment(仅发一句话文本,缺少排查所需的会话日志和模型调用 request_id),且附件选择界面未说明具体会上传哪些文件;同时引擎在 HTTP 请求失败结束回合时会丢失当跳 requestId。本 PR 移除 TUI 纯文本无附件选项,确认前列出当前 session 目录里的文件,同时在引擎层与 SessionExportService 中补齐主会话最近一次 request_id 采集。

Bug Reproduction Steps

N/A

Root Cause

N/A

Code Changes

基于 #4875 的 IFeedbackService,将会话文件列表预览和主会话最近一次 request_id 采集收敛在 SessionExportService 与 FeedbackService 内部完成,TUI 只负责展示 availability.session 并支持翻页。

  1. 引擎补齐失败回合及最近一次轮次 requestId:
    • AgentLoopRequestObserver.failRequest 先取 outcomeRequestId ?? apiRequestId(error) ?? observation.currentRequestId,写回请求 trace 并清理活跃显示 ID;turn.ended 和 api_error 均读取该 trace。
    • SessionRequestAttributionService.noteActiveRequest 与 RequestMetadataTracker 记录最近一次轮次请求的 lastRequestId(天然排除 source.type !== 'turn' 的 prediction 请求,并在恢复历史会话时重放 TurnEnded 的 requestId)。
  2. FeedbackService 仅通过 ISessionExportService 获取会话预览与 request_id:
    • IFeedbackService.availability(modelAlias, sessionId) 调用 SessionExportService.preview(sessionId)(先执行 flushLiveSession 再枚举文件、跳过 file-history)返回 { sessionId, sessionDir, files }。
    • FeedbackService.submit 从 SessionExportService.preview 读取最近一次 requestId 填入 info: { request_id }。
    • 若会话尚未落盘(如刚启动尚未发送首条消息),SessionExportService.export 在 includeGlobalLog: true 时仍打包 manifest.json 与全局日志生成 session.zip。
flowchart LR
    Headers["响应头 / 错误上的 requestId"] --> Attribution["SessionRequestAttributionService.lastRequestId"]
    Restore["RequestMetadataTracker<br/>(TurnEnded 恢复重放)"] --> Attribution
    Attribution --> Preview["SessionExportService.preview<br/>(flush + 跳过 file-history)"]
    Preview --> Availability["IFeedbackService.availability"]
    Availability --> Picker["TUI 附件确认弹窗"]
    Picker --> Submit["IFeedbackService.submit"]
    Preview -->|requestId| Submit
    Submit --> Export["SessionExportService.export"]
Loading

阅读指南:

  1. packages/agent-core-v2/src/app/auth/feedbackService.ts:看 availability 返回会话文件预览、submit 填入 { request_id }。
  2. packages/agent-core-v2/src/app/sessionExport/{sessionExportService.ts,zip.ts}:看 preview、目录遍历跳过 file-history 以及未落盘会话导出。
  3. packages/agent-core-v2/src/agent/loop/{requestObservation.ts,turnProjection.ts,requestMetadata.ts} 与 requestAttributionService.ts:看失败请求 ID 与最近一次轮次 lastRequestId 的记录。
  4. apps/kimi-code/src/tui/commands/prompts.ts 与 choice-picker.ts:看弹窗文件列表渲染与翻页。

Screenshots / Recordings

附件选择弹窗改动前后对比:

Before After
────────────────────────────────────────────────────────────────────────────
Share diagnostic info to help us investigate?
↑↓ navigate · Enter select · Esc cancel

❯ No attachment
Text feedback only
Logs only
Upload wire events and diagnostic logs from this session
Logs + codebase
Include your codebase for deeper diagnosis. Sensitive files are
automatically excluded — e.g. .env, config files, secret keys. We use
attachments only for diagnosis and never share them.

────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────────────────────────────────
Choose what to include with your feedback
↑↓ navigate · ←→ page · Enter select · Esc cancel

Your note, session ID, request ID, model, CLI version, OS, and shell are
always included. Choose whether to add diagnostics below.

❯ Current session logs
Upload the files listed below with your feedback
Session logs + project code
Also upload source files from this workspace to help reproduce the
issue. Secrets, dependencies, and build outputs are excluded.

Current session · ses-42

3 session files · showing 1–3
~/.kimi-code/sessions/wd_demo/ses-42/agents/main/wire.jsonl
~/.kimi-code/sessions/wd_demo/ses-42/logs/kimi-code.log
~/.kimi-code/sessions/wd_demo/ses-42/state.json

session.zip also includes the application log, which may mention other
sessions.

────────────────────────────────────────────────────────────────────────────

Behavior Changes and Affected Users

行为 改动前 改动后 依赖旧行为的人群 退路
TUI /feedback(及别名 /bug)附件选项 默认提供 No attachment、Logs only、Logs + codebase 三项,可仅提交纯文本而不上传会话日志 TUI 移除 No attachment,必选当前会话日志(默认选中)或再加项目代码(远端会话只有当前会话日志);FeedbackService 仍兼容编程调用传入 attachmentLevel: 'none' 不希望上传 session.zip 但此前用 /feedback 提交纯文本的 TUI 用户 Esc 取消后改用 GitHub Issues。changeset 已声明移除 TUI 纯文本选项
/feedback 确认前的文件披露与 session.zip 导出 静态说明会上传哪些类型,会话未创建时跳过导出 确认前通过 SessionExportService.preview 列出 flush 后的会话文件(排除 file-history);未创建会话时仍打包 manifest.json 与全局日志 需要在回车前核对会话文件的 TUI 用户 目录不可用时提示列表不可用;Esc 仍可取消
/feedback 选择 Session logs + project code 时的 Git 仓库扫描 git ls-files 路径仅过滤敏感文件,已跟踪的 dist/build/node_modules 文件仍会进 repo.zip scanWithGit 同步过滤 isIgnoredDirName 目录段,与弹窗披露文案一致 仓库中跟踪了构建产物或依赖目录并上传代码库的反馈用户 无
/feedback 提交体 info 不自动附带 request_id 引擎在 FeedbackService.submit 中自动从主 agent 最近一次非 prediction 轮次请求提取 requestId,填入 info: { request_id } /feedback 接收端与所有客户端 调用方显式传入 info 时以传入值为准;无 ID 时不传
模型 HTTP 失败结束回合时的 turn.ended.requestId 和 api_error.request_id 非流式报错或流式连接中断时可能丢失已拿到的 requestId 失败前把 outcome.requestId ?? apiRequestId(error) ?? trace.requestId 写回 trace,回合结束读 trace 消费 turn.ended 的 SDK/客户端及遥测 无

受影响模块与测试覆盖:

  • @moonshot-ai/agent-core-v2:feedback.test.ts 覆盖 availability 会话预览、request_id 注入及 attachmentLevel: 'none' 兼容;sessionExport.test.ts 覆盖 preview(排除 file-history、提取最近一次 requestId)及无会话时的全局日志导出;loop.test.ts 覆盖失败回合 turn.ended.requestId。
  • @moonshot-ai/kimi-code:feedback-input-dialog.test.ts、choice-picker.test.ts、kimi-tui-message-flow.test.ts 覆盖弹窗文件列表披露、翻页及 availability.session 透传。
验证详情
  • packages/oauth、packages/node-sdk、packages/agent-core-v2、apps/kimi-code 相关 14 个测试文件共 1024 项测试全部通过。
  • typecheck、lint:imports、gen:wire-manifest、oxlint --type-aware 零差异/零错误。

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.

Copilot AI balanced review requested due to automatic review settings November 12, 2026 12:25
@changeset-bot

changeset-bot Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fac67ef

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

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@7Hanrui

7Hanrui commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 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-13T11:41:56.231730Z fac67ef Manual request
ℹ️ 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.

@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: 31983281e4

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

const lines = [
'The following data will be submitted for troubleshooting:',
'- Feedback note and metadata (`session_id`, `request_id`, active model, CLI version, OS, shell)',
'- `session.zip`: conversation history (`wire.jsonl`), tool calls/results, session attachments, `logs/kimi-code.log`, and `logs/global/kimi-code.log`',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Disclose every file bundled in session.zip

For every user choosing Logs only or Logs + codebase, this notice understates what is uploaded: exportSessionDirectory recursively includes every file under the session directory except file-history blobs, including files such as state.json, plan files, background-task output, and the generated manifest.json. Because the new prompt presents this as the data that will be submitted, users can consent without being told about files actually present in session.zip; either disclose the complete recursive session-directory export or constrain the archive to the listed entries.

Useful? React with 👍 / 👎.

label: 'Logs + codebase',
description:
'Include your codebase for deeper diagnosis. Sensitive files are automatically excluded — e.g. .env, config files, secret keys. We use attachments only for diagnosis and never share them.',
'Also upload repo.zip from this workspace (excludes .git, node_modules, build outputs, .env*, private keys, and credential dirs). Attachments are used only for diagnosis and never shared.',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Do not promise that every .env file is excluded

When a workspace contains .env.example, .env.sample, or .env.template, selecting Logs + codebase uploads those files even though this text promises that .env* is excluded: isSensitivePath explicitly allows those three suffixes. Users may rely on this disclosure when deciding whether to upload a repository, so the copy must describe the exceptions accurately or the scanner must exclude all .env* files as promised.

Useful? React with 👍 / 👎.

Comment on lines +161 to +162
const wireText = await readFile(join(sessionDir, 'agents', 'main', 'wire.jsonl'), 'utf8');
for (const line of wireText.split('\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 loading the entire wire journal for feedback

For long-running sessions with a large wire.jsonl, opening /feedback now reads the complete journal into one UTF-8 string and then duplicates it into an array with split, even though only the latest 50 IDs are retained. This can add a long pause or substantial memory pressure before feedback is submitted; scan the file incrementally or read a bounded tail instead.

Useful? React with 👍 / 👎.

Comment thread apps/kimi-code/src/tui/kimi-tui.ts Outdated
Comment on lines +2393 to +2394
handleTurnEnded(event: TurnEndedEvent): void {
if (event.requestId !== undefined && event.requestId.length > 0) {

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 Include the in-flight request ID in feedback

When /feedback is invoked while a model request is still streaming or hung, the command executes immediately because it is registered as availability: 'always', but this list is populated only after turn.ended. The current request has neither a persisted usage.record nor a turn.ended entry yet, so the feedback submitted for that active failure omits the most relevant request_id; expose and collect the active request trace as well as completed-turn IDs.

Useful? React with 👍 / 👎.

): void {
const modelAlias = observation.context?.modelAlias ?? observation.config.resolved.modelAlias;
this.log.warn('llm request failed', {
const requestId = apiRequestId(error) ?? previousRequestId;

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 Read request IDs directly from APIStatusError

For ordinary non-2xx OpenAI or Anthropic responses, the SDK error decoder places the response ID in APIStatusError.requestId/details.requestId, while no llm.streaming.headers event is emitted, so previousRequestId is undefined. apiRequestId only inspects diagnostics and therefore this newly added requestId log field—and the corresponding api_error.request_id fallback—remains empty despite the error carrying the ID; include the direct status-error request ID before falling back to the trace.

Useful? React with 👍 / 👎.

@7Hanrui

7Hanrui commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

@codex review

@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: c10cb2e530

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

label: 'Logs + codebase',
description:
'Include your codebase for deeper diagnosis. Sensitive files are automatically excluded — e.g. .env, config files, secret keys. We use attachments only for diagnosis and never share them.',
'Also upload repo.zip from this workspace (excludes .git, node_modules, build outputs, .env files except .example/.sample/.template, private keys, and credential files/dirs). Attachments are used only for diagnosis and never shared.',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Stop promising tracked build outputs are excluded

For Git worktrees containing tracked files under dist, build, out, or even node_modules, this disclosure is inaccurate: scanWithGit uses git ls-files -co --exclude-standard, which includes tracked files, and its loop applies only isSensitivePath rather than the ignored-directory list. Users may therefore approve Logs + codebase believing these artifacts are absent when they are included in repo.zip; either filter ignored directory segments on the Git scan path or narrow the disclosure.

Useful? React with 👍 / 👎.

function buildFeedbackDisclosureMarkdown(sessionDir?: string): string {
const lines = [
'The following data will be submitted for troubleshooting:',
'- Feedback note and metadata (`session_id`, `request_id`, active model, CLI version, OS, shell)',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Disclose that up to 50 request IDs are submitted

For sessions with more than one recorded model request, this notice says only request_id is submitted, but collectFeedbackRequestInfo also sends a request_ids array containing up to 50 historical IDs. Users can therefore consent believing only the latest request identifier is included when identifiers from many earlier turns are sent; disclose the full list or submit only the singular field described here.

Useful? React with 👍 / 👎.

? undefined
: result.type === 'completed'
? this.lastRequestId
: (errorRequestId ?? this.activeRequestTrace?.requestId);

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 Preserve header request IDs when streamed requests fail

When a streaming response emits a request-ID header and then ends with a non-status failure whose serialized error lacks details.requestId, such as a connection or empty-response error, AgentLoopRequestObserver.failRequest uses the header ID only for logging and then clears the mutable request trace. Both fallbacks here are consequently undefined, so turn.ended and the wire journal omit the failed request ID and later /feedback submissions cannot attach it; preserve the final LlmOutcome.requestId or snapshot the trace before clearing it.

Useful? React with 👍 / 👎.

? undefined
: result.type === 'completed'
? this.lastRequestId
: (errorRequestId ?? this.activeRequestTrace?.requestId);

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 Preserve header request IDs when streamed requests fail

When a streaming response emits a request-ID header and then ends with a non-status failure whose serialized error lacks details.requestId, such as a connection or empty response, failRequest captures the header only for logging and then clears the mutable trace. This fallback is therefore undefined, so the resulting turn.ended record omits the request ID and /feedback cannot collect it; carry the failed outcome/header ID into the turn result before clearing the trace.

Useful? React with 👍 / 👎.

@7Hanrui

7Hanrui commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: bf4a32db36

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

@7Hanrui

7Hanrui commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

@codex review

@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: f983117bd4

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

Comment on lines 84 to +88
const FEEDBACK_ATTACHMENT_OPTIONS: readonly ChoiceOption[] = [
{ value: 'none', label: 'No attachment', description: 'Text feedback only' },
{
value: 'logs',
label: 'Logs only',
description: 'Upload wire events and diagnostic logs from this session',
label: 'Current session logs',
description: 'Upload the files listed below with your feedback',

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 Keep feedback usable before the first session exists

On a normal v2 startup, the TUI deliberately remains session-less until the first message (kimi-tui.ts:1297-1308), while /feedback remains always available (registry.ts:368-372). In that state the session ID is empty and no session directory can be resolved, but this picker now offers only attachment-bearing choices; after selection the fallback export uses id: '', so feedback submitted before the first prompt inevitably reports an attachment failure. Preserve a text-only choice for this state or create/require a session before showing these options.

AGENTS.md reference: AGENTS.md:L110-L112

Useful? React with 👍 / 👎.

Comment on lines +341 to +343
if (matchesKey(data, Key.pageUp) || matchesKey(data, Key.pageDown)) {
this.opts.onPreviewScroll?.(matchesKey(data, Key.pageUp) ? -1 : 1, true);
return;

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 Forward PageUp and PageDown without a preview scroller

PreviewChoicePickerComponent is also the base for the Tool Call Density and Thinking Display settings selectors, which do not provide onPreviewScroll. This new branch nevertheless returns unconditionally, so PageUp/PageDown no longer reach the underlying ChoicePickerComponent/SearchableList; for example, PageDown previously moved the Tool Call Density selection from Compact to Detailed but now does nothing. Consume these keys only when a preview-scrolling callback is present or handles them, and otherwise delegate to the picker.

AGENTS.md reference: AGENTS.md:L110-L112

Useful? React with 👍 / 👎.

@7Hanrui

7Hanrui commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

@codex review

@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: 69769d589b

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

Comment thread apps/kimi-code/src/tui/commands/info.ts Outdated
let preparedSession: PreparedFeedbackSessionArchive | undefined;
if (sessionDir !== undefined) {
try {
preparedSession = await prepareFeedbackSessionArchive(host);

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 Show progress before preparing large session archives

For sessions containing large attachments or task outputs, this await completes the full export and archiveFromExportedSession reads the entire resulting zip into memory before either the attachment picker or submission spinner appears. /feedback can therefore look frozen and consume archive-sized RAM even when the user ultimately cancels; previously the picker appeared before archive creation. Prepare it behind visible progress and hash the file as a stream rather than materializing the whole zip.

Useful? React with 👍 / 👎.

Comment thread apps/kimi-code/src/tui/commands/info.ts Outdated
Comment on lines +155 to +159
attachmentFailed = await submitFeedbackWithAttachments(
host,
res.feedbackId,
level,
preparedSession,

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 Refresh the archive after an active turn settles

When /feedback is opened while a request is streaming or hung—the command is registered as always available—the session archive is snapshotted before the picker opens and this same snapshot is uploaded after an arbitrary delay. Any wire events or logs written while the dialog is open, including the failure the user is reporting, are omitted from session.zip even though request IDs are collected later; re-export after confirmation or prevent this flow while a turn is active.

Useful? React with 👍 / 👎.

Comment on lines +252 to +253
if (record.type === 'usage.record' || record.type === 'turn.ended') {
push(record.requestId ?? record.error?.details?.requestId);

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 Exclude prompt-prediction IDs from feedback metadata

When the prompt_prediction experimental feature is enabled, every completed turn can be followed by a side-channel model request whose usage.record has usageScope: 'prediction'. This condition accepts that record like an ordinary turn request, so after prediction finishes info.request_id points to the prediction rather than the main request the user is reporting; filter prediction-scoped usage records while retaining turn-scoped request IDs.

Useful? React with 👍 / 👎.

@7Hanrui

7Hanrui commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

@codex review

@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: 26ab1e1275

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

Comment thread apps/kimi-code/src/tui/commands/info.ts Outdated
Comment on lines +90 to +94
const sessionDir = await resolveCurrentSessionDir(host);
let sessionFiles: readonly string[] | undefined;
if (sessionDir !== undefined) {
try {
sessionFiles = await listFeedbackSessionFiles(sessionDir);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Upload only the session files shown for consent

When an active turn or background task creates a session file while the attachment picker is open, this snapshot is all the user sees, but prepareAndUploadSessionArchive later calls exportSession, which recursively packages the then-current directory. Because the final code now intentionally exports after confirmation, a newly created plan, task output, or wire file can therefore be uploaded even though it was absent from the disclosure; bind the export to the displayed file set or re-list and reconfirm when it changes.

Useful? React with 👍 / 👎.

export async function listFeedbackSessionFiles(sessionDir: string): Promise<readonly string[]> {
let entries;
try {
entries = await readdir(sessionDir, { recursive: true, withFileTypes: 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 Prune file-history before recursive enumeration

For a long editing session with many file-history blobs, recursive readdir traverses and materializes every blob entry before the later filter removes them; file history stores a blob per recorded file version and has no per-session entry cap. Since handleFeedbackCommand awaits this before mounting the picker, merely opening /feedback can pause or consume substantial memory even if the user cancels, and a submitted report repeats the same traversal during export. Walk the tree while skipping file-history directories rather than filtering after recursive enumeration.

Useful? React with 👍 / 👎.

@7Sageer
7Sageer force-pushed the feat-feedback-improvements branch 2 times, most recently from 8904523 to f8e1ceb Compare November 13, 2026 10:01
@7Sageer
7Sageer changed the base branch from main to feat-custom-registry-endpoints November 13, 2026 10:01
@7Hanrui

7Hanrui commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

@codex review

@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: f8e1cebe00

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

Comment on lines +222 to +224
if (sessionId === undefined) return true;
if (this.sessionIndex !== undefined && (await this.sessionIndex.get(sessionId)) === undefined) {
return 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 Report when no session archive is uploaded

When /feedback is invoked before the first session is created, or while its ID is not yet in the session index, these branches return true, which is interpreted as a successful session archive upload. The picker simultaneously says that session.zip will still be uploaded, so the command reports success even though the backend receives no diagnostics. Unlike the earlier attachment-failure path, the fresh implementation now silently treats the skipped upload as successful; either present this as a text-only submission or return an upload failure/skip status that the TUI can disclose.

AGENTS.md reference: AGENTS.md:L131-L133

Useful? React with 👍 / 👎.

Comment on lines 128 to 130
const level = input.attachmentLevel;
if (level === undefined || level === 'none') {
if (level === undefined) {
return { kind: 'ok', feedbackId: result.feedbackId };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve none for existing feedback clients

A JavaScript caller or a client built against the previous exported FeedbackSubmitInput contract can still send attachmentLevel: 'none'; because this branch now exits only for undefined, that value reaches uploadAttachments, where every value other than 'logs' is handled as 'logs+codebase'. For an existing session or supplied workDir, upgrading therefore changes an explicit no-attachment submission into a silent upload of both session diagnostics and project files. Keep the runtime 'none' behavior, or reject it before any upload, even if the TUI no longer offers that option.

AGENTS.md reference: AGENTS.md:L123-L125

Useful? React with 👍 / 👎.

@7Sageer
7Sageer force-pushed the feat-feedback-improvements branch 2 times, most recently from 160b311 to d620e0c Compare November 13, 2026 11:01
@7Hanrui

7Hanrui commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

@codex review

@7Sageer
7Sageer force-pushed the feat-feedback-improvements branch from d620e0c to 3d7342e Compare November 13, 2026 11:11
@7Hanrui

7Hanrui commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

@codex review

@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: 3d7342eaf7

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


const summary = await this.index.get(input.sessionId);
if (summary === undefined) {
if (summary === undefined && input.includeGlobalLog !== 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.

P1 Badge Preserve missing-session errors for ordinary exports

When a user runs kimi export <missing-or-typoed-id> without --no-include-global-log, this condition now bypasses SESSION_NOT_FOUND because the CLI enables global-log inclusion by default (apps/kimi-code/src/cli/sub/export.ts:125-128). The command consequently prints a successful ZIP path even though the archive contains only the manifest/global log rather than the requested session. Keep the missing-session error for the public export path and use a feedback-specific global-log export for the pre-session case.

AGENTS.md reference: AGENTS.md:L131-L133

Useful? React with 👍 / 👎.

Comment on lines +190 to +193
const lastRequestId =
event.requestId ??
(event.error?.details?.['requestId'] as string | undefined) ??
state.lastRequestId;

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 Validate fallback request IDs before attribution

When a failed turn has a non-string error.details.requestId, which is permitted because error details are Record<string, unknown>, this assertion stores that value as lastRequestId; the subsequent commit passes it to noteActiveRequest, which calls .trim() and throws. A non-LLM Error2 or restored event using the same detail key can therefore break TurnEnded dispatch or disable attribution replay; accept the fallback only when it is a non-empty string.

Useful? React with 👍 / 👎.

@7Sageer
7Sageer marked this pull request as ready for review November 13, 2026 11:18
@pkg-pr-new

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

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

commit: fac67ef

@7Hanrui

7Hanrui commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

@codex review

@7Sageer
7Sageer changed the base branch from feat-custom-registry-endpoints to release/2026-11-13-2 November 13, 2026 11:25

@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: fa946090c7

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

session === undefined
? undefined
: (direction) => {
scroll = Math.max(0, Math.min(maxScroll, scroll + direction * 5));

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 Keep preview paging on five-file boundaries

When the session file count is not divisible by five, clamping to files.length - 5 creates overlapping, asymmetric pages: with 12 files, moving forward from offset 5 lands at 7 (showing items 8–12), and moving back then lands at 2 rather than returning to offset 5. This makes the advertised next/previous-page controls inconsistent; clamp to page-aligned offsets or track a page index instead.

Useful? React with 👍 / 👎.

…sion ids

The global-log-only fallback exists for feedback submissions without an
active session (empty id). Scoping it to empty ids restores the 40401
envelope that kap-server's export route promises for unknown sessions.
@7Sageer
7Sageer force-pushed the feat-feedback-improvements branch from fa94609 to fac67ef Compare November 13, 2026 11:35
@7Hanrui

7Hanrui commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

@codex review

@7Sageer
7Sageer changed the base branch from release/2026-11-13-2 to feat-custom-registry-endpoints November 13, 2026 11:38

@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: fac67efc88

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

Comment on lines 139 to 143
export type {
FeedbackAttachmentLevel,
FeedbackAvailability,
FeedbackSessionPreview,
FeedbackSubmitInput,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve the existing feedback SDK exports

For existing SDK consumers, this replacement removes the exported KimiAuth*Feedback* types while the same commit also deletes KimiAuthFacade.submitFeedback, createFeedbackUploadUrl, and completeFeedbackUpload; integrations using harness.auth therefore stop compiling or fail at runtime after what is released only as a CLI patch. Preserve compatibility shims or declare and version this as a breaking API change instead of replacing the public contract.

AGENTS.md reference: AGENTS.md:L122-L124

Useful? React with 👍 / 👎.

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.

4 participants