fix(feedback): include session id in acknowledgement

This commit is contained in:
Turtle
2026-08-07 16:01:41 +08:00
parent a44009ec35
commit ef35c7f3b2
6 changed files with 17 additions and 10 deletions
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority; # side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with: # after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/feedback/command-feedback/README.md # pnpm run verify-translation-pairing --write packages/feedback/command-feedback/README.md
README.md: d7849e25fc62897e4ac6793f40bdc139adf9ba3d README.md: 96d2825f4b63c95ad6f45ca8b2e05d1fc5ae92aa
README.zh.md: c3b7b59d90d924de6042aeac1e7eec39457c6c83 README.zh.md: 5220afe68b1f0de50fd1368900758906ee6907c9
+1 -1
View File
@@ -8,7 +8,7 @@ Trigger-independent session feedback plus human-facing `/feedback` capture. The
| Input | Result | | Input | Result |
|---|---| |---|---|
| `/feedback <text>` | Append `feedback/record` and acknowledge with `Feedback recorded.` | | `/feedback <text>` | Append `feedback/record` and acknowledge with `Feedback recorded for session {id}`. |
| `/feedback` | Return a direct usage error. Whitespace-only input is treated as empty. | | `/feedback` | Return a direct usage error. Whitespace-only input is treated as empty. |
Surrounding whitespace is discarded, but feedback is otherwise unparsed: no truncation, case folding, or control words. Text that looks like another command, such as `/feedback /plan felt slow`, is feedback content. Repeated commands each produce their own event; nothing is replaced or merged. Surrounding whitespace is discarded, but feedback is otherwise unparsed: no truncation, case folding, or control words. Text that looks like another command, such as `/feedback /plan felt slow`, is feedback content. Repeated commands each produce their own event; nothing is replaced or merged.
@@ -8,7 +8,7 @@
| 输入 | 结果 | | 输入 | 结果 |
|---|---| |---|---|
| `/feedback <text>` | 追加 `feedback/record`,并以 `Feedback recorded.` 确认。 | | `/feedback <text>` | 追加 `feedback/record`,并以 `Feedback recorded for session {id}` 确认。 |
| `/feedback` | 返回一个直接用法错误。仅含空白的输入视为空输入。 | | `/feedback` | 返回一个直接用法错误。仅含空白的输入视为空输入。 |
前后空白会被丢弃,但除此之外,反馈内容不会被解析:没有截断、大小写折叠或控制词。看起来像另一个命令的文本(例如 `/feedback /plan felt slow`)就是反馈内容。重复执行命令时,每次都会产生一个事件;不会发生替换或合并。 前后空白会被丢弃,但除此之外,反馈内容不会被解析:没有截断、大小写折叠或控制词。看起来像另一个命令的文本(例如 `/feedback /plan felt slow`)就是反馈内容。重复执行命令时,每次都会产生一个事件;不会发生替换或合并。
@@ -41,14 +41,18 @@ export function recordFeedback(session: Session, text: string): void {
* Validate, record, and acknowledge one feedback entry. Returning an error * Validate, record, and acknowledge one feedback entry. Returning an error
* leaves no `feedback/record` event. * leaves no `feedback/record` event.
* @param invocation - receiving agent, raw command input, and UI cancellation. * @param invocation - receiving agent, raw command input, and UI cancellation.
* @returns an acknowledgement, or a usage error when no feedback text was supplied. * @returns an acknowledgement containing the receiving session id, or a usage error
* when no feedback text was supplied.
*/ */
function executeFeedbackCommand(invocation: CommandInvocation): CommandResult { function executeFeedbackCommand(invocation: CommandInvocation): CommandResult {
if (invocation.rawInput.trim().length === 0) { if (invocation.rawInput.trim().length === 0) {
return { kind: 'error', text: `Feedback text is required. ${USAGE}` } return { kind: 'error', text: `Feedback text is required. ${USAGE}` }
} }
recordFeedback(invocation.agent.session, invocation.rawInput) recordFeedback(invocation.agent.session, invocation.rawInput)
return { kind: 'success', text: 'Feedback recorded.' } return {
kind: 'success',
text: `Feedback recorded for session ${invocation.agent.session.id}`,
}
} }
/** Register the global `/feedback` command for every composed command adapter. */ /** Register the global `/feedback` command for every composed command adapter. */
@@ -93,7 +93,7 @@ describe('/feedback human command', () => {
const test = await harness() const test = await harness()
await expect(run(test, ' the diff view is unreadable')).resolves.toEqual({ await expect(run(test, ' the diff view is unreadable')).resolves.toEqual({
kind: 'success', kind: 'success',
text: 'Feedback recorded.', text: `Feedback recorded for session ${test.session.id}`,
}) })
expect(feedbackTexts(test.session)).toEqual(['the diff view is unreadable']) expect(feedbackTexts(test.session)).toEqual(['the diff view is unreadable'])
const commandRun = test.session.events.find(event => event.type === 'command/run') const commandRun = test.session.events.find(event => event.type === 'command/run')
@@ -141,8 +141,8 @@ describe('/feedback human command', () => {
test.ctx.commands.execute(test.agent, '/feedback second', signal), test.ctx.commands.execute(test.agent, '/feedback second', signal),
]) ])
expect(settled.map(item => item?.result)).toEqual([ expect(settled.map(item => item?.result)).toEqual([
{ kind: 'success', text: 'Feedback recorded.' }, { kind: 'success', text: `Feedback recorded for session ${test.session.id}` },
{ kind: 'success', text: 'Feedback recorded.' }, { kind: 'success', text: `Feedback recorded for session ${test.session.id}` },
]) ])
expect(feedbackTexts(test.session)).toEqual(['first', 'second']) expect(feedbackTexts(test.session)).toEqual(['first', 'second'])
}) })
@@ -87,7 +87,10 @@ describe('/feedback real Loader composition through cordis.yml', () => {
expect(context.commands.list(owner).map(command => command.name)).toContain('feedback') expect(context.commands.list(owner).map(command => command.name)).toContain('feedback')
const accepted = await context.commands.execute(owner, '/feedback the diff view is unreadable', signal) const accepted = await context.commands.execute(owner, '/feedback the diff view is unreadable', signal)
expect(accepted?.result).toEqual({ kind: 'success', text: 'Feedback recorded.' }) expect(accepted?.result).toEqual({
kind: 'success',
text: 'Feedback recorded for session feedback-loader-agent',
})
const rejected = await context.commands.execute(owner, '/feedback', signal) const rejected = await context.commands.execute(owner, '/feedback', signal)
expect(rejected?.result).toEqual({ expect(rejected?.result).toEqual({
kind: 'error', kind: 'error',