Skip to content

Commit 3b4e7b0

Browse files
authored
Merge pull request #82 from mcintyre94/test-claude-behavior-issue-3b71887e
Fix quick chat blank response when Claude hits max-turns limit
2 parents b822e81 + 8ed26e9 commit 3b4e7b0

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

Wisp/ViewModels/QuickChatViewModel.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ final class QuickChatViewModel {
6060

6161
var claudeCmd = "claude -p --verbose --output-format stream-json --dangerously-skip-permissions"
6262
claudeCmd += " --disallowedTools \"Bash,Write,Edit,MultiEdit,WebSearch,WebFetch\""
63-
claudeCmd += " --max-turns 3"
63+
claudeCmd += " --max-turns 5"
6464
claudeCmd += " --model \(modelId)"
6565
if let sid = sessionId {
6666
claudeCmd += " --resume \(sid)"
@@ -155,8 +155,13 @@ final class QuickChatViewModel {
155155
}
156156
}
157157
case .result(let resultEvent):
158-
if resultEvent.isError == true, response.isEmpty {
159-
error = "Claude returned an error"
158+
let isErrorResult = resultEvent.isError == true || (resultEvent.subtype != nil && resultEvent.subtype != "success")
159+
if isErrorResult, response.isEmpty {
160+
if resultEvent.subtype == "error_max_turns" {
161+
error = "Claude hit the turn limit without responding — try a simpler question"
162+
} else {
163+
error = "Claude returned an error"
164+
}
160165
}
161166
default:
162167
break

WispTests/QuickChatViewModelTests.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,30 @@ struct QuickChatViewModelTests {
106106
#expect(vm.error == nil)
107107
}
108108

109+
@Test func handle_maxTurnsResult_setsSpecificErrorWhenResponseEmpty() {
110+
let vm = makeViewModel()
111+
let event = ClaudeStreamEvent.result(ClaudeResultEvent(
112+
type: "result", subtype: "error_max_turns",
113+
sessionId: "sess-abc", isError: false,
114+
durationMs: 100, numTurns: 3, result: nil
115+
))
116+
vm.handle(event)
117+
#expect(vm.error?.contains("turn limit") == true)
118+
}
119+
120+
@Test func handle_maxTurnsResult_doesNotSetErrorWhenResponseNonEmpty() {
121+
let vm = makeViewModel()
122+
vm.handle(assistantEvent("Some partial answer"))
123+
let event = ClaudeStreamEvent.result(ClaudeResultEvent(
124+
type: "result", subtype: "error_max_turns",
125+
sessionId: "sess-abc", isError: false,
126+
durationMs: 100, numTurns: 3, result: nil
127+
))
128+
vm.handle(event)
129+
#expect(vm.error == nil)
130+
#expect(vm.response == "Some partial answer")
131+
}
132+
109133
@Test func send_withNilSessionId_setsIsStreamingTrue() {
110134
let vm = makeViewModel(sessionId: nil)
111135
vm.question = "What files are here?"

0 commit comments

Comments
 (0)