File tree Expand file tree Collapse file tree 4 files changed +91
-3
lines changed
Sources/AnthropicSwiftSDK Expand file tree Collapse file tree 4 files changed +91
-3
lines changed Original file line number Diff line number Diff line change @@ -35,6 +35,10 @@ public enum ClientError: Error {
35
35
case failedToMakeEncodableToolUseInput( [ String : Any ] )
36
36
/// SDK failed to encode `SystemPrompt` object
37
37
case failedToEncodeSystemPrompt
38
+ /// These messages are not supported by the model.
39
+ case unsupportedMessageContentContained( model: Model , messages: [ Message ] )
40
+ /// Some unsupported features are used.
41
+ case unsupportedFeatureUsed( description: String )
38
42
39
43
/// Description of sdk internal errors.
40
44
public var localizedDescription : String {
@@ -63,6 +67,10 @@ public enum ClientError: Error {
63
67
return " Failed to make ToolUse.input object Encodable "
64
68
case . failedToEncodeSystemPrompt:
65
69
return " Failed to encode `SystemPrompt` object "
70
+ case let . unsupportedMessageContentContained( model, messages) :
71
+ return " The model \( model. stringfy) does not support these messages: \( messages) "
72
+ case let . unsupportedFeatureUsed( description) :
73
+ return " Some unsupported features are used. For more detail, see \( description) . "
66
74
}
67
75
}
68
76
}
Original file line number Diff line number Diff line change @@ -47,6 +47,50 @@ public enum Model {
47
47
}
48
48
}
49
49
50
+ extension Model {
51
+ /// Whether this model supports Message Batches API or not.
52
+ ///
53
+ /// `Claude 3.0 Sonnet` does not support it.
54
+ var isSupportBatches : Bool {
55
+ switch self {
56
+ case
57
+ . claude_3_Opus,
58
+ . claude_3_Haiku,
59
+ . claude_3_5_Sonnet,
60
+ . claude_3_5_Haiku,
61
+ . custom:
62
+ return true
63
+ case . claude_3_Sonnet:
64
+ return false
65
+ }
66
+ }
67
+
68
+ /// Whether this model supports Vision feature or not.
69
+ ///
70
+ /// `Claude 3.5 Haiku` does not support it.
71
+ var isSupportVision : Bool {
72
+ switch self {
73
+ case
74
+ . claude_3_Opus,
75
+ . claude_3_Haiku,
76
+ . claude_3_Sonnet,
77
+ . claude_3_5_Sonnet,
78
+ . custom:
79
+ return true
80
+ case . claude_3_5_Haiku:
81
+ return false
82
+ }
83
+ }
84
+
85
+ func isValid( for message: Message ) -> Bool {
86
+ if isSupportVision {
87
+ return true
88
+ }
89
+
90
+ return message. content. allSatisfy { $0. contentType != . image }
91
+ }
92
+ }
93
+
50
94
extension Model {
51
95
var stringfy : String {
52
96
switch self {
Original file line number Diff line number Diff line change @@ -31,7 +31,9 @@ public struct MessageBatches {
31
31
/// - Returns: A `BatchResponse` containing the details of the created batches.
32
32
/// - Throws: An error if the request fails.
33
33
public func createBatches( batches: [ MessageBatch ] ) async throws -> BatchResponse {
34
- try await createBatches (
34
+ try validate ( batches: batches)
35
+
36
+ return try await createBatches (
35
37
batches: batches,
36
38
anthropicHeaderProvider: DefaultAnthropicHeaderProvider ( ) ,
37
39
authenticationHeaderProvider: APIKeyAuthenticationHeaderProvider ( apiKey: apiKey)
@@ -336,3 +338,22 @@ public struct MessageBatches {
336
338
return try anthropicJSONDecoder. decode ( BatchResponse . self, from: data)
337
339
}
338
340
}
341
+
342
+ extension MessageBatches {
343
+ func validate( batches: [ MessageBatch ] ) throws {
344
+ try batches. forEach { batch in
345
+ let model = batch. parameter. model
346
+ guard model. isSupportBatches else {
347
+ throw ClientError . unsupportedFeatureUsed ( description: " The model: \( model. stringfy) does not support Message Batches API " )
348
+ }
349
+
350
+ let messages = batch. parameter. messages
351
+ guard ( messages. allSatisfy { model. isValid ( for: $0) } ) else {
352
+ throw ClientError . unsupportedMessageContentContained (
353
+ model: model,
354
+ messages: messages. filter { model. isValid ( for: $0) == false }
355
+ )
356
+ }
357
+ }
358
+ }
359
+ }
Original file line number Diff line number Diff line change @@ -45,7 +45,9 @@ public struct Messages {
45
45
tools: [ Tool ] ? = nil ,
46
46
toolChoice: ToolChoice = . auto
47
47
) async throws -> MessagesResponse {
48
- try await createMessage (
48
+ try validate ( model, for: messages)
49
+
50
+ return try await createMessage (
49
51
messages,
50
52
model: model,
51
53
system: system,
@@ -160,7 +162,9 @@ public struct Messages {
160
162
tools: [ Tool ] ? = nil ,
161
163
toolChoice: ToolChoice = . auto
162
164
) async throws -> AsyncThrowingStream < StreamingResponse , Error > {
163
- try await streamMessage (
165
+ try validate ( model, for: messages)
166
+
167
+ return try await streamMessage (
164
168
messages,
165
169
model: model,
166
170
system: system,
@@ -246,3 +250,14 @@ public struct Messages {
246
250
return try await AnthropicStreamingParser . parse ( stream: data. lines) . accumulated ( )
247
251
}
248
252
}
253
+
254
+ extension Messages {
255
+ func validate( _ model: Model , for messages: [ Message ] ) throws {
256
+ guard ( messages. allSatisfy { model. isValid ( for: $0) } ) else {
257
+ throw ClientError . unsupportedMessageContentContained (
258
+ model: model,
259
+ messages: messages. filter { model. isValid ( for: $0) == false }
260
+ )
261
+ }
262
+ }
263
+ }
You can’t perform that action at this time.
0 commit comments