refactor(agent-loop): drop the steering/message session event
Steer, inject, and followup now land as durable user/message events on the session surface; the steering/message event type and its ConversationNode kind are removed from the client projection. Update tests, docs, generated catalogs, and agent notes to match, and align the steering e2e fixture and prompt inventory assertions with the durable user/message landing.
This commit is contained in:
@@ -756,14 +756,6 @@ export function createTuiChat(
|
||||
trailAssistantStep()
|
||||
break
|
||||
}
|
||||
case 'steering/message': {
|
||||
const text = displayText(contentText(event.data.message.content).trim())
|
||||
if (text) {
|
||||
chat.addChild(new Spacer(1))
|
||||
chat.addChild(new UserMessageComponent(text, palette, mdTheme, 'Steering'))
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'step/start':
|
||||
startAssistantStep(event.data)
|
||||
break
|
||||
|
||||
@@ -1337,20 +1337,14 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: ' ' }], source: { kind: 'user' },
|
||||
}), { surfaceOp: 'append' })
|
||||
result.session.append('steering/message', {
|
||||
turn: 2,
|
||||
message: createUserMessage({
|
||||
content: [{ type: 'text', text: 'steering note' }],
|
||||
source: { kind: 'user' },
|
||||
}),
|
||||
}, { surfaceOp: 'append' })
|
||||
result.session.append('steering/message', {
|
||||
turn: 2,
|
||||
message: createUserMessage({
|
||||
content: [{ type: 'text', text: '' }],
|
||||
source: { kind: 'user' },
|
||||
}),
|
||||
}, { surfaceOp: 'append' })
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: 'steering note' }],
|
||||
source: { kind: 'user' },
|
||||
}), { surfaceOp: 'append' })
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: '' }],
|
||||
source: { kind: 'user' },
|
||||
}), { surfaceOp: 'append' })
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: 'user context' }], source: { kind: 'user' },
|
||||
}), { surfaceOp: 'append' })
|
||||
@@ -1448,7 +1442,8 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
})
|
||||
|
||||
expect(result.terminal.output).toContain('press enter to steer and esc to cancel')
|
||||
expect(result.terminal.output).toContain('Steering')
|
||||
// Steer content renders as a plain user bubble, with no steering label.
|
||||
expect(result.terminal.output).toContain('steering note')
|
||||
expect(result.terminal.output).toContain('user context')
|
||||
expect(result.terminal.output).toContain('Context · workspace-context')
|
||||
// The redundant `system-reminder` frame element is dropped: the source label
|
||||
@@ -1702,13 +1697,10 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
const index = result.agent.inbox.nextStep.findIndex(message => message.id === id)
|
||||
if (index >= 0) result.agent.inbox.splice('next-step', index, 1, [])
|
||||
}
|
||||
result.session.append('steering/message', {
|
||||
turn: 1,
|
||||
message: createUserMessage({
|
||||
content: [{ type: 'text', text }],
|
||||
source: { kind: 'user' },
|
||||
}),
|
||||
}, { surfaceOp: 'append' })
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text }],
|
||||
source: { kind: 'user' },
|
||||
}), { surfaceOp: 'append' })
|
||||
}
|
||||
|
||||
// Two steering messages queue while the turn runs.
|
||||
@@ -1740,16 +1732,12 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('1 queued')
|
||||
|
||||
// A steering/message has no inbox identity and therefore cannot consume a
|
||||
// pending slot by itself.
|
||||
// A user/message append alone cannot consume a pending slot by itself.
|
||||
result.terminal.output = ''
|
||||
result.session.append('steering/message', {
|
||||
turn: 1,
|
||||
message: createUserMessage({
|
||||
content: [{ type: 'text', text: 'continue: goal not reached' }],
|
||||
source: { kind: 'plugin', plugin: 'hooks' },
|
||||
}),
|
||||
}, { surfaceOp: 'append' })
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: 'continue: goal not reached' }],
|
||||
source: { kind: 'plugin', plugin: 'hooks' },
|
||||
}), { surfaceOp: 'append' })
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('1 queued')
|
||||
result.terminal.output = ''
|
||||
@@ -2266,13 +2254,10 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
it('tracks steering drains without a running status line', async () => {
|
||||
const result = await setup()
|
||||
const source = { kind: 'user' as const }
|
||||
result.session.append('steering/message', {
|
||||
turn: 1,
|
||||
message: createUserMessage({
|
||||
content: [{ type: 'text', text: 'early' }],
|
||||
source,
|
||||
}),
|
||||
}, { surfaceOp: 'append' })
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: 'early' }],
|
||||
source,
|
||||
}), { surfaceOp: 'append' })
|
||||
await tick()
|
||||
expect(result.terminal.output).not.toContain('queued')
|
||||
await dispose(result)
|
||||
@@ -3244,13 +3229,10 @@ describe('pi-tui chat lifecycle and transcript', () => {
|
||||
references: [{ sessionId: 'steering-source', label: 'Steering source' }],
|
||||
} as never,
|
||||
}), { surfaceOp: 'append' })
|
||||
result.session.append('steering/message', {
|
||||
turn: 1,
|
||||
message: createUserMessage({
|
||||
content: [{ type: 'text', text: 'visible steering prompt' }],
|
||||
source: { kind: 'user' },
|
||||
}),
|
||||
}, { surfaceOp: 'append' })
|
||||
result.session.append('user/message', createUserMessage({
|
||||
content: [{ type: 'text', text: 'visible steering prompt' }],
|
||||
source: { kind: 'user' },
|
||||
}), { surfaceOp: 'append' })
|
||||
await tick()
|
||||
expect(result.terminal.output).toContain('visible steering prompt')
|
||||
expect(result.terminal.output).toContain('Referenced sessions · Steering source (steering-source)')
|
||||
|
||||
Reference in New Issue
Block a user