ios: add tool call stacking

This commit is contained in:
2026-06-12 00:26:21 -07:00
parent 95796646b1
commit 7436544a69
2 changed files with 312 additions and 4 deletions

View File

@@ -402,6 +402,70 @@ private func makeSearchDetail(id: String, date: Date, answer: String) -> SearchD
)
}
private func makeToolCallMessage(id: String, date: Date, summary: String = "Ran a tool") -> Message {
Message(
id: id,
createdAt: date,
role: .tool,
content: summary,
name: "web_search",
metadata: .object([
"kind": .string("tool_call"),
"toolCallId": .string("call-\(id)"),
"toolName": .string("web_search"),
"status": .string("completed"),
"summary": .string(summary),
"durationMs": .number(120)
])
)
}
@Test func transcriptRenderItemsGroupAdjacentToolCalls() async throws {
let date = Date(timeIntervalSince1970: 1_700_000_000)
let user = Message(id: "user-1", createdAt: date, role: .user, content: "Search this", name: nil)
let toolA = makeToolCallMessage(id: "tool-a", date: date, summary: "Search A")
let toolB = makeToolCallMessage(id: "tool-b", date: date, summary: "Search B")
let assistant = Message(id: "assistant-1", createdAt: date, role: .assistant, content: "Answer", name: nil)
let items = buildTranscriptRenderItems(from: [user, toolA, toolB, assistant])
#expect(items.count == 3)
guard case let .message(firstMessage) = items[0] else {
Issue.record("Expected the first item to remain a normal message")
return
}
#expect(firstMessage.id == "user-1")
guard case let .toolGroup(groupID, groupedMessages) = items[1] else {
Issue.record("Expected adjacent tool calls to be grouped")
return
}
#expect(groupID == "tool-a")
#expect(groupedMessages.map(\.id) == ["tool-a", "tool-b"])
guard case let .message(lastMessage) = items[2] else {
Issue.record("Expected the assistant response to remain a normal message")
return
}
#expect(lastMessage.id == "assistant-1")
}
@Test func transcriptRenderItemsKeepSingleToolCallsInline() async throws {
let date = Date(timeIntervalSince1970: 1_700_000_000)
let user = Message(id: "user-1", createdAt: date, role: .user, content: "Search this", name: nil)
let tool = makeToolCallMessage(id: "tool-a", date: date)
let assistant = Message(id: "assistant-1", createdAt: date, role: .assistant, content: "Answer", name: nil)
let items = buildTranscriptRenderItems(from: [user, tool, assistant])
#expect(items.count == 3)
guard case let .message(toolMessage) = items[1] else {
Issue.record("Expected a single tool call to use the existing inline chip")
return
}
#expect(toolMessage.id == "tool-a")
}
@MainActor
@Test func normalizedAPIBaseURLPreservesExplicitAPIPath() async throws {
let defaults = UserDefaults(suiteName: #function)!