diff --git a/Example.swiftpm/Package.resolved b/Example.swiftpm/Package.resolved index a91bbf1..5ebc559 100644 --- a/Example.swiftpm/Package.resolved +++ b/Example.swiftpm/Package.resolved @@ -1,12 +1,21 @@ { "pins" : [ + { + "identity" : "asynchttpkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/fumito-ito/AsyncHTTPKit.git", + "state" : { + "revision" : "2a8b270746e7e1fe7b350db26e04be43eb3030e1", + "version" : "0.0.1" + } + }, { "identity" : "swiftyjsonlines", "kind" : "remoteSourceControl", "location" : "https://github.com/fumito-ito/SwiftyJSONLines.git", "state" : { - "revision" : "fb957dada1e920b6916c7083e99895f8f7fc885a", - "version" : "0.0.3" + "revision" : "a96f39c20f9d9ed5abf3a4dc3294e69d0e3521cc", + "version" : "0.0.4" } } ], diff --git a/Example.swiftpm/Package.swift b/Example.swiftpm/Package.swift index f1a4a58..de98a57 100644 --- a/Example.swiftpm/Package.swift +++ b/Example.swiftpm/Package.swift @@ -10,7 +10,7 @@ import AppleProductTypes let package = Package( name: "Example", platforms: [ - .iOS("17.0") + .iOS("18.0") ], products: [ .iOSApplication( diff --git a/Package.resolved b/Package.resolved index a91bbf1..baedf1c 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,14 +1,15 @@ { + "originHash" : "d61a94dd8be384d28c66ae7d8255335932a2cc4a4de7aed63c898ec3ce7da233", "pins" : [ { "identity" : "swiftyjsonlines", "kind" : "remoteSourceControl", "location" : "https://github.com/fumito-ito/SwiftyJSONLines.git", "state" : { - "revision" : "fb957dada1e920b6916c7083e99895f8f7fc885a", - "version" : "0.0.3" + "revision" : "a96f39c20f9d9ed5abf3a4dc3294e69d0e3521cc", + "version" : "0.0.4" } } ], - "version" : 2 + "version" : 3 } diff --git a/Package.swift b/Package.swift index 7049c13..ef2644f 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 5.9 +// swift-tools-version: 6.0 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription @@ -6,8 +6,8 @@ import PackageDescription let package = Package( name: "AnthropicSwiftSDK", platforms: [ - .iOS(.v17), - .macOS(.v14) + .iOS(.v18), + .macOS(.v15) ], products: [ // Products define the executables and libraries a package produces, making them visible to other packages. diff --git a/Sources/AnthropicSwiftSDK-TestUtils/HTTPMock.swift b/Sources/AnthropicSwiftSDK-TestUtils/HTTPMock.swift index 225a885..c120fe0 100644 --- a/Sources/AnthropicSwiftSDK-TestUtils/HTTPMock.swift +++ b/Sources/AnthropicSwiftSDK-TestUtils/HTTPMock.swift @@ -16,7 +16,7 @@ public enum MockInspectType { } public class HTTPMock: URLProtocol { - public static var inspectType: MockInspectType = .none + nonisolated(unsafe) public static var inspectType: MockInspectType = .none public override class func canInit(with request: URLRequest) -> Bool { return true diff --git a/Sources/AnthropicSwiftSDK/AnthropicAPIError.swift b/Sources/AnthropicSwiftSDK/AnthropicAPIError.swift index e815c9f..8de32b2 100644 --- a/Sources/AnthropicSwiftSDK/AnthropicAPIError.swift +++ b/Sources/AnthropicSwiftSDK/AnthropicAPIError.swift @@ -10,7 +10,7 @@ import Foundation /// The error returned from the Anthropic API /// /// for more detail, see https://docs.anthropic.com/claude/reference/errors -public enum AnthropicAPIError: String, Decodable, Error { +public enum AnthropicAPIError: String, Decodable, Error, Sendable { case invalidRequestError = "invalid_request_error" case authenticationError = "authentication_error" case permissionError = "permission_error" diff --git a/Sources/AnthropicSwiftSDK/ClientError.swift b/Sources/AnthropicSwiftSDK/ClientError.swift index f7720ea..a9c3bc7 100644 --- a/Sources/AnthropicSwiftSDK/ClientError.swift +++ b/Sources/AnthropicSwiftSDK/ClientError.swift @@ -8,7 +8,7 @@ import Foundation /// Errors in swift SDK -public enum ClientError: Error { +public enum ClientError: Error, @unchecked Sendable { /// Received unknown event in Stream. case unknownStreamingEvent(String) /// Received in Stream with unknown line type. diff --git a/Sources/AnthropicSwiftSDK/Entity/Batch/BatchRequestCounts.swift b/Sources/AnthropicSwiftSDK/Entity/Batch/BatchRequestCounts.swift index ef8591c..11b36cc 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Batch/BatchRequestCounts.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Batch/BatchRequestCounts.swift @@ -12,7 +12,7 @@ public struct BatchRequestCounts: Decodable { /// Number of requests in the Message Batch that have completed successfully. /// /// This is zero until processing of the entire Message Batch has ended. - let succeeeded: Int + let succeeded: Int /// Number of requests in the Message Batch that encountered an error. /// /// This is zero until processing of the entire Message Batch has ended. diff --git a/Sources/AnthropicSwiftSDK/Entity/Content/Content.swift b/Sources/AnthropicSwiftSDK/Entity/Content/Content.swift index ee9d941..da212c7 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Content/Content.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Content/Content.swift @@ -8,7 +8,7 @@ import Foundation /// Type of content block. -public enum ContentType: String { +public enum ContentType: String, Sendable { /// single string case text /// image content @@ -26,7 +26,7 @@ public enum ContentType: String { /// Each input message `content` may be either a single `string` or an array of content blocks, where each block has a specific `type`. Using a `string` for `content` is shorthand for an array of one content block of type `text`. /// /// Starting with Claude 3 models, you can also send `image` content blocks. -public enum Content { +public enum Content: Sendable { /// a single string case text(String, cacheControl: CacheControl? = nil) /// currently supported the `base64` source type for images, and the `image/jpeg`, `image/png`, `image/gif`, and `image/webp` media types. diff --git a/Sources/AnthropicSwiftSDK/Entity/Content/DocumentContent.swift b/Sources/AnthropicSwiftSDK/Entity/Content/DocumentContent.swift index 4534f5b..a22db8d 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Content/DocumentContent.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Content/DocumentContent.swift @@ -6,12 +6,12 @@ // import Foundation -public struct DocumentContent { - public enum DocumentContentType: String, Codable { +public struct DocumentContent: Sendable { + public enum DocumentContentType: String, Codable, Sendable { case base64 } - public enum DocumentContentMediaType: String, Codable { + public enum DocumentContentMediaType: String, Codable, Sendable { case pdf = "application/pdf" } diff --git a/Sources/AnthropicSwiftSDK/Entity/Content/ImageContent.swift b/Sources/AnthropicSwiftSDK/Entity/Content/ImageContent.swift index d265393..6fa4f8a 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Content/ImageContent.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Content/ImageContent.swift @@ -8,14 +8,14 @@ import Foundation /// Object for image content. -public struct ImageContent { +public struct ImageContent: Sendable { /// currently support the base64 source type for images - public enum ImageContentType: String, Codable { + public enum ImageContentType: String, Codable, Sendable { case base64 } /// currently support the image/jpeg, image/png, image/gif, and image/webp media types. - public enum ImageContentMediaType: String, Codable { + public enum ImageContentMediaType: String, Codable, Sendable { case jpeg = "image/jpeg" case png = "image/png" case gif = "image/gif" diff --git a/Sources/AnthropicSwiftSDK/Entity/Content/ToolResultContent.swift b/Sources/AnthropicSwiftSDK/Entity/Content/ToolResultContent.swift index f2cc40f..e5ed8f6 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Content/ToolResultContent.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Content/ToolResultContent.swift @@ -7,7 +7,7 @@ import Foundation -public struct ToolResultContent { +public struct ToolResultContent: Sendable { /// The `id of the tool use request this is a result for public let toolUseId: String /// The result of the tool, as a string (e.g. `"content": "15 degrees"` ) or diff --git a/Sources/AnthropicSwiftSDK/Entity/Content/ToolUseContent.swift b/Sources/AnthropicSwiftSDK/Entity/Content/ToolUseContent.swift index 0d7ac3a..15469f5 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Content/ToolUseContent.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Content/ToolUseContent.swift @@ -7,7 +7,7 @@ import Foundation -public struct ToolUseContent { +public struct ToolUseContent: @unchecked Sendable { /// A unique identifier for this particular tool use block. /// This will be used to match up the tool results later. public let id: String diff --git a/Sources/AnthropicSwiftSDK/Entity/Message.swift b/Sources/AnthropicSwiftSDK/Entity/Message.swift index c15fe10..3f5a6e9 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Message.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Message.swift @@ -14,7 +14,7 @@ import Foundation /// Each input message must be an object with a `role` and `content`. You can specify a single `user`-role message, or you can include multiple `user` and `assistant` messages. The first message must always use the `user` role. /// /// If the final message uses the `assistant` role, the response content will continue immediately from the content in that message. This can be used to constrain part of the model's response. -public struct Message: Codable { +public struct Message: Codable, Sendable { /// role of the message public let role: Role /// content of the message diff --git a/Sources/AnthropicSwiftSDK/Entity/Model.swift b/Sources/AnthropicSwiftSDK/Entity/Model.swift index 8e3f193..effe43b 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Model.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Model.swift @@ -10,7 +10,7 @@ import Foundation /// The model that will complete your prompt. /// /// See [models](https://docs.anthropic.com/claude/docs/models-overview) for additional details and options. -public enum Model { +public enum Model: Sendable { /// Most powerful model for highly complex tasks // swiftlint:disable:next identifier_name case claude_3_Opus diff --git a/Sources/AnthropicSwiftSDK/Entity/Role.swift b/Sources/AnthropicSwiftSDK/Entity/Role.swift index a5f5689..b89f3d2 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Role.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Role.swift @@ -7,7 +7,7 @@ import Foundation -public enum Role: String, Codable { +public enum Role: String, Codable, Sendable { case user case assistant } diff --git a/Sources/AnthropicSwiftSDK/Entity/StopReason.swift b/Sources/AnthropicSwiftSDK/Entity/StopReason.swift index 9f28dcb..624820e 100644 --- a/Sources/AnthropicSwiftSDK/Entity/StopReason.swift +++ b/Sources/AnthropicSwiftSDK/Entity/StopReason.swift @@ -8,7 +8,7 @@ import Foundation /// The reason that we stopped. -public enum StopReason: String, Decodable { +public enum StopReason: String, Decodable, Sendable { /// the model reached a natural stopping point case endTurn = "end_turn" /// we exceeded the requested max_tokens or the model's maximum diff --git a/Sources/AnthropicSwiftSDK/Entity/Streaming/ContentBlockDelta.swift b/Sources/AnthropicSwiftSDK/Entity/Streaming/ContentBlockDelta.swift index 77d8bab..691c5f4 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Streaming/ContentBlockDelta.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Streaming/ContentBlockDelta.swift @@ -7,7 +7,7 @@ import Foundation -public struct ContentBlockDelta: Decodable { +public struct ContentBlockDelta: Decodable, Sendable { public let type: ContentBlockDeltaType public let text: String? public let partialJson: String? diff --git a/Sources/AnthropicSwiftSDK/Entity/Streaming/ContentBlockDeltaType.swift b/Sources/AnthropicSwiftSDK/Entity/Streaming/ContentBlockDeltaType.swift index 720729c..e5297f7 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Streaming/ContentBlockDeltaType.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Streaming/ContentBlockDeltaType.swift @@ -7,7 +7,7 @@ import Foundation -public enum ContentBlockDeltaType: String, Decodable { +public enum ContentBlockDeltaType: String, Decodable, Sendable { case text = "text_delta" case inputJSON = "input_json_delta" } diff --git a/Sources/AnthropicSwiftSDK/Entity/Streaming/MessageDelta.swift b/Sources/AnthropicSwiftSDK/Entity/Streaming/MessageDelta.swift index e8d6a45..00b1f2a 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Streaming/MessageDelta.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Streaming/MessageDelta.swift @@ -7,7 +7,7 @@ import Foundation -public struct MessageDelta: Decodable { +public struct MessageDelta: Decodable, Sendable { public let stopReason: StopReason public let stopSequence: String? } diff --git a/Sources/AnthropicSwiftSDK/Entity/Streaming/StreamingError.swift b/Sources/AnthropicSwiftSDK/Entity/Streaming/StreamingError.swift index 4b5a087..ebf5716 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Streaming/StreamingError.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Streaming/StreamingError.swift @@ -7,7 +7,7 @@ import Foundation -public struct StreamingError: Decodable { +public struct StreamingError: Decodable, Sendable { public let type: AnthropicAPIError public let message: String } diff --git a/Sources/AnthropicSwiftSDK/Entity/Streaming/StreamingEvent.swift b/Sources/AnthropicSwiftSDK/Entity/Streaming/StreamingEvent.swift index 11db6ed..5af1671 100644 --- a/Sources/AnthropicSwiftSDK/Entity/Streaming/StreamingEvent.swift +++ b/Sources/AnthropicSwiftSDK/Entity/Streaming/StreamingEvent.swift @@ -7,7 +7,7 @@ import Foundation -public enum StreamingEvent: String, Decodable { +public enum StreamingEvent: String, Decodable, Sendable { /// contains a `Message` object with empty content case messageStart = "message_start" /// A series of content blocks, each of which have a `content_block_start`, one or more `content_block_delta` events, and a `content_block_stop` event. Each content block will have an `index` that corresponds to its index in the final `Message` content array. diff --git a/Sources/AnthropicSwiftSDK/Entity/SystemPrompt.swift b/Sources/AnthropicSwiftSDK/Entity/SystemPrompt.swift index fb7f3f8..544cdc0 100644 --- a/Sources/AnthropicSwiftSDK/Entity/SystemPrompt.swift +++ b/Sources/AnthropicSwiftSDK/Entity/SystemPrompt.swift @@ -7,7 +7,7 @@ import Foundation -public enum CacheControl: String { +public enum CacheControl: String, Sendable { /// corresponds to this 5-minute lifetime. case ephemeral } @@ -23,7 +23,7 @@ extension CacheControl: Encodable { } } -public enum SystemPrompt { +public enum SystemPrompt: Sendable { case text(String, CacheControl?) private var type: String { diff --git a/Sources/AnthropicSwiftSDK/Entity/TokenUsage.swift b/Sources/AnthropicSwiftSDK/Entity/TokenUsage.swift index 00d2d0e..41668ba 100644 --- a/Sources/AnthropicSwiftSDK/Entity/TokenUsage.swift +++ b/Sources/AnthropicSwiftSDK/Entity/TokenUsage.swift @@ -8,7 +8,7 @@ import Foundation /// Billing and rate-limit usage. -public struct TokenUsage: Decodable { +public struct TokenUsage: Decodable, Sendable { /// The number of input tokens which were used. public let inputTokens: Int? /// The number of output tokens which were used. diff --git a/Sources/AnthropicSwiftSDK/Network/Extension/StreamingResponse+Extension.swift b/Sources/AnthropicSwiftSDK/Network/Extension/StreamingResponse+Extension.swift index 899bd00..da32276 100644 --- a/Sources/AnthropicSwiftSDK/Network/Extension/StreamingResponse+Extension.swift +++ b/Sources/AnthropicSwiftSDK/Network/Extension/StreamingResponse+Extension.swift @@ -50,17 +50,14 @@ extension AsyncThrowingStream where Element == StreamingResponse { let accumulator = InputJSONDeltaAccumulator() let accumulativeStream = accumulator.createAccumulativeStream() - Task { + Task { @Sendable in do { - defer { - accumulator.finish() - } - for try await value in self { try accumulator.accumulateIfNeeded(value) } + accumulator.finish() } catch { - throw error + accumulator.finish(throwing: error) } } diff --git a/Sources/AnthropicSwiftSDK/Network/Response/MessagesResponse.swift b/Sources/AnthropicSwiftSDK/Network/Response/MessagesResponse.swift index 0fae2e7..94665c6 100644 --- a/Sources/AnthropicSwiftSDK/Network/Response/MessagesResponse.swift +++ b/Sources/AnthropicSwiftSDK/Network/Response/MessagesResponse.swift @@ -10,12 +10,12 @@ import Foundation /// Object type. /// /// For Messages, this is always "message". -public enum MessagesResponseType: String, Decodable { +public enum MessagesResponseType: String, Decodable, Sendable { case message } /// Messages API response -public struct MessagesResponse: Decodable { +public struct MessagesResponse: Decodable, Sendable { /// Unique object identifier. public let id: String /// Object type. diff --git a/Sources/AnthropicSwiftSDK/Network/Response/StreamingResponse.swift b/Sources/AnthropicSwiftSDK/Network/Response/StreamingResponse.swift index 4be1aa3..21d292f 100644 --- a/Sources/AnthropicSwiftSDK/Network/Response/StreamingResponse.swift +++ b/Sources/AnthropicSwiftSDK/Network/Response/StreamingResponse.swift @@ -7,7 +7,7 @@ import Foundation -public protocol StreamingResponse: Decodable { +public protocol StreamingResponse: Decodable, Sendable { var type: StreamingEvent { get } } diff --git a/Sources/AnthropicSwiftSDK/Network/StreamingParser/AnthropicStreamingParser.swift b/Sources/AnthropicSwiftSDK/Network/StreamingParser/AnthropicStreamingParser.swift index a44cbbe..fc722f2 100644 --- a/Sources/AnthropicSwiftSDK/Network/StreamingParser/AnthropicStreamingParser.swift +++ b/Sources/AnthropicSwiftSDK/Network/StreamingParser/AnthropicStreamingParser.swift @@ -9,7 +9,7 @@ import Foundation public enum AnthropicStreamingParser { // swiftlint:disable:next cyclomatic_complexity - public static func parse(stream: T) async throws -> AsyncThrowingStream where T.Element == String { + public static func parse(stream: T) async throws -> AsyncThrowingStream where T.Element == String, T: Sendable { return AsyncThrowingStream.init { continuation in let task = Task { var currentEvent: StreamingEvent? diff --git a/Sources/AnthropicSwiftSDK/Util/InputJSONDeltaAccumulator.swift b/Sources/AnthropicSwiftSDK/Util/InputJSONDeltaAccumulator.swift index f25537d..9337014 100644 --- a/Sources/AnthropicSwiftSDK/Util/InputJSONDeltaAccumulator.swift +++ b/Sources/AnthropicSwiftSDK/Util/InputJSONDeltaAccumulator.swift @@ -7,7 +7,7 @@ import Foundation -class InputJSONDeltaAccumulator { +class InputJSONDeltaAccumulator: @unchecked Sendable { private var partialJson: [StreamingContentBlockDeltaResponse] = [] private var toolUseInfo: StreamingContentBlockStartResponse? private var accumulativeStream: AsyncThrowingStream.Continuation? @@ -15,27 +15,28 @@ class InputJSONDeltaAccumulator { /// Receive StreamingResponse and collect `tool_use` related information if it exists. When `message_stop` is detected, the collected `tool_use`-related information is compiled and sent together with the `StreamingMessageDeltaResponse`. /// - Parameter response: `StreamingResponse` to collect data func accumulateIfNeeded(_ response: StreamingResponse) throws { - var modifiedResponse = response - switch response { case let contentBlockStart as StreamingContentBlockStartResponse: if case .toolUse = contentBlockStart.contentBlock { toolUseInfo = contentBlockStart } + accumulativeStream?.yield(response) case let contentBlockDelta as StreamingContentBlockDeltaResponse: if contentBlockDelta.delta.type == .inputJSON { partialJson.append(contentBlockDelta) } + accumulativeStream?.yield(response) case let messageDelta as StreamingMessageDeltaResponse: if messageDelta.delta.stopReason == .toolUse { let toolUseContent = try aggregateToolUseContent(from: partialJson, with: toolUseInfo) - modifiedResponse = messageDelta.added(toolUseContent: toolUseContent) + let modifiedResponse = messageDelta.added(toolUseContent: toolUseContent) + accumulativeStream?.yield(modifiedResponse) + } else { + accumulativeStream?.yield(response) } default: - break + accumulativeStream?.yield(response) } - - accumulativeStream?.yield(modifiedResponse) } /// Aggregate the `input_json_delta` of the collected `tool_use` to generate a JSON String and return it as a `ToolUseContent` with other information from the `tool_use`. @@ -70,4 +71,8 @@ class InputJSONDeltaAccumulator { func finish() { accumulativeStream?.finish() } + + func finish(throwing error: Error) { + accumulativeStream?.finish(throwing: error) + } } diff --git a/Tests/AnthropicSwiftSDKTests/API/MessageBatchesTests.swift b/Tests/AnthropicSwiftSDKTests/API/MessageBatchesTests.swift index 25967a1..50b63ac 100644 --- a/Tests/AnthropicSwiftSDKTests/API/MessageBatchesTests.swift +++ b/Tests/AnthropicSwiftSDKTests/API/MessageBatchesTests.swift @@ -34,7 +34,7 @@ final class MessageBatchesTests: XCTestCase { "processing_status": "ended", "request_counts": { "processing": 0, - "succeeeded": 95, + "succeeded": 95, "errored": 3, "canceled": 1, "expired": 1 @@ -77,7 +77,7 @@ final class MessageBatchesTests: XCTestCase { "processing_status": "ended", "request_counts": { "processing": 0, - "succeeeded": 95, + "succeeded": 95, "errored": 3, "canceled": 1, "expired": 1 @@ -99,7 +99,7 @@ final class MessageBatchesTests: XCTestCase { XCTAssertEqual(response.type, .message) XCTAssertEqual(response.processingStatus, .ended) XCTAssertEqual(response.requestCounts.processing, 0) - XCTAssertEqual(response.requestCounts.succeeeded, 95) + XCTAssertEqual(response.requestCounts.succeeded, 95) XCTAssertEqual(response.requestCounts.errored, 3) XCTAssertEqual(response.requestCounts.canceled, 1) XCTAssertEqual(response.requestCounts.expired, 1) @@ -120,7 +120,7 @@ final class MessageBatchesTests: XCTestCase { "processing_status": "in_progress", "request_counts": { "processing": 50, - "succeeeded": 0, + "succeeded": 0, "errored": 0, "canceled": 0, "expired": 0 @@ -153,7 +153,7 @@ final class MessageBatchesTests: XCTestCase { "processing_status": "canceling", "request_counts": { "processing": 25, - "succeeeded": 25, + "succeeded": 25, "errored": 0, "canceled": 0, "expired": 0 @@ -197,7 +197,7 @@ final class MessageBatchesTests: XCTestCase { "processing_status": "in_progress", "request_counts": { "processing": 100, - "succeeeded": 0, + "succeeded": 0, "errored": 0, "canceled": 0, "expired": 0 diff --git a/Tests/AnthropicSwiftSDKTests/Network/Response/BatchResponseTests.swift b/Tests/AnthropicSwiftSDKTests/Network/Response/BatchResponseTests.swift index 49dcb79..1acbde3 100644 --- a/Tests/AnthropicSwiftSDKTests/Network/Response/BatchResponseTests.swift +++ b/Tests/AnthropicSwiftSDKTests/Network/Response/BatchResponseTests.swift @@ -17,7 +17,7 @@ final class BatchResponseTests: XCTestCase { "processing_status": "ended", "request_counts": { "processing": 0, - "succeeeded": 95, + "succeeded": 95, "errored": 3, "canceled": 1, "expired": 1 @@ -41,7 +41,7 @@ final class BatchResponseTests: XCTestCase { XCTAssertEqual(batchResponse.processingStatus, .ended) XCTAssertEqual(batchResponse.requestCounts.processing, 0) - XCTAssertEqual(batchResponse.requestCounts.succeeeded, 95) + XCTAssertEqual(batchResponse.requestCounts.succeeded, 95) XCTAssertEqual(batchResponse.requestCounts.errored, 3) XCTAssertEqual(batchResponse.requestCounts.canceled, 1) XCTAssertEqual(batchResponse.requestCounts.expired, 1) @@ -61,7 +61,7 @@ final class BatchResponseTests: XCTestCase { "processing_status": "canceling", "request_counts": { "processing": 50, - "succeeeded": 40, + "succeeded": 40, "errored": 10, "canceled": 0, "expired": 0 @@ -85,7 +85,7 @@ final class BatchResponseTests: XCTestCase { XCTAssertEqual(batchResponse.processingStatus, .canceling) XCTAssertEqual(batchResponse.requestCounts.processing, 50) - XCTAssertEqual(batchResponse.requestCounts.succeeeded, 40) + XCTAssertEqual(batchResponse.requestCounts.succeeded, 40) XCTAssertEqual(batchResponse.requestCounts.errored, 10) XCTAssertEqual(batchResponse.requestCounts.canceled, 0) XCTAssertEqual(batchResponse.requestCounts.expired, 0) @@ -96,4 +96,4 @@ final class BatchResponseTests: XCTestCase { XCTAssertEqual(batchResponse.cancelInitiatedAt, "2024-10-18T16:30:00Z") XCTAssertNil(batchResponse.resultsUrl) } -} \ No newline at end of file +} diff --git a/Tests/AnthropicSwiftSDKTests/Network/Response/ObjectListResponseTests.swift b/Tests/AnthropicSwiftSDKTests/Network/Response/ObjectListResponseTests.swift index 88203aa..3d97fc4 100644 --- a/Tests/AnthropicSwiftSDKTests/Network/Response/ObjectListResponseTests.swift +++ b/Tests/AnthropicSwiftSDKTests/Network/Response/ObjectListResponseTests.swift @@ -19,7 +19,7 @@ final class ObjectListResponseTests: XCTestCase { "processing_status": "ended", "request_counts": { "processing": 0, - "succeeeded": 95, + "succeeded": 95, "errored": 5, "canceled": 0, "expired": 0 @@ -36,7 +36,7 @@ final class ObjectListResponseTests: XCTestCase { "processing_status": "in_progress", "request_counts": { "processing": 100, - "succeeeded": 0, + "succeeded": 0, "errored": 0, "canceled": 0, "expired": 0 @@ -66,7 +66,7 @@ final class ObjectListResponseTests: XCTestCase { XCTAssertEqual(firstBatch.type, .message) XCTAssertEqual(firstBatch.processingStatus, .ended) XCTAssertEqual(firstBatch.requestCounts.processing, 0) - XCTAssertEqual(firstBatch.requestCounts.succeeeded, 95) + XCTAssertEqual(firstBatch.requestCounts.succeeded, 95) XCTAssertEqual(firstBatch.requestCounts.errored, 5) XCTAssertEqual(firstBatch.requestCounts.canceled, 0) XCTAssertEqual(firstBatch.requestCounts.expired, 0) @@ -82,7 +82,7 @@ final class ObjectListResponseTests: XCTestCase { XCTAssertEqual(secondBatch.type, .message) XCTAssertEqual(secondBatch.processingStatus, .inProgress) XCTAssertEqual(secondBatch.requestCounts.processing, 100) - XCTAssertEqual(secondBatch.requestCounts.succeeeded, 0) + XCTAssertEqual(secondBatch.requestCounts.succeeded, 0) XCTAssertEqual(secondBatch.requestCounts.errored, 0) XCTAssertEqual(secondBatch.requestCounts.canceled, 0) XCTAssertEqual(secondBatch.requestCounts.expired, 0)