|
| 1 | +// |
| 2 | +// GeminiImagenRequestBody.swift |
| 3 | +// AIProxy |
| 4 | +// |
| 5 | +// Created by Lou Zell on 3/18/25. |
| 6 | +// |
| 7 | + |
| 8 | +import Foundation |
| 9 | + |
| 10 | +/// See the Imagen [prompt guide](https://ai.google.dev/gemini-api/docs/imagen-prompt-guide) |
| 11 | +/// |
| 12 | +/// Imagen is described in a few places: |
| 13 | +/// - https://ai.google.dev/gemini-api/docs/image-generation#imagen |
| 14 | +/// - https://cloud.google.com/vertex-ai/generative-ai/docs/image/model-versioning |
| 15 | +/// - https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-api |
| 16 | +/// |
| 17 | +/// It's unclear to me whether you need to apply to this first: |
| 18 | +/// https://cloud.google.com/vertex-ai/generative-ai/docs/image/overview?authuser=1 |
| 19 | +/// - Request access: Imagen 3 Customization and Editing |
| 20 | +/// - Request access: Person and face generation |
| 21 | +public struct GeminiImagenRequestBody: Encodable { |
| 22 | + public let instances: [Instance] |
| 23 | + public let parameters: Parameters |
| 24 | + |
| 25 | + public init( |
| 26 | + instances: [GeminiImagenRequestBody.Instance], |
| 27 | + parameters: GeminiImagenRequestBody.Parameters |
| 28 | + ) { |
| 29 | + self.instances = instances |
| 30 | + self.parameters = parameters |
| 31 | + } |
| 32 | +} |
| 33 | + |
| 34 | +extension GeminiImagenRequestBody { |
| 35 | + public struct Instance: Encodable { |
| 36 | + public let prompt: String |
| 37 | + public let image: InputImage? |
| 38 | + |
| 39 | + public init(prompt: String, image: GeminiImagenRequestBody.Instance.InputImage? = nil) { |
| 40 | + self.prompt = prompt |
| 41 | + self.image = image |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + public struct Parameters: Encodable { |
| 46 | + public init( |
| 47 | + aspectRatio: String? = nil, |
| 48 | + mode: String? = nil, |
| 49 | + personGeneration: GeminiImagenRequestBody.Parameters.PersonGeneration? = nil, |
| 50 | + safetyLevel: GeminiImagenRequestBody.Parameters.SafetyLevel? = nil, |
| 51 | + sampleCount: Int, |
| 52 | + upscaleConfig: GeminiImagenRequestBody.Parameters.UpscaleConfig? = nil |
| 53 | + ) { |
| 54 | + self.aspectRatio = aspectRatio |
| 55 | + self.mode = mode |
| 56 | + self.personGeneration = personGeneration |
| 57 | + self.safetyLevel = safetyLevel |
| 58 | + self.sampleCount = sampleCount |
| 59 | + self.upscaleConfig = upscaleConfig |
| 60 | + } |
| 61 | + |
| 62 | + /// Supported values are "1:1", "3:4", "4:3", "9:16", and "16:9". The default is "1:1". |
| 63 | + public let aspectRatio: String? |
| 64 | + |
| 65 | + /// One valid mode is 'upscale'. I do not know what the other valid modes are. |
| 66 | + public let mode: String? |
| 67 | + |
| 68 | + /// "dont_allow": Disallow the inclusion of people or faces in images. |
| 69 | + /// "allow_adult": Allow generation of adults only. |
| 70 | + /// "allow_all": Allow generation of people of all ages. |
| 71 | + /// The default value is "allow_adult". |
| 72 | + public let personGeneration: PersonGeneration? |
| 73 | + |
| 74 | + /// Adds a filter level to safety filtering. The following values are supported: |
| 75 | + /// |
| 76 | + /// "block_low_and_above": Strongest filtering level, most strict blocking. |
| 77 | + /// "block_medium_and_above": Block some problematic prompts and responses. |
| 78 | + /// "block_only_high": Reduces the number of requests blocked due to safety filters. May increase objectionable content generated by Imagen. |
| 79 | + /// "block_none": Block very few problematic prompts and responses. Access to this feature is restricted. |
| 80 | + /// |
| 81 | + /// The default value is "block_medium_and_above". |
| 82 | + public let safetyLevel: SafetyLevel? |
| 83 | + |
| 84 | + /// The number of images to create |
| 85 | + public let sampleCount: Int |
| 86 | + |
| 87 | + public let upscaleConfig: UpscaleConfig? |
| 88 | + } |
| 89 | +} |
| 90 | + |
| 91 | + |
| 92 | +extension GeminiImagenRequestBody.Parameters { |
| 93 | + /// Represents the safety filtering level for content moderation. |
| 94 | + public enum SafetyLevel: String, Encodable { |
| 95 | + /// Strongest filtering level, most strict blocking. Deprecated value: "block_most". |
| 96 | + case blockLowAndAbove = "block_low_and_above" |
| 97 | + |
| 98 | + /// Block some problematic prompts and responses. Deprecated value: "block_some". |
| 99 | + case blockMediumAndAbove = "block_medium_and_above" |
| 100 | + |
| 101 | + /// Reduces the number of requests blocked due to safety filters. May increase |
| 102 | + /// objectionable content generated by Imagen. Deprecated value: "block_few". |
| 103 | + case blockOnlyHigh = "block_only_high" |
| 104 | + |
| 105 | + /// Block very few problematic prompts and responses. Access to this feature is |
| 106 | + /// restricted. Previous field value: "block_fewest". |
| 107 | + case blockNone = "block_none" |
| 108 | + } |
| 109 | +} |
| 110 | + |
| 111 | +extension GeminiImagenRequestBody.Parameters { |
| 112 | + /// Controls the generation of people or faces in images. |
| 113 | + public enum PersonGeneration: String, Encodable { |
| 114 | + /// Disallow the inclusion of people or faces in images. |
| 115 | + case dontAllow = "dont_allow" |
| 116 | + |
| 117 | + /// Allow generation of adults only. |
| 118 | + case allowAdult = "allow_adult" |
| 119 | + |
| 120 | + /// Allow generation of people of all ages. |
| 121 | + case allowAll = "allow_all" |
| 122 | + } |
| 123 | +} |
| 124 | + |
| 125 | +extension GeminiImagenRequestBody.Instance { |
| 126 | + public struct InputImage: Encodable { |
| 127 | + public let data: Data |
| 128 | + |
| 129 | + private enum CodingKeys: String, CodingKey { |
| 130 | + case bytesBase64Encoded |
| 131 | + } |
| 132 | + |
| 133 | + public init(data: Data) { |
| 134 | + self.data = data |
| 135 | + } |
| 136 | + |
| 137 | + public func encode(to encoder: any Encoder) throws { |
| 138 | + var container = encoder.container(keyedBy: CodingKeys.self) |
| 139 | + try container.encode(self.data.base64EncodedString(), forKey: .bytesBase64Encoded) |
| 140 | + } |
| 141 | + } |
| 142 | +} |
| 143 | + |
| 144 | +extension GeminiImagenRequestBody.Parameters { |
| 145 | + public struct UpscaleConfig: Encodable { |
| 146 | + public enum UpscaleFactor: String, Encodable { |
| 147 | + case x2 |
| 148 | + case x4 |
| 149 | + } |
| 150 | + |
| 151 | + public let upscaleFactor: UpscaleFactor |
| 152 | + |
| 153 | + public init(upscaleFactor: GeminiImagenRequestBody.Parameters.UpscaleConfig.UpscaleFactor) { |
| 154 | + self.upscaleFactor = upscaleFactor |
| 155 | + } |
| 156 | + } |
| 157 | +} |
0 commit comments