@@ -28,6 +28,7 @@ public protocol AppArguments {
2828 var port : Int { get }
2929 var logLevel : Logger . Level ? { get }
3030 var sso : Bool { get }
31+ var profileName : String { get }
3132}
3233
3334// Request context used by application
@@ -46,7 +47,7 @@ public func buildApplication(
4647 arguments. logLevel ?? environment. get ( " LOG_LEVEL " ) . flatMap {
4748 Logger . Level ( rawValue: $0)
4849 } ?? . info
49- let router = try await buildRouter ( useSSO: arguments. sso, logger: logger)
50+ let router = try await buildRouter ( useSSO: arguments. sso, logger: logger, profileName : arguments . profileName )
5051 let app = Application (
5152 router: router,
5253 configuration: . init(
@@ -59,7 +60,7 @@ public func buildApplication(
5960}
6061
6162/// Build router
62- func buildRouter( useSSO: Bool , logger: Logger ) async throws -> Router < AppRequestContext > {
63+ func buildRouter( useSSO: Bool , logger: Logger , profileName : String ) async throws -> Router < AppRequestContext > {
6364 let router = Router ( context: AppRequestContext . self)
6465
6566 // CORS
@@ -76,7 +77,22 @@ func buildRouter(useSSO: Bool, logger: Logger) async throws -> Router<AppRequest
7677 }
7778
7879 // SwiftBedrock
79- let bedrock = try await BedrockService ( useSSO: useSSO)
80+ var auth : BedrockAuthentication = . default
81+ if useSSO {
82+ auth = . sso( profileName: profileName)
83+ }
84+ let bedrock = try await BedrockService ( authentication: auth)
85+
86+ // Error handling
87+ @Sendable func handleBedrockServiceError( _ error: Error , context: String ) throws {
88+ if let bedrockServiceError = error as? BedrockServiceError {
89+ logger. trace ( " BedrockServiceError while \( context) " , metadata: [ " error " : " \( error) " ] )
90+ throw HTTPError ( . badRequest, message: bedrockServiceError. message)
91+ } else {
92+ logger. trace ( " Error while \( context) " , metadata: [ " error " : " \( error) " ] )
93+ throw HTTPError ( . internalServerError, message: " Error: \( error) " )
94+ }
95+ }
8096
8197 // List models
8298 // GET /foundation-models lists all models
@@ -173,25 +189,56 @@ func buildRouter(useSSO: Bool, logger: Logger) async throws -> Router<AppRequest
173189 throw HTTPError ( . badRequest, message: " Model \( modelId) does not support converse. " )
174190 }
175191 let input = try await request. decode ( as: ChatInput . self, context: context)
176- return try await bedrock. converse (
177- with: model,
178- prompt: input. prompt,
179- imageFormat: input. imageFormat ?? . jpeg, // default to simplify frontend
180- imageBytes: input. imageBytes,
181- history: input. history ?? [ ] ,
182- maxTokens: input. maxTokens,
183- temperature: input. temperature,
184- topP: input. topP,
185- stopSequences: input. stopSequences,
186- systemPrompts: input. systemPrompts,
187- tools: input. tools,
188- toolResult: input. toolResult
189- )
192+ var image : ImageBlock ? = nil
193+ if let imageBytes = input. imageBytes {
194+ image = try ImageBlock ( format: input. imageFormat ?? . jpeg, source: imageBytes)
195+ }
196+ var document : DocumentBlock ? = nil
197+ if let documentBytes = input. documentBytes, let name = input. documentName {
198+ document = try DocumentBlock ( name: name, format: input. documentFormat ?? . pdf, source: documentBytes)
199+ }
200+ var builder = try ConverseRequestBuilder ( with: model)
201+ . withHistory ( input. history ?? [ ] )
202+ . withMaxTokens ( input. maxTokens)
203+ . withTemperature ( input. temperature)
204+ . withTopP ( input. topP)
205+
206+ if let stopSequences = input. stopSequences,
207+ !stopSequences. isEmpty
208+ {
209+ builder = try builder. withStopSequences ( stopSequences)
210+ }
211+ if let systemPrompts = input. systemPrompts,
212+ !systemPrompts. isEmpty
213+ {
214+ builder = try builder. withStopSequences ( systemPrompts)
215+ }
216+ if let prompt = input. prompt {
217+ builder = try builder. withPrompt ( prompt)
218+ }
219+ if let tools = input. tools {
220+ builder = try builder. withTools ( tools)
221+ }
222+ if let toolResult = input. toolResult {
223+ builder = try builder. withToolResult ( toolResult)
224+ }
225+ if let document {
226+ builder = try builder. withDocument ( document)
227+ }
228+ if let image {
229+ builder = try builder. withImage ( image)
230+ }
231+ if let enableReasoning = input. enableReasoning, enableReasoning {
232+ builder = try builder. withReasoning ( )
233+ . withMaxReasoningTokens ( input. maxReasoningTokens)
234+ }
235+ return try await bedrock. converse ( with: builder)
190236 } catch {
191237 logger. info (
192238 " An error occured while generating chat " ,
193239 metadata: [ " url " : " /foundation-models/chat/:modelId " , " error " : " \( error) " ]
194240 )
241+ try handleBedrockServiceError ( error, context: " /foundation-models/chat/:modelId " )
195242 throw HTTPError ( . internalServerError, message: " Error: \( error) " )
196243 }
197244 }
0 commit comments