fix: finish empty Claude Code runs

This commit is contained in:
lucaronin
2026-04-23 14:15:15 +02:00
parent bb1b18686f
commit 3b4d9599d2
2 changed files with 44 additions and 1 deletions

View File

@@ -152,6 +152,43 @@ describe('aiAgentStreamCallbacks', () => {
])
})
it('finishes with a readable empty state when Claude exits without assistant text', () => {
const messages = createMessageStore([
{
id: 'msg-1',
userMessage: '/exit',
actions: [],
isStreaming: true,
},
])
const status = createStatusStore('thinking')
const callbacks = createStreamCallbacks({
messageId: 'msg-1',
vaultPath: '/vault',
setMessages: messages.setMessages,
setStatus: status.setStatus,
abortRef: { current: { aborted: false } },
responseAccRef: { current: '' },
toolInputMapRef: { current: new Map() },
fileCallbacksRef: { current: undefined },
})
callbacks.onDone()
expect(status.getStatus()).toBe('done')
expect(messages.getMessages()).toEqual([
{
id: 'msg-1',
userMessage: '/exit',
actions: [],
isStreaming: false,
reasoningDone: true,
response: 'Claude Code finished without returning a reply.',
},
])
})
it('ignores stream events after the request has been aborted', () => {
const messages = createMessageStore([
{

View File

@@ -20,6 +20,12 @@ export interface StreamMutationContext {
fileCallbacksRef: MutableRefObject<AgentFileCallbacks | undefined>
}
const EMPTY_CLAUDE_RESPONSE = 'Claude Code finished without returning a reply.'
function finalResponseText(response: string): string {
return response.trim() ? response : EMPTY_CLAUDE_RESPONSE
}
export function createStreamCallbacks(context: StreamMutationContext) {
const {
messageId,
@@ -95,7 +101,7 @@ export function createStreamCallbacks(context: StreamMutationContext) {
if (abortRef.current.aborted) return
setStatus('done')
const finalResponse = responseAccRef.current || undefined
const finalResponse = finalResponseText(responseAccRef.current)
updateMessage(setMessages, messageId, (message) => ({
...message,
isStreaming: false,