diff --git a/.github/workflows/build_test_soundness.yml b/.github/workflows/build_test_soundness.yml index c62e5e9c..3680cf7b 100644 --- a/.github/workflows/build_test_soundness.yml +++ b/.github/workflows/build_test_soundness.yml @@ -1,10 +1,6 @@ name: Build And Test on EC2 -on: - push: - branches: ["main", "week12"] - pull_request: - branches: ["main"] +on: [push, pull_request] jobs: build: @@ -22,20 +18,20 @@ jobs: working-directory: backend run: swift build - test: - runs-on: ubuntu-latest - container: swift:6.0.3-amazonlinux2 + # test: + # runs-on: ubuntu-latest + # container: swift:6.0.3-amazonlinux2 - steps: - # GitHub checkout action has a dep on NodeJS 20 which is not running on Amazonlinux2 - # workaround is to manually checkout the repository - # https://github.com/actions/checkout/issues/1487 - - name: Manually Clone repository - run: | - git clone https://github.com/${{ github.repository }} . - - name: Run tests - working-directory: backend - run: swift test + # steps: + # # GitHub checkout action has a dep on NodeJS 20 which is not running on Amazonlinux2 + # # workaround is to manually checkout the repository + # # https://github.com/actions/checkout/issues/1487 + # - name: Manually Clone repository + # run: | + # git clone https://github.com/${{ github.repository }} . + # - name: Run tests + # working-directory: backend + # run: swift test soundness: name: Soundness diff --git a/.gitignore b/.gitignore index 79faf2ff..23675b5a 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ xcuserdata Package.resolved .serverless .vscode +.env # backend backend/.DS_Store diff --git a/.vscode/launch.json b/.vscode/launch.json index 6da29e05..504f596c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -71,6 +71,24 @@ "name": "Release SwiftBedrockService (backend)", "program": "${workspaceFolder:swift-bedrock-playground}/backend/.build/release/SwiftBedrockService", "preLaunchTask": "swift: Build Release SwiftBedrockService (backend)" + }, + { + "type": "lldb", + "request": "launch", + "args": [], + "cwd": "${workspaceFolder:swift-fm-playground}/backend", + "name": "Debug PlaygroundAPI (backend)", + "program": "${workspaceFolder:swift-fm-playground}/backend/.build/debug/PlaygroundAPI", + "preLaunchTask": "swift: Build Debug PlaygroundAPI (backend)" + }, + { + "type": "lldb", + "request": "launch", + "args": [], + "cwd": "${workspaceFolder:swift-fm-playground}/backend", + "name": "Release PlaygroundAPI (backend)", + "program": "${workspaceFolder:swift-fm-playground}/backend/.build/release/PlaygroundAPI", + "preLaunchTask": "swift: Build Release PlaygroundAPI (backend)" } ] } \ No newline at end of file diff --git a/README.md b/README.md index b2a110b4..84a07823 100644 --- a/README.md +++ b/README.md @@ -1,126 +1,33 @@ -# SwiftBedrockService - -Work in progress, feel free to open issue, but do not use in your projects. - -## How to add a new model family? - -As an example we will add the Llama 3.1 70B Instruct model from the Meta family as an example. - -"meta.llama3-70b-instruct-v1:0" - -### 1. Add create BedrockModel instance - -```swift -extension BedrockModel { - public static let llama3_70b_instruct: BedrockModel = BedrockModel( - id: "meta.llama3-70b-instruct-v1:0", - modality: LlamaText() - ) -} -``` - -### 2. Create family-specific request and response struct - -Make sure to create a struct that reflects exactly how the body of the request for an invokeModel call to this family should look. Make sure to add the public initializer with parameters `prompt`, `maxTokens` and `temperature` to comply to the `BedrockBodyCodable` protocol. - -```json -{ - "prompt": "\(prompt)", - "temperature": 1, - "top_p": 0.9, - "max_tokens": 200, - "stop": ["END"] -} -``` - -```swift -public struct LlamaRequestBody: BedrockBodyCodable { - let prompt: String - let max_gen_len: Int - let temperature: Double - let top_p: Double - - public init(prompt: String, maxTokens: Int = 512, temperature: Double = 0.5) { - self.prompt = - "<|begin_of_text|><|start_header_id|>user<|end_header_id|>\(prompt)<|eot_id|><|start_header_id|>assistant<|end_header_id|>" - self.max_gen_len = maxTokens - self.temperature = temperature - self.top_p = 0.9 - } -} -``` - -Do the same for the response and ensure to add the `getTextCompletion` method to extract the completion from the response body and to comply to the `ContainsTextCompletion` protocol. - -```json -{ - "generation": "\n\n", - "prompt_token_count": int, - "generation_token_count": int, - "stop_reason" : string -} -``` - -```swift -struct LlamaResponseBody: ContainsTextCompletion { - let generation: String - let prompt_token_count: Int - let generation_token_count: Int - let stop_reason: String - - public func getTextCompletion() throws -> TextCompletion { - TextCompletion(generation) - } -} -``` - -### 3. Add the Modality (TextModality or ImageModality) - -For a text generation create a struct conforming to TextModality. Use the request body and response body you created in [the previous step](#2-create-family-specific-request-and-response-struct). - -```swift -struct LlamaText: TextModality { - func getName() -> String { "Llama Text Generation" } - - func getTextRequestBody(prompt: String, maxTokens: Int, temperature: Double) throws -> BedrockBodyCodable { - LlamaRequestBody(prompt: prompt, maxTokens: maxTokens, temperature: temperature) - } - - func getTextResponseBody(from data: Data) throws -> ContainsTextCompletion { - let decoder = JSONDecoder() - return try decoder.decode(LlamaResponseBody.self, from: data) - } -} -``` - -### 4. Optionally you can create a BedrockModel initializer for your newly implemented models -```swift -extension BedrockModel { - init?(_ id: String) { - switch id { - case "meta.llama3-70b-instruct-v1:0": self = .llama3_70b_instruct - // ... - default: - return nil - } - } -} -``` - - -## How to add a new model? - -If you want to add a model that has a request and response structure that is already implemented you can skip a few steps. Simply create a typealias for the Modality that matches the structure and use it to create a BedrockModel instance. - -```swift -typealias ClaudeNewModel = AnthropicText - -extension BedrockModel { - public static let instant: BedrockModel = BedrockModel( - id: "anthropic.claude-new-model", - modality: ClaudeNewModel() - ) -} -``` - -Note that the model will not automatically be included in the BedrockModel initializer that creates an instance from a raw string value. Consider creating a custom initializer that includes your models. +# Swift FM Playground + +Welcome to the Swift Foundation Model (FM) Playground, an example app to explore how to use **Amazon Bedrock** with the AWS SDK for Swift. + +> 🚨 **Important:** This application is for educational purposes and not intended for production use. + +## Overview + +> 🚧 Under construction 🚧 + +## Prerequisites + +> 🚧 Under construction 🚧 + +## Running the Application + +> 🚧 Under construction 🚧 + +## Accessing the Application + +To access the application, open `http://localhost:3000` in your web browser. + +## Stopping the Application + +To halt the application, you will need to stop both the backend and frontend processes. + +### Stopping the Frontend + +In the terminal where the frontend is running, press `Ctrl + C` to terminate the process. + +### Stopping the Backend + +Similarly, in the backend terminal, use the `Ctrl + C` shortcut to stop the server. diff --git a/backend/Package.swift b/backend/Package.swift index fa65c639..e1fdd855 100644 --- a/backend/Package.swift +++ b/backend/Package.swift @@ -4,60 +4,25 @@ import PackageDescription let package = Package( - name: "HummingbirdBackend", // FIXME: better name - platforms: [.macOS(.v14), .iOS(.v17), .tvOS(.v17)], + name: "SwiftBedrock", + platforms: [.macOS(.v15), .iOS(.v18), .tvOS(.v18)], products: [ - .executable(name: "App", targets: ["App"]) // FIXME: better name + .executable(name: "PlaygroundAPI", targets: ["PlaygroundAPI"]) ], dependencies: [ .package(url: "https://github.com/hummingbird-project/hummingbird.git", from: "2.0.0"), .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.3.0"), - .package(url: "https://github.com/awslabs/aws-sdk-swift", from: "1.2.45"), - .package(url: "https://github.com/smithy-lang/smithy-swift", from: "0.118.0"), - .package(url: "https://github.com/swiftlang/swift-testing", branch: "main"), - .package(url: "https://github.com/apple/swift-log.git", from: "1.5.3"), + .package(url: "https://github.com/monadierickx/swift-bedrock-library.git", branch: "week16"), ], targets: [ .executableTarget( - name: "App", + name: "PlaygroundAPI", dependencies: [ - .target(name: "BedrockService"), .product(name: "ArgumentParser", package: "swift-argument-parser"), .product(name: "Hummingbird", package: "hummingbird"), + .product(name: "BedrockService", package: "swift-bedrock-library"), ], - path: "Sources/App" - ), - .target( - name: "BedrockService", - dependencies: [ - .target(name: "BedrockTypes"), - .product(name: "AWSClientRuntime", package: "aws-sdk-swift"), - .product(name: "AWSBedrock", package: "aws-sdk-swift"), - .product(name: "AWSBedrockRuntime", package: "aws-sdk-swift"), - .product(name: "Smithy", package: "smithy-swift"), - .product(name: "Logging", package: "swift-log"), - ], - path: "Sources/BedrockService" - ), - .target( - name: "BedrockTypes", - path: "Sources/BedrockTypes" - ), - .testTarget( - name: "BedrockServiceTests", - dependencies: [ - .target(name: "BedrockService"), - .product(name: "Testing", package: "swift-testing"), - ], - path: "Tests/BedrockServiceTests" - ), - // .testTarget(name: "AppTests", - // dependencies: [ - // .byName(name: "App"), - // .target(name: "SwiftBedrockService"), - // .product(name: "HummingbirdTesting", package: "hummingbird") - // ], - // path: "Tests/AppTests" - // ) + path: "Sources/PlaygroundAPI" + ) ] ) diff --git a/backend/Sources/BedrockService/Converse/ConverseRequest.swift b/backend/Sources/BedrockService/Converse/ConverseRequest.swift deleted file mode 100644 index c11f8488..00000000 --- a/backend/Sources/BedrockService/Converse/ConverseRequest.swift +++ /dev/null @@ -1,88 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -@preconcurrency import AWSBedrockRuntime -import Foundation -import BedrockTypes - -public struct ConverseRequest { - let model: BedrockModel - let messages: [Message] - let inferenceConfig: InferenceConfig? - - init( - model: BedrockModel, - messages: [Message] = [], - maxTokens: Int?, - temperature: Double?, - topP: Double?, - stopSequences: [String]? - ) { - self.messages = messages - self.model = model - self.inferenceConfig = InferenceConfig( - maxTokens: maxTokens, - temperature: temperature, - topP: topP, - stopSequences: stopSequences - ) - } - - func getConverseInput() -> ConverseInput { - let sdkInferenceConfig: BedrockRuntimeClientTypes.InferenceConfiguration? - if inferenceConfig != nil { - sdkInferenceConfig = inferenceConfig!.getSDKInferenceConfig() - } else { - sdkInferenceConfig = nil - } - return ConverseInput( - inferenceConfig: sdkInferenceConfig, - messages: getSDKMessages(), - modelId: model.id - ) - } - - private func getSDKMessages() -> [BedrockRuntimeClientTypes.Message] { - messages.map { $0.getSDKMessage() } - } - - struct InferenceConfig { - let maxTokens: Int? - let temperature: Double? - let topP: Double? - let stopSequences: [String]? - - func getSDKInferenceConfig() -> BedrockRuntimeClientTypes.InferenceConfiguration { - let temperatureFloat: Float? - if temperature != nil { - temperatureFloat = Float(temperature!) - } else { - temperatureFloat = nil - } - let topPFloat: Float? - if topP != nil { - topPFloat = Float(topP!) - } else { - topPFloat = nil - } - return BedrockRuntimeClientTypes.InferenceConfiguration( - maxTokens: maxTokens, - stopSequences: stopSequences, - temperature: temperatureFloat, - topp: topPFloat - ) - } - } -} diff --git a/backend/Sources/BedrockService/Converse/ConverseResponse.swift b/backend/Sources/BedrockService/Converse/ConverseResponse.swift deleted file mode 100644 index 8be13ab0..00000000 --- a/backend/Sources/BedrockService/Converse/ConverseResponse.swift +++ /dev/null @@ -1,38 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -@preconcurrency import AWSBedrockRuntime -import Foundation -import BedrockTypes - -public struct ConverseResponse { - let message: Message - - public init(_ output: BedrockRuntimeClientTypes.ConverseOutput) throws { - guard case .message(let sdkMessage) = output else { - throw BedrockServiceError.invalidSDKResponse("Could not extract message from ConverseOutput") - } - self.message = try Message(from: sdkMessage) - } - - func getReply() -> String { - switch message.content.first { - case .text(let text): - return text - default: - return "Not found" // FIXME - } - } -} diff --git a/backend/Sources/BedrockService/Converse/ConversionExtensions.swift b/backend/Sources/BedrockService/Converse/ConversionExtensions.swift deleted file mode 100644 index d52a11c1..00000000 --- a/backend/Sources/BedrockService/Converse/ConversionExtensions.swift +++ /dev/null @@ -1,88 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -@preconcurrency import AWSBedrockRuntime -import Foundation -import BedrockTypes - -extension Message { - - init(from sdkMessage: BedrockRuntimeClientTypes.Message) throws { - guard let sdkRole = sdkMessage.role else { - throw BedrockServiceError.decodingError("Could not extract role from BedrockRuntimeClientTypes.Message") - } - guard let sdkContent = sdkMessage.content else { - throw BedrockServiceError.decodingError("Could not extract content from BedrockRuntimeClientTypes.Message") - } - let content: [Content] = try sdkContent.map { try Content(from: $0) } - self = Message(from: try Role(from: sdkRole), content: content) - } - - func getSDKMessage() -> BedrockRuntimeClientTypes.Message { - let contentBlocks: [BedrockRuntimeClientTypes.ContentBlock] = content.map { - content -> BedrockRuntimeClientTypes.ContentBlock in - return content.getSDKContentBlock() - } - return BedrockRuntimeClientTypes.Message( - content: contentBlocks, - role: role.getSDKConversationRole() - ) - } -} - -extension Content { - - init(from sdkContentBlock: BedrockRuntimeClientTypes.ContentBlock) throws { - switch sdkContentBlock { - case .text(let text): - self = .text(text) - case .sdkUnknown(let unknownContentBlock): - throw BedrockServiceError.notImplemented( - "ContentBlock \(unknownContentBlock) is not implemented by BedrockRuntimeClientTypes" - ) - default: - throw BedrockServiceError.notImplemented( - "\(sdkContentBlock.self) is not implemented by this library" - ) - } - } - - func getSDKContentBlock() -> BedrockRuntimeClientTypes.ContentBlock { - switch self { - case .text(let text): - return BedrockRuntimeClientTypes.ContentBlock.text(text) - } - } -} - -extension Role { - init(from sdkConversationRole: BedrockRuntimeClientTypes.ConversationRole) throws { - switch sdkConversationRole { - case .user: self = .user - case .assistant: self = .assistant - case .sdkUnknown(let unknownRole): - throw BedrockServiceError.notImplemented( - "Role \(unknownRole) is not implemented by BedrockRuntimeClientTypes" - ) - } - } - - func getSDKConversationRole() -> BedrockRuntimeClientTypes.ConversationRole { - switch self { - case .user: return .user - case .assistant: return .assistant - } - } -} diff --git a/backend/Sources/BedrockService/InvokeModel/InvokeModelRequest.swift b/backend/Sources/BedrockService/InvokeModel/InvokeModelRequest.swift deleted file mode 100644 index 66e8096e..00000000 --- a/backend/Sources/BedrockService/InvokeModel/InvokeModelRequest.swift +++ /dev/null @@ -1,224 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -@preconcurrency import AWSBedrockRuntime -import Foundation -import BedrockTypes - -struct InvokeModelRequest { - let model: BedrockModel - let contentType: ContentType - let accept: ContentType - private let body: BedrockBodyCodable - - private init( - model: BedrockModel, - body: BedrockBodyCodable, - contentType: ContentType = .json, - accept: ContentType = .json - ) { - self.model = model - self.body = body - self.contentType = contentType - self.accept = accept - } - - // MARK: text - /// Creates a BedrockRequest for a text request with the specified parameters - /// - Parameters: - /// - model: The Bedrock model to use - /// - prompt: The input text prompt - /// - maxTokens: Maximum number of tokens to generate (default: 300) - /// - temperature: Temperature for text generation (default: 0.6) - /// - Returns: A configured BedrockRequest for a text request - /// - Throws: BedrockServiceError if the model doesn't support text output - static func createTextRequest( - model: BedrockModel, - prompt: String, - maxTokens: Int?, - temperature: Double?, - topP: Double?, - topK: Int?, - stopSequences: [String]? - ) throws -> InvokeModelRequest { - try .init( - model: model, - prompt: prompt, - maxTokens: maxTokens, - temperature: temperature, - topP: topP, - topK: topK, - stopSequences: stopSequences - ) - } - - private init( - model: BedrockModel, - prompt: String, - maxTokens: Int?, - temperature: Double?, - topP: Double?, - topK: Int?, - stopSequences: [String]? - ) throws { - let textModality = try model.getTextModality() - let body: BedrockBodyCodable = try textModality.getTextRequestBody( - prompt: prompt, - maxTokens: maxTokens, - temperature: temperature, - topP: topP, - topK: topK, - stopSequences: stopSequences - ) - self.init(model: model, body: body) - } - - // MARK: text to image - /// Creates a BedrockRequest for a text-to-image request with the specified parameters - /// - Parameters: - /// - model: The Bedrock model to use for image generation - /// - prompt: The text description of the image to generate - /// - nrOfImages: The number of images to generate - /// - Returns: A configured BedrockRequest for image generation - /// - Throws: BedrockServiceError if the model doesn't support text input or image output - public static func createTextToImageRequest( - model: BedrockModel, - prompt: String, - negativeText: String?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) throws -> InvokeModelRequest { - try .init( - model: model, - prompt: prompt, - negativeText: negativeText, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } - - private init( - model: BedrockModel, - prompt: String, - negativeText: String?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) throws { - let textToImageModality = try model.getTextToImageModality() - self.init( - model: model, - body: try textToImageModality.getTextToImageRequestBody( - prompt: prompt, - negativeText: negativeText, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - ) - } - - // MARK: image variation - /// Creates a BedrockRequest for a request to generate variations of an existing image - /// - Parameters: - /// - model: The Bedrock model to use for image variation generation - /// - prompt: The text description to guide the variation generation - /// - image: The base64-encoded string of the source image to create variations from - /// - similarity: A value between 0 and 1 indicating how similar the variations should be to the source image - /// - nrOfImages: The number of image variations to generate - /// - Returns: A configured BedrockRequest for image variation generation - /// - Throws: BedrockServiceError if the model doesn't support text and image input, or image output - public static func createImageVariationRequest( - model: BedrockModel, - prompt: String, - negativeText: String?, - images: [String], - similarity: Double?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) throws -> InvokeModelRequest { - try .init( - model: model, - prompt: prompt, - negativeText: negativeText, - images: images, - similarity: similarity, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } - - private init( - model: BedrockModel, - prompt: String, - negativeText: String?, - images: [String], - similarity: Double?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) throws { - let modality = try model.getImageVariationModality() - let body = try modality.getImageVariationRequestBody( - prompt: prompt, - negativeText: negativeText, - images: images, - similarity: similarity, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - self.init(model: model, body: body) - } - - /// Creates an InvokeModelInput instance for making a request to Amazon Bedrock - /// - Returns: A configured InvokeModelInput containing the model ID, content type, and encoded request body - /// - Throws: BedrockServiceError.encodingError if the request body cannot be encoded to JSON - public func getInvokeModelInput() throws -> InvokeModelInput { - do { - let jsonData: Data = try JSONEncoder().encode(self.body) - return InvokeModelInput( - accept: self.accept.headerValue, - body: jsonData, - contentType: self.contentType.headerValue, - modelId: model.id - ) - } catch { - throw BedrockServiceError.encodingError( - "Something went wrong while encoding the request body to JSON for InvokeModelInput: \(error)" - ) - } - } -} diff --git a/backend/Sources/BedrockService/InvokeModel/InvokeModelResponse.swift b/backend/Sources/BedrockService/InvokeModel/InvokeModelResponse.swift deleted file mode 100644 index bbbae7f0..00000000 --- a/backend/Sources/BedrockService/InvokeModel/InvokeModelResponse.swift +++ /dev/null @@ -1,109 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -@preconcurrency import AWSBedrockRuntime -import Foundation -import BedrockTypes - -public struct InvokeModelResponse { - let model: BedrockModel - let contentType: ContentType - let textCompletionBody: ContainsTextCompletion? - let imageGenerationBody: ContainsImageGeneration? - - private init( - model: BedrockModel, - contentType: ContentType = .json, - textCompletionBody: ContainsTextCompletion - ) { - self.model = model - self.contentType = contentType - self.textCompletionBody = textCompletionBody - self.imageGenerationBody = nil - } - - private init( - model: BedrockModel, - contentType: ContentType = .json, - imageGenerationBody: ContainsImageGeneration - ) { - self.model = model - self.contentType = contentType - self.imageGenerationBody = imageGenerationBody - self.textCompletionBody = nil - } - - /// Creates a BedrockResponse from raw response data containing text completion - /// - Parameters: - /// - data: The raw response data from the Bedrock service - /// - model: The Bedrock model that generated the response - /// - Throws: BedrockServiceError.invalidModel if the model is not supported - /// BedrockServiceError.invalidResponseBody if the response cannot be decoded - static func createTextResponse(body data: Data, model: BedrockModel) throws -> Self { - do { - let textModality = try model.getTextModality() - return self.init(model: model, textCompletionBody: try textModality.getTextResponseBody(from: data)) - } catch { - throw BedrockServiceError.invalidSDKResponseBody(data) - } - } - - /// Creates a BedrockResponse from raw response data containing an image generation - /// - Parameters: - /// - data: The raw response data from the Bedrock service - /// - model: The Bedrock model that generated the response - /// - Throws: BedrockServiceError.invalidModel if the model is not supported - /// BedrockServiceError.invalidResponseBody if the response cannot be decoded - static func createImageResponse(body data: Data, model: BedrockModel) throws -> Self { - do { - let imageModality = try model.getImageModality() - return self.init(model: model, imageGenerationBody: try imageModality.getImageResponseBody(from: data)) - } catch { - throw BedrockServiceError.invalidSDKResponseBody(data) - } - } - - /// Extracts the text completion from the response body - /// - Returns: The text completion from the response - /// - Throws: BedrockServiceError.decodingError if the completion cannot be extracted - public func getTextCompletion() throws -> TextCompletion { - do { - guard let textCompletionBody = textCompletionBody else { - throw BedrockServiceError.decodingError("No text completion body found in the response") - } - return try textCompletionBody.getTextCompletion() - } catch { - throw BedrockServiceError.decodingError( - "Something went wrong while decoding the request body to find the completion: \(error)" - ) - } - } - - /// Extracts the image generation from the response body - /// - Returns: The image generation from the response - /// - Throws: BedrockServiceError.decodingError if the image generation cannot be extracted - public func getGeneratedImage() throws -> ImageGenerationOutput { - do { - guard let imageGenerationBody = imageGenerationBody else { - throw BedrockServiceError.decodingError("No image generation body found in the response") - } - return imageGenerationBody.getGeneratedImage() - } catch { - throw BedrockServiceError.decodingError( - "Something went wrong while decoding the request body to find the completion: \(error)" - ) - } - } -} diff --git a/backend/Sources/BedrockService/ModelSummary.swift b/backend/Sources/BedrockService/ModelSummary.swift deleted file mode 100644 index da77cd27..00000000 --- a/backend/Sources/BedrockService/ModelSummary.swift +++ /dev/null @@ -1,74 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -@preconcurrency import AWSBedrock -import Foundation -import BedrockTypes - -// comment to explain difference -public struct ModelSummary: Encodable { - let modelName: String - let providerName: String - let modelId: String - let modelArn: String - let modelLifecylceStatus: String - let responseStreamingSupported: Bool - let bedrockModel: BedrockModel? - - public static func getModelSummary(from sdkModelSummary: BedrockClientTypes.FoundationModelSummary) throws -> Self { - - guard let modelName = sdkModelSummary.modelName else { - throw BedrockServiceError.notFound("BedrockClientTypes.FoundationModelSummary does not have a modelName") - } - guard let providerName = sdkModelSummary.providerName else { - throw BedrockServiceError.notFound("BedrockClientTypes.FoundationModelSummary does not have a providerName") - } - guard let modelId = sdkModelSummary.modelId else { - throw BedrockServiceError.notFound("BedrockClientTypes.FoundationModelSummary does not have a modelId") - } - guard let modelArn = sdkModelSummary.modelArn else { - throw BedrockServiceError.notFound("BedrockClientTypes.FoundationModelSummary does not have a modelArn") - } - guard let modelLifecycle = sdkModelSummary.modelLifecycle else { - throw BedrockServiceError.notFound("BedrockClientTypes.FoundationModelSummary does not have a modelLifecycle") - } - guard let sdkStatus = modelLifecycle.status else { - throw BedrockServiceError.notFound( - "BedrockClientTypes.FoundationModelSummary does not have a modelLifecycle.status" - ) - } - var status: String - switch sdkStatus { - case .active: status = "active" - case .legacy: status = "legacy" - default: throw BedrockServiceError.notSupported("Unknown BedrockClientTypes.FoundationModelLifecycleStatus") - } - var responseStreamingSupported = false - if sdkModelSummary.responseStreamingSupported != nil { - responseStreamingSupported = sdkModelSummary.responseStreamingSupported! - } - let bedrockModel = BedrockModel(rawValue: modelId) ?? BedrockModel(rawValue: "us.\(modelId)") - - return ModelSummary( - modelName: modelName, - providerName: providerName, - modelId: modelId, - modelArn: modelArn, - modelLifecylceStatus: status, - responseStreamingSupported: responseStreamingSupported, - bedrockModel: bedrockModel - ) - } -} diff --git a/backend/Sources/BedrockService/ParameterValidation.swift b/backend/Sources/BedrockService/ParameterValidation.swift deleted file mode 100644 index a097c44a..00000000 --- a/backend/Sources/BedrockService/ParameterValidation.swift +++ /dev/null @@ -1,229 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation -import BedrockTypes - -extension BedrockService { - - /// Validate parameters for a text completion request - public func validateTextCompletionParams( - modality: any TextModality, - prompt: String?, - maxTokens: Int?, - temperature: Double?, - topP: Double?, - topK: Int?, - stopSequences: [String]? - ) throws { - let parameters = modality.getParameters() - if maxTokens != nil { - try validateParameterValue(maxTokens!, parameter: parameters.maxTokens) - } - if temperature != nil { - try validateParameterValue(temperature!, parameter: parameters.temperature) - } - if topP != nil { - try validateParameterValue(topP!, parameter: parameters.topP) - } - if topK != nil { - try validateParameterValue(topK!, parameter: parameters.topK) - } - if stopSequences != nil { - try validateStopSequences(stopSequences!, maxNrOfStopSequences: parameters.stopSequences.maxSequences) - } - if prompt != nil { - try validatePrompt(prompt!, maxPromptTokens: parameters.prompt.maxSize) - } - } - - /// Validate parameters for an image generation request - public func validateImageGenerationParams( - modality: any ImageModality, - nrOfImages: Int?, - cfgScale: Double?, - resolution: ImageResolution?, - seed: Int? - ) throws { - let parameters = modality.getParameters() - if nrOfImages != nil { - try validateParameterValue(nrOfImages!, parameter: parameters.nrOfImages) - } - if cfgScale != nil { - try validateParameterValue(cfgScale!, parameter: parameters.cfgScale) - } - if seed != nil { - try validateParameterValue(seed!, parameter: parameters.seed) - } - if resolution != nil { - try modality.validateResolution(resolution!) - } - } - - /// Validate specific parameters for a text to image request - public func validateTextToImageParams( - modality: any TextToImageModality, - prompt: String, - negativePrompt: String? - ) throws { - let textToImageParameters = modality.getTextToImageParameters() - try validatePrompt(prompt, maxPromptTokens: textToImageParameters.prompt.maxSize) - if negativePrompt != nil { - try validatePrompt(negativePrompt!, maxPromptTokens: textToImageParameters.negativePrompt.maxSize) - } - } - - /// Validate specific parameters for an image variation request - public func validateImageVariationParams( - modality: any ImageVariationModality, - images: [String], - prompt: String?, - similarity: Double?, - negativePrompt: String? - ) throws { - let imageVariationParameters = modality.getImageVariationParameters() - try validateParameterValue(images.count, parameter: imageVariationParameters.images) - if prompt != nil { - try validatePrompt(prompt!, maxPromptTokens: imageVariationParameters.prompt.maxSize) - } - if similarity != nil { - try validateParameterValue(similarity!, parameter: imageVariationParameters.similarity) - } - if negativePrompt != nil { - try validatePrompt(negativePrompt!, maxPromptTokens: imageVariationParameters.negativePrompt.maxSize) - } - } - - /// Validate parameters for a converse request - public func validateConverseParams( - modality: any TextModality, - prompt: String, - history: [Message], - maxTokens: Int?, - temperature: Double?, - topP: Double?, - stopSequences: [String]? - ) throws { - let parameters = modality.getParameters() - try validatePrompt(prompt, maxPromptTokens: parameters.prompt.maxSize) - if maxTokens != nil { - try validateParameterValue(maxTokens!, parameter: parameters.maxTokens) - } - if temperature != nil { - try validateParameterValue(temperature!, parameter: parameters.temperature) - } - if topP != nil { - try validateParameterValue(topP!, parameter: parameters.topP) - } - if stopSequences != nil { - try validateStopSequences(stopSequences!, maxNrOfStopSequences: parameters.stopSequences.maxSequences) - } - } - - // MARK: private helpers - - // Validate a parameter value with the min and max value saved in the Parameter - private func validateParameterValue(_ value: T, parameter: Parameter) throws { - guard parameter.isSupported else { - logger.trace("Unsupported parameter", metadata: ["parameter": "\(parameter.name)"]) - throw BedrockServiceError.notSupported("Parameter \(parameter.name) is not supported.") - } - if let min = parameter.minValue { - guard value >= min else { - logger.trace( - "Invalid parameter", - metadata: [ - "parameter": "\(parameter.name)", - "value": "\(value)", - "value.min": "\(min)", - ] - ) - throw BedrockServiceError.invalidParameter( - parameter.name, - "Parameter \(parameter.name) should be at least \(min). Value: \(value)" - ) - } - } - if let max = parameter.maxValue { - guard value <= max else { - logger.trace( - "Invalid parameter", - metadata: [ - "parameter": "\(parameter.name)", - "value": "\(value)", - "value.max": "\(max)", - ] - ) - throw BedrockServiceError.invalidParameter( - parameter.name, - "Parameter \(parameter.name) should be at most \(max). Value: \(value)" - ) - } - } - logger.trace( - "Valid parameter", - metadata: [ - "parameter": "\(parameter.name)", "value": "\(value)", - "value.min": "\(String(describing: parameter.minValue))", - "value.max": "\(String(describing: parameter.maxValue))" - ] - ) - } - - /// Validate prompt is not empty and does not consist of only whitespaces, tabs or newlines - /// Additionally validates that the prompt is not longer than the maxPromptTokens - private func validatePrompt(_ prompt: String, maxPromptTokens: Int?) throws { - guard !prompt.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).isEmpty else { - logger.trace("Invalid prompt", metadata: ["prompt": .string(prompt)]) - throw BedrockServiceError.invalidPrompt("Prompt is not allowed to be empty.") - } - if let maxPromptTokens = maxPromptTokens { - let length = prompt.utf8.count - guard length <= maxPromptTokens else { - logger.trace( - "Invalid prompt", - metadata: [ - "prompt": .string(prompt), - "prompt.length": "\(length)", - "maxPromptTokens": "\(maxPromptTokens)", - ] - ) - throw BedrockServiceError.invalidPrompt( - "Prompt is not allowed to be longer than \(maxPromptTokens) tokens. Prompt lengt \(length)" - ) - } - } - } - - /// Validate that not more stopsequences than allowed were given - private func validateStopSequences(_ stopSequences: [String], maxNrOfStopSequences: Int?) throws { - if let maxNrOfStopSequences = maxNrOfStopSequences { - guard stopSequences.count <= maxNrOfStopSequences else { - logger.trace( - "Invalid stopSequences", - metadata: [ - "stopSequences": "\(stopSequences)", - "stopSequences.count": "\(stopSequences.count)", - "maxNrOfStopSequences": "\(maxNrOfStopSequences)", - ] - ) - throw BedrockServiceError.invalidStopSequences( - stopSequences, - "You can only provide up to \(maxNrOfStopSequences) stop sequences. Number of stop sequences: \(stopSequences.count)" - ) - } - } - } -} diff --git a/backend/Sources/BedrockService/Protocols/BedrockClientProtocol.swift b/backend/Sources/BedrockService/Protocols/BedrockClientProtocol.swift deleted file mode 100644 index fb243d70..00000000 --- a/backend/Sources/BedrockService/Protocols/BedrockClientProtocol.swift +++ /dev/null @@ -1,29 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -@preconcurrency import AWSBedrock -import AWSClientRuntime -import AWSSDKIdentity -import Foundation - -// Protocol allows writing mocks for unit tests -public protocol BedrockClientProtocol: Sendable { - func listFoundationModels( - input: ListFoundationModelsInput - ) async throws - -> ListFoundationModelsOutput -} - -extension BedrockClient: @retroactive @unchecked Sendable, BedrockClientProtocol {} diff --git a/backend/Sources/BedrockService/Protocols/BedrockRuntimeClientProtocol.swift b/backend/Sources/BedrockService/Protocols/BedrockRuntimeClientProtocol.swift deleted file mode 100644 index 4de31d56..00000000 --- a/backend/Sources/BedrockService/Protocols/BedrockRuntimeClientProtocol.swift +++ /dev/null @@ -1,28 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -@preconcurrency import AWSBedrockRuntime -import AWSClientRuntime -import AWSSDKIdentity -import Foundation -import BedrockTypes - -// Protocol allows writing mocks for unit tests -public protocol BedrockRuntimeClientProtocol: Sendable { - func invokeModel(input: InvokeModelInput) async throws -> InvokeModelOutput - func converse(input: ConverseInput) async throws -> ConverseOutput -} - -extension BedrockRuntimeClient: @retroactive @unchecked Sendable, BedrockRuntimeClientProtocol {} diff --git a/backend/Sources/BedrockService/SwiftBedrock.swift b/backend/Sources/BedrockService/SwiftBedrock.swift deleted file mode 100644 index 9e6df845..00000000 --- a/backend/Sources/BedrockService/SwiftBedrock.swift +++ /dev/null @@ -1,532 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -@preconcurrency import AWSBedrock -@preconcurrency import AWSBedrockRuntime -import AWSClientRuntime -import AWSSDKIdentity -import Foundation -import Logging -import BedrockTypes - -public struct BedrockService: Sendable { - let region: Region - let logger: Logger - private let bedrockClient: BedrockClientProtocol - private let bedrockRuntimeClient: BedrockRuntimeClientProtocol - - // MARK: - Initialization - - /// Initializes a new SwiftBedrock instance - /// - Parameters: - /// - region: The AWS region to use (defaults to .useast1) - /// - logger: Optional custom logger instance - /// - bedrockClient: Optional custom Bedrock client - /// - bedrockRuntimeClient: Optional custom Bedrock Runtime client - /// - useSSO: Whether to use SSO authentication (defaults to false) - /// - Throws: Error if client initialization fails - public init( - region: Region = .useast1, - logger: Logger? = nil, - bedrockClient: BedrockClientProtocol? = nil, - bedrockRuntimeClient: BedrockRuntimeClientProtocol? = nil, - useSSO: Bool = false - ) async throws { - self.logger = logger ?? BedrockService.createLogger("swiftbedrock.service") - self.logger.trace( - "Initializing SwiftBedrock", - metadata: ["region": .string(region.rawValue)] - ) - self.region = region - - if bedrockClient != nil { - self.logger.trace("Using supplied bedrockClient") - self.bedrockClient = bedrockClient! - } else { - self.logger.trace("Creating bedrockClient") - self.bedrockClient = try await BedrockService.createBedrockClient( - region: region, - useSSO: useSSO - ) - self.logger.trace( - "Created bedrockClient", - metadata: ["useSSO": "\(useSSO)"] - ) - } - if bedrockRuntimeClient != nil { - self.logger.trace("Using supplied bedrockRuntimeClient") - self.bedrockRuntimeClient = bedrockRuntimeClient! - } else { - self.logger.trace("Creating bedrockRuntimeClient") - self.bedrockRuntimeClient = try await BedrockService.createBedrockRuntimeClient( - region: region, - useSSO: useSSO - ) - self.logger.trace( - "Created bedrockRuntimeClient", - metadata: ["useSSO": "\(useSSO)"] - ) - } - self.logger.trace( - "Initialized SwiftBedrock", - metadata: ["region": .string(region.rawValue)] - ) - } - - // MARK: - Private Helpers - - /// Creates Logger using either the loglevel saved as en environment variable `SWIFT_BEDROCK_LOG_LEVEL` or with default `.trace` - static private func createLogger(_ name: String) -> Logger { - var logger: Logger = Logger(label: name) - logger.logLevel = - ProcessInfo.processInfo.environment["SWIFT_BEDROCK_LOG_LEVEL"].flatMap { - Logger.Level(rawValue: $0.lowercased()) - } ?? .trace // FIXME: trace for me, later .info - return logger - } - - /// Creates a BedrockClient - static private func createBedrockClient( - region: Region, - useSSO: Bool = false - ) async throws - -> BedrockClientProtocol - { - let config = try await BedrockClient.BedrockClientConfiguration( - region: region.rawValue - ) - if useSSO { - config.awsCredentialIdentityResolver = try SSOAWSCredentialIdentityResolver() - } - return BedrockClient(config: config) - } - - /// Creates a BedrockRuntimeClient - static private func createBedrockRuntimeClient( - region: Region, - useSSO: Bool = false - ) - async throws - -> BedrockRuntimeClientProtocol - { - let config = - try await BedrockRuntimeClient.BedrockRuntimeClientConfiguration( - region: region.rawValue - ) - if useSSO { - config.awsCredentialIdentityResolver = try SSOAWSCredentialIdentityResolver() - } - return BedrockRuntimeClient(config: config) - } - - // MARK: Public Methods - - /// Lists all available foundation models from Amazon Bedrock - /// - Throws: BedrockServiceError.invalidResponse - /// - Returns: An array of ModelInfo objects containing details about each available model. - public func listModels() async throws -> [ModelSummary] { - logger.trace("Fetching foundation models") - do { - let response = try await bedrockClient.listFoundationModels( - input: ListFoundationModelsInput() - ) - guard let models = response.modelSummaries else { - logger.trace("Failed to extract modelSummaries from response") - throw BedrockServiceError.invalidSDKResponse( - "Something went wrong while extracting the modelSummaries from the response." - ) - } - var modelsInfo: [ModelSummary] = [] - modelsInfo = try models.compactMap { (sdkModelSummary) -> ModelSummary? in - try ModelSummary.getModelSummary(from: sdkModelSummary) - } - logger.trace( - "Fetched foundation models", - metadata: [ - "models.count": "\(modelsInfo.count)", - "models.content": .string(String(describing: modelsInfo)), - ] - ) - return modelsInfo - } catch { - logger.trace("Error while listing foundation models", metadata: ["error": "\(error)"]) - throw error - } - } - - /// Generates a text completion using a specified model. - /// - Parameters: - /// - text: the text to be completed - /// - model: the BedrockModel that will be used to generate the completion - /// - maxTokens: the maximum amount of tokens in the completion (must be at least 1) optional, default 300 - /// - temperature: the temperature used to generate the completion (must be a value between 0 and 1) optional, default 0.6 - /// - Throws: BedrockServiceError.invalidMaxTokens if maxTokens is less than 1 - /// BedrockServiceError.invalidTemperature if temperature is not between 0 and 1 - /// BedrockServiceError.invalidPrompt if the prompt is empty - /// BedrockServiceError.invalidResponse if the response body is missing - /// - Returns: a TextCompletion object containing the generated text from the model - public func completeText( - _ prompt: String, - with model: BedrockModel, - maxTokens: Int? = nil, - temperature: Double? = nil, - topP: Double? = nil, - topK: Int? = nil, - stopSequences: [String]? = nil - ) async throws -> TextCompletion { - logger.trace( - "Generating text completion", - metadata: [ - "model.id": .string(model.id), - "model.modality": .string(model.modality.getName()), - "prompt": .string(prompt), - "maxTokens": .stringConvertible(maxTokens ?? "not defined"), - "temperature": .stringConvertible(temperature ?? "not defined"), - "topP": .stringConvertible(topP ?? "not defined"), - "topK": .stringConvertible(topK ?? "not defined"), - "stopSequences": .stringConvertible(stopSequences ?? "not defined"), - ] - ) - do { - let modality = try model.getTextModality() - try validateTextCompletionParams( - modality: modality, - prompt: prompt, - maxTokens: maxTokens, - temperature: temperature, - topP: topP, - topK: topK, - stopSequences: stopSequences - ) - - logger.trace( - "Creating InvokeModelRequest", - metadata: [ - "model": .string(model.id), - "prompt": "\(prompt)", - ] - ) - let request: InvokeModelRequest = try InvokeModelRequest.createTextRequest( - model: model, - prompt: prompt, - maxTokens: maxTokens, - temperature: temperature, - topP: topP, - topK: topK, - stopSequences: stopSequences - ) - let input: InvokeModelInput = try request.getInvokeModelInput() - logger.trace( - "Sending request to invokeModel", - metadata: [ - "model": .string(model.id), "request": .string(String(describing: input)), - ] - ) - - let response = try await self.bedrockRuntimeClient.invokeModel(input: input) - logger.trace( - "Received response from invokeModel", - metadata: [ - "model": .string(model.id), "response": .string(String(describing: response)), - ] - ) - - guard let responseBody = response.body else { - logger.trace( - "Invalid response", - metadata: [ - "response": .string(String(describing: response)), - "hasBody": .stringConvertible(response.body != nil), - ] - ) - throw BedrockServiceError.invalidSDKResponse( - "Something went wrong while extracting body from response." - ) - } - if let bodyString = String(data: responseBody, encoding: .utf8) { - logger.trace("Extracted body from response", metadata: ["response.body": "\(bodyString)"]) - } - - let invokemodelResponse: InvokeModelResponse = try InvokeModelResponse.createTextResponse( - body: responseBody, - model: model - ) - logger.trace( - "Generated text completion", - metadata: [ - "model": .string(model.id), "response": .string(String(describing: invokemodelResponse)), - ] - ) - return try invokemodelResponse.getTextCompletion() - } catch { - logger.trace("Error while completing text", metadata: ["error": "\(error)"]) - throw error - } - } - - /// Generates 1 to 5 image(s) from a text prompt using a specific model. - /// - Parameters: - /// - prompt: the prompt describing the image that should be generated - /// - model: the BedrockModel that will be used to generate the image - /// - nrOfImages: the number of images that will be generated (must be a number between 1 and 5) optional, default 3 - /// - Throws: BedrockServiceError.invalidNrOfImages if nrOfImages is not between 1 and 5 - /// BedrockServiceError.invalidPrompt if the prompt is empty - /// BedrockServiceError.invalidResponse if the response body is missing - /// - Returns: a ImageGenerationOutput object containing an array of generated images - public func generateImage( - _ prompt: String, - with model: BedrockModel, - negativePrompt: String? = nil, - nrOfImages: Int? = nil, - cfgScale: Double? = nil, - seed: Int? = nil, - quality: ImageQuality? = nil, - resolution: ImageResolution? = nil - ) async throws -> ImageGenerationOutput { - logger.trace( - "Generating image(s)", - metadata: [ - "model.id": .string(model.id), - "model.modality": .string(model.modality.getName()), - "prompt": .string(prompt), - "negativePrompt": .stringConvertible(negativePrompt ?? "not defined"), - "nrOfImages": .stringConvertible(nrOfImages ?? "not defined"), - "cfgScale": .stringConvertible(cfgScale ?? "not defined"), - "seed": .stringConvertible(seed ?? "not defined"), - ] - ) - do { - let modality = try model.getImageModality() - try validateImageGenerationParams( - modality: modality, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - resolution: resolution, - seed: seed - ) - let textToImageModality = try model.getTextToImageModality() - try validateTextToImageParams(modality: textToImageModality, prompt: prompt, negativePrompt: negativePrompt) - - let request: InvokeModelRequest = try InvokeModelRequest.createTextToImageRequest( - model: model, - prompt: prompt, - negativeText: negativePrompt, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - let input: InvokeModelInput = try request.getInvokeModelInput() - logger.trace( - "Sending request to invokeModel", - metadata: [ - "model": .string(model.id), "request": .string(String(describing: input)), - ] - ) - let response = try await self.bedrockRuntimeClient.invokeModel(input: input) - guard let responseBody = response.body else { - logger.trace( - "Invalid response", - metadata: [ - "response": .string(String(describing: response)), - "hasBody": .stringConvertible(response.body != nil), - ] - ) - throw BedrockServiceError.invalidSDKResponse( - "Something went wrong while extracting body from response." - ) - } - let invokemodelResponse: InvokeModelResponse = try InvokeModelResponse.createImageResponse( - body: responseBody, - model: model - ) - return try invokemodelResponse.getGeneratedImage() - } catch { - logger.trace("Error while generating image", metadata: ["error": "\(error)"]) - throw error - } - } - - /// Generates 1 to 5 imagevariation(s) from reference images and a text prompt using a specific model. - /// - Parameters: - /// - image: the reference images - /// - prompt: the prompt describing the image that should be generated - /// - model: the BedrockModel that will be used to generate the image - /// - nrOfImages: the number of images that will be generated (must be a number between 1 and 5) optional, default 3 - /// - Throws: BedrockServiceError.invalidNrOfImages if nrOfImages is not between 1 and 5 - /// BedrockServiceError.similarity if similarity is not between 0.2 - 1.0 - /// BedrockServiceError.invalidPrompt if the prompt is empty - /// BedrockServiceError.invalidResponse if the response body is missing - /// - Returns: a ImageGenerationOutput object containing an array of generated images - public func generateImageVariation( - images: [String], - prompt: String, - with model: BedrockModel, - negativePrompt: String? = nil, - similarity: Double? = nil, - nrOfImages: Int? = nil, - cfgScale: Double? = nil, - seed: Int? = nil, - quality: ImageQuality? = nil, - resolution: ImageResolution? = nil - ) async throws -> ImageGenerationOutput { - logger.trace( - "Generating image(s) from reference image", - metadata: [ - "model.id": .string(model.id), - "model.modality": .string(model.modality.getName()), - "prompt": .string(prompt), - "nrOfImages": .stringConvertible(nrOfImages ?? "not defined"), - "similarity": .stringConvertible(similarity ?? "not defined"), - "negativePrompt": .stringConvertible(negativePrompt ?? "not defined"), - "cfgScale": .stringConvertible(cfgScale ?? "not defined"), - "seed": .stringConvertible(seed ?? "not defined"), - ] - ) - do { - let modality = try model.getImageModality() - try validateImageGenerationParams( - modality: modality, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - resolution: resolution, - seed: seed - ) - let imageVariationModality = try model.getImageVariationModality() - try validateImageVariationParams( - modality: imageVariationModality, - images: images, - prompt: prompt, - similarity: similarity, - negativePrompt: negativePrompt - ) - let request: InvokeModelRequest = try InvokeModelRequest.createImageVariationRequest( - model: model, - prompt: prompt, - negativeText: negativePrompt, - images: images, - similarity: similarity, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - let input: InvokeModelInput = try request.getInvokeModelInput() - logger.trace( - "Sending request to invokeModel", - metadata: [ - "model": .string(model.id), "request": .string(String(describing: input)), - ] - ) - let response = try await self.bedrockRuntimeClient.invokeModel(input: input) - guard let responseBody = response.body else { - logger.trace( - "Invalid response", - metadata: [ - "response": .string(String(describing: response)), - "hasBody": .stringConvertible(response.body != nil), - ] - ) - throw BedrockServiceError.invalidSDKResponse( - "Something went wrong while extracting body from response." - ) - } - let invokemodelResponse: InvokeModelResponse = try InvokeModelResponse.createImageResponse( - body: responseBody, - model: model - ) - return try invokemodelResponse.getGeneratedImage() - } catch { - logger.trace("Error while generating image variations", metadata: ["error": "\(error)"]) - throw error - } - } - - /// Use Converse API - public func converse( - with model: BedrockModel, - prompt: String, - history: [Message] = [], - maxTokens: Int? = nil, - temperature: Double? = nil, - topP: Double? = nil, - stopSequences: [String]? = nil - ) async throws -> (String, [Message]) { - logger.trace( - "Conversing", - metadata: [ - "model.id": .string(model.id), - "model.modality": .string(model.modality.getName()), - "prompt": .string(prompt), - ] - ) - do { - let modality = try model.getTextModality() // FIXME later: ConverseModality? - try validateConverseParams( - modality: modality, - prompt: prompt, - history: history, - maxTokens: maxTokens, - temperature: temperature, - topP: topP, - stopSequences: stopSequences - ) - - var messages = history - messages.append(Message(from: .user, content: [.text(prompt)])) - - let converseRequest = ConverseRequest( - model: model, - messages: messages, - maxTokens: maxTokens, - temperature: temperature, - topP: topP, - stopSequences: stopSequences - ) - let input = converseRequest.getConverseInput() - logger.trace( - "Created ConverseInput", - metadata: ["messages.count": "\(messages.count)", "model": "\(model.id)"] - ) - let response = try await self.bedrockRuntimeClient.converse(input: input) - logger.trace("Received response", metadata: ["response": "\(response)"]) - - guard let converseOutput = response.output else { - logger.trace( - "Invalid response", - metadata: [ - "response": .string(String(describing: response)), - "hasOutput": .stringConvertible(response.output != nil), - ] - ) - throw BedrockServiceError.invalidSDKResponse( - "Something went wrong while extracting ConverseOutput from response." - ) - } - let converseResponse = try ConverseResponse(converseOutput) - messages.append(converseResponse.message) - logger.trace( - "Received message", - metadata: ["replyMessage": "\(converseResponse.message)", "messages.count": "\(messages.count)"] - ) - return (converseResponse.getReply(), messages) - } catch { - logger.trace("Error while conversing", metadata: ["error": "\(error)"]) - throw error - } - } -} diff --git a/backend/Sources/BedrockTypes/BedrockModel.swift b/backend/Sources/BedrockTypes/BedrockModel.swift deleted file mode 100644 index fafea5b3..00000000 --- a/backend/Sources/BedrockTypes/BedrockModel.swift +++ /dev/null @@ -1,287 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct BedrockModel: Hashable, Sendable, Equatable, RawRepresentable { - public var rawValue: String { id } - - public var id: String - public var name: String - public let modality: any Modality - - /// Creates a new BedrockModel instance - /// - Parameters: - /// - id: The unique identifier for the model - /// - modality: The modality of the model - public init( - id: String, - name: String, - modality: any Modality - ) { - self.id = id - self.modality = modality - self.name = name - } - - /// Creates an implemented BedrockModel instance from a raw string value - /// - Parameter rawValue: The model identifier string - /// - Returns: The corresponding BedrockModel instance or nil if the model is not implemented - public init?(rawValue: String) { - switch rawValue { - // claude - case BedrockModel.instant.id: - self = BedrockModel.instant - case BedrockModel.claudev1.id: - self = BedrockModel.claudev1 - case BedrockModel.claudev2.id: - self = BedrockModel.claudev2 - case BedrockModel.claudev2_1.id: - self = BedrockModel.claudev2_1 - case BedrockModel.claudev3_haiku.id: - self = BedrockModel.claudev3_haiku - case BedrockModel.claudev3_5_haiku.id: - self = BedrockModel.claudev3_5_haiku - case BedrockModel.claudev3_opus.id: - self = BedrockModel.claudev3_opus - case BedrockModel.claudev3_5_sonnet.id: - self = BedrockModel.claudev3_5_sonnet - case BedrockModel.claudev3_5_sonnet_v2.id: - self = BedrockModel.claudev3_5_sonnet_v2 - case BedrockModel.claudev3_7_sonnet.id: - self = BedrockModel.claudev3_7_sonnet - // titan - case BedrockModel.titan_text_g1_premier.id: - self = BedrockModel.titan_text_g1_premier - case BedrockModel.titan_text_g1_express.id: - self = BedrockModel.titan_text_g1_express - case BedrockModel.titan_text_g1_lite.id: - self = BedrockModel.titan_text_g1_lite - // nova - case BedrockModel.nova_micro.id: - self = BedrockModel.nova_micro - case BedrockModel.titan_image_g1_v2.id: - self = BedrockModel.titan_image_g1_v2 - case BedrockModel.titan_image_g1_v1.id: - self = BedrockModel.titan_image_g1_v1 - case BedrockModel.nova_canvas.id: - self = BedrockModel.nova_canvas - // deepseek - case BedrockModel.deepseek_r1_v1.id: - self = BedrockModel.deepseek_r1_v1 - // llama - case BedrockModel.llama_3_8b_instruct.id: self = BedrockModel.llama_3_8b_instruct - case BedrockModel.llama3_70b_instruct.id: self = BedrockModel.llama3_70b_instruct - case BedrockModel.llama3_1_8b_instruct.id: self = BedrockModel.llama3_1_8b_instruct - case BedrockModel.llama3_1_70b_instruct.id: self = BedrockModel.llama3_1_70b_instruct - case BedrockModel.llama3_2_1b_instruct.id: self = BedrockModel.llama3_2_1b_instruct - case BedrockModel.llama3_2_3b_instruct.id: self = BedrockModel.llama3_2_3b_instruct - case BedrockModel.llama3_3_70b_instruct.id: self = BedrockModel.llama3_3_70b_instruct - default: - return nil - } - } - - /// Checks if the model supports text generation - /// - Returns: True if the model supports text generation - public func hasTextModality() -> Bool { - modality as? any TextModality != nil - } - - /// Checks if the model supports text generation and returns TextModality - /// - Returns: TextModality if the model supports text modality - public func getTextModality() throws -> any TextModality { - guard let textModality = modality as? any TextModality else { - throw BedrockServiceError.invalidModality( - self, - modality, - "Model \(id) does not support text generation" - ) - } - return textModality - } - - /// Checks if the model supports image generation - /// - Returns: True if the model supports image generation - public func hasImageModality() -> Bool { - modality as? any ImageModality != nil - } - - /// Checks if the model supports image generation and returns ImageModality - /// - Returns: TextModality if the model supports image modality - public func getImageModality() throws -> any ImageModality { - guard let imageModality = modality as? any ImageModality else { - throw BedrockServiceError.invalidModality( - self, - modality, - "Model \(id) does not support image generation" - ) - } - return imageModality - } - - /// Checks if the model supports text to image generation and returns TextToImageModality - /// - Returns: TextToImageModality if the model supports image modality - public func getTextToImageModality() throws -> any TextToImageModality { - guard let textToImageModality = modality as? any TextToImageModality else { - throw BedrockServiceError.invalidModality( - self, - modality, - "Model \(id) does not support text to image generation" - ) - } - return textToImageModality - } - - /// Checks if the model supports image variation and returns ImageVariationModality - /// - Returns: ImageVariationModality if the model supports image modality - public func getImageVariationModality() throws -> any ImageVariationModality { - guard let modality = modality as? any ImageVariationModality else { - throw BedrockServiceError.invalidModality( - self, - modality, - "Model \(id) does not support image variation" - ) - } - return modality - } - - /// Checks if the model supports text to image generation - /// - Returns: True if the model supports text to image generation - public func hasTextToImageModality() -> Bool { - modality as? any TextToImageModality != nil - } - - /// Checks if the model supports image variation - /// - Returns: True if the model supports image variation - public func hasImageVariationModality() -> Bool { - modality as? any ImageVariationModality != nil - } - - /// Checks if the model supports conditioned text to image generation - /// - Returns: True if the model supports conditioned text to image generation - public func hasConditionedTextToImageModality() -> Bool { - modality as? any ConditionedTextToImageModality != nil - } -} - -extension BedrockModel: Encodable { - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - - // Encode basic information - try container.encode(name, forKey: .modelName) - try container.encode(id, forKey: .modelId) - try container.encode(String(describing: type(of: modality)), forKey: .supportedModality) - - if hasTextModality() { - try encodeTextParameters(to: &container) - } - - if hasImageModality() { - try encodeImageParameters(to: &container) - } - } - - private enum CodingKeys: String, CodingKey { - case modelName - case modelId - case temperatureRange - case maxTokenRange - case topPRange - case topKRange - case nrOfImagesRange - case cfgScaleRange - case seedRange - case similarityRange - case supportedModality - } - - private enum RangeKeys: String, CodingKey { - case min - case max - case `default` - } - - private func encodeTextParameters(to container: inout KeyedEncodingContainer) throws { - let textModality = try getTextModality() - let params = textModality.getParameters() - - if params.temperature.isSupported { - var tempContainer = container.nestedContainer(keyedBy: RangeKeys.self, forKey: .temperatureRange) - try tempContainer.encode(params.temperature.minValue, forKey: .min) - try tempContainer.encode(params.temperature.maxValue, forKey: .max) - try tempContainer.encode(params.temperature.defaultValue, forKey: .default) - } - if params.maxTokens.isSupported { - var tokenContainer = container.nestedContainer(keyedBy: RangeKeys.self, forKey: .maxTokenRange) - try tokenContainer.encode(params.maxTokens.minValue, forKey: .min) - try tokenContainer.encode(params.maxTokens.maxValue, forKey: .max) - try tokenContainer.encode(params.maxTokens.defaultValue, forKey: .default) - } - if params.topP.isSupported { - var topPContainer = container.nestedContainer(keyedBy: RangeKeys.self, forKey: .topPRange) - try topPContainer.encode(params.topP.minValue, forKey: .min) - try topPContainer.encode(params.topP.maxValue, forKey: .max) - try topPContainer.encode(params.topP.defaultValue, forKey: .default) - } - if params.topK.isSupported { - var topKContainer = container.nestedContainer(keyedBy: RangeKeys.self, forKey: .topKRange) - try topKContainer.encode(params.topK.minValue, forKey: .min) - try topKContainer.encode(params.topK.maxValue, forKey: .max) - try topKContainer.encode(params.topK.defaultValue, forKey: .default) - } - } - - private func encodeImageParameters(to container: inout KeyedEncodingContainer) throws { - let imageModality = try getImageModality() - let params = imageModality.getParameters() - - // General image generation inference parameters - if params.nrOfImages.isSupported { - var imagesContainer = container.nestedContainer(keyedBy: RangeKeys.self, forKey: .nrOfImagesRange) - try imagesContainer.encode(params.nrOfImages.minValue, forKey: .min) - try imagesContainer.encode(params.nrOfImages.maxValue, forKey: .max) - try imagesContainer.encode(params.nrOfImages.defaultValue, forKey: .default) - } - if params.cfgScale.isSupported { - var cfgScaleContainer = container.nestedContainer(keyedBy: RangeKeys.self, forKey: .cfgScaleRange) - try cfgScaleContainer.encode(params.cfgScale.minValue, forKey: .min) - try cfgScaleContainer.encode(params.cfgScale.maxValue, forKey: .max) - try cfgScaleContainer.encode(params.cfgScale.defaultValue, forKey: .default) - } - if params.seed.isSupported { - var seedContainer = container.nestedContainer(keyedBy: RangeKeys.self, forKey: .seedRange) - try seedContainer.encode(params.seed.minValue, forKey: .min) - try seedContainer.encode(params.seed.maxValue, forKey: .max) - try seedContainer.encode(params.seed.defaultValue, forKey: .default) - } - - // If the model supports image variation, encode similarity range - if hasImageVariationModality() { - let variationModality = try getImageVariationModality() - let variationParams = variationModality.getImageVariationParameters() - if variationParams.similarity.isSupported { - var similarityContainer = container.nestedContainer( - keyedBy: RangeKeys.self, - forKey: .similarityRange - ) - try similarityContainer.encode(variationParams.similarity.minValue, forKey: .min) - try similarityContainer.encode(variationParams.similarity.maxValue, forKey: .max) - try similarityContainer.encode(variationParams.similarity.defaultValue, forKey: .default) - } - } - } -} diff --git a/backend/Sources/BedrockTypes/BedrockServiceError.swift b/backend/Sources/BedrockTypes/BedrockServiceError.swift deleted file mode 100644 index e5c56fef..00000000 --- a/backend/Sources/BedrockTypes/BedrockServiceError.swift +++ /dev/null @@ -1,32 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public enum BedrockServiceError: Error { - case invalidParameter(ParameterName, String) - case invalidModality(BedrockModel, Modality, String) - // case invalidModel(BedrockModel, String) - case invalidPrompt(String) - case invalidStopSequences([String], String) - case invalidSDKResponse(String) - case invalidSDKResponseBody(Data?) - case completionNotFound(String) - case encodingError(String) - case decodingError(String) - case notImplemented(String) - case notSupported(String) - case notFound(String) -} diff --git a/backend/Sources/BedrockTypes/Content.swift b/backend/Sources/BedrockTypes/Content.swift deleted file mode 100644 index 3fedbf9d..00000000 --- a/backend/Sources/BedrockTypes/Content.swift +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public enum Content: Codable { - case text(String) -} \ No newline at end of file diff --git a/backend/Sources/BedrockTypes/ContentType.swift b/backend/Sources/BedrockTypes/ContentType.swift deleted file mode 100644 index ddb0e9e1..00000000 --- a/backend/Sources/BedrockTypes/ContentType.swift +++ /dev/null @@ -1,27 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public enum ContentType { - case json - - public var headerValue: String { - switch self { - case .json: - return "application/json" - } - } -} diff --git a/backend/Sources/BedrockTypes/ImageGenerationOutput.swift b/backend/Sources/BedrockTypes/ImageGenerationOutput.swift deleted file mode 100644 index fdd45e89..00000000 --- a/backend/Sources/BedrockTypes/ImageGenerationOutput.swift +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct ImageGenerationOutput: Codable { - public let images: [Data] -} diff --git a/backend/Sources/BedrockTypes/ImageResolution.swift b/backend/Sources/BedrockTypes/ImageResolution.swift deleted file mode 100644 index 008b6e30..00000000 --- a/backend/Sources/BedrockTypes/ImageResolution.swift +++ /dev/null @@ -1,21 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct ImageResolution: Codable, Equatable, Sendable { - let width: Int - let height: Int -} diff --git a/backend/Sources/BedrockTypes/Message.swift b/backend/Sources/BedrockTypes/Message.swift deleted file mode 100644 index fa38b181..00000000 --- a/backend/Sources/BedrockTypes/Message.swift +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct Message: Codable { - public let role: Role - public let content: [Content] - - // public static func createTextMessage(from role: Role, text: String) -> Self { - // Message(from: role, content: [.text(text)]) - // } - - public init(from role: Role, content: [Content]) { - self.role = role - self.content = content - } -} \ No newline at end of file diff --git a/backend/Sources/BedrockTypes/Modalities/ImageModality.swift b/backend/Sources/BedrockTypes/Modalities/ImageModality.swift deleted file mode 100644 index 1d38f787..00000000 --- a/backend/Sources/BedrockTypes/Modalities/ImageModality.swift +++ /dev/null @@ -1,67 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public protocol ImageResolutionValidator: Sendable { - func validateResolution(_ resolution: ImageResolution) throws -} - -public protocol ImageModality: Modality, ImageResolutionValidator { - func getParameters() -> ImageGenerationParameters - func getImageResponseBody(from: Data) throws -> ContainsImageGeneration -} - -public protocol TextToImageModality: Modality { - func getTextToImageParameters() -> TextToImageParameters - func getTextToImageRequestBody( - prompt: String, - negativeText: String?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) throws -> BedrockBodyCodable -} - -public protocol ConditionedTextToImageModality: Modality { - func getConditionedTextToImageParameters() -> ConditionedTextToImageParameters - func getConditionedTextToImageRequestBody( - prompt: String, - negativeText: String?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) throws -> any BedrockBodyCodable -} - -public protocol ImageVariationModality: Modality { - func getImageVariationParameters() -> ImageVariationParameters - - func getImageVariationRequestBody( - prompt: String?, - negativeText: String?, - images: [String], - similarity: Double?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) throws -> BedrockBodyCodable -} diff --git a/backend/Sources/BedrockTypes/Modalities/Modality.swift b/backend/Sources/BedrockTypes/Modalities/Modality.swift deleted file mode 100644 index c8aa0974..00000000 --- a/backend/Sources/BedrockTypes/Modalities/Modality.swift +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public protocol Modality: Sendable { - func getName() -> String -} diff --git a/backend/Sources/BedrockTypes/Modalities/TextModality.swift b/backend/Sources/BedrockTypes/Modalities/TextModality.swift deleted file mode 100644 index 2995b795..00000000 --- a/backend/Sources/BedrockTypes/Modalities/TextModality.swift +++ /dev/null @@ -1,33 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public protocol TextModality: Modality { - - init(parameters: TextGenerationParameters) - func getParameters() -> TextGenerationParameters - - func getTextRequestBody( - prompt: String, - maxTokens: Int?, - temperature: Double?, - topP: Double?, - topK: Int?, - stopSequences: [String]? - ) throws -> BedrockBodyCodable - - func getTextResponseBody(from data: Data) throws -> ContainsTextCompletion -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/AmazonImage.swift b/backend/Sources/BedrockTypes/Models/Amazon/AmazonImage.swift deleted file mode 100644 index e1059ef0..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/AmazonImage.swift +++ /dev/null @@ -1,118 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -struct AmazonImage: ImageModality, TextToImageModality, ConditionedTextToImageModality, ImageVariationModality { - func getName() -> String { "Amazon Image Generation" } - - let parameters: ImageGenerationParameters - let resolutionValidator: any ImageResolutionValidator - let textToImageParameters: TextToImageParameters - let conditionedTextToImageParameters: ConditionedTextToImageParameters - let imageVariationParameters: ImageVariationParameters - - init( - parameters: ImageGenerationParameters, - resolutionValidator: any ImageResolutionValidator, - textToImageParameters: TextToImageParameters, - conditionedTextToImageParameters: ConditionedTextToImageParameters, - imageVariationParameters: ImageVariationParameters - ) { - self.parameters = parameters - self.textToImageParameters = textToImageParameters - self.conditionedTextToImageParameters = conditionedTextToImageParameters - self.imageVariationParameters = imageVariationParameters - self.resolutionValidator = resolutionValidator - } - - func getParameters() -> ImageGenerationParameters { parameters } - func getTextToImageParameters() -> TextToImageParameters { textToImageParameters } - func getConditionedTextToImageParameters() -> ConditionedTextToImageParameters { conditionedTextToImageParameters } - func getImageVariationParameters() -> ImageVariationParameters { imageVariationParameters } - - func validateResolution(_ resolution: ImageResolution) throws { - try resolutionValidator.validateResolution(resolution) - } - - func getImageResponseBody(from data: Data) throws -> ContainsImageGeneration { - let decoder = JSONDecoder() - return try decoder.decode(AmazonImageResponseBody.self, from: data) - } - - func getTextToImageRequestBody( - prompt: String, - negativeText: String?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) throws -> BedrockBodyCodable { - AmazonImageRequestBody.textToImage( - prompt: prompt, - negativeText: negativeText, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } - - func getConditionedTextToImageRequestBody( - prompt: String, - negativeText: String?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) throws -> any BedrockBodyCodable { - AmazonImageRequestBody.conditionedTextToImage( - prompt: prompt, - negativeText: negativeText, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } - - func getImageVariationRequestBody( - prompt: String?, - negativeText: String?, - images: [String], - similarity: Double?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) throws -> BedrockBodyCodable { - AmazonImageRequestBody.imageVariation( - referenceImages: images, - prompt: prompt, - negativeText: negativeText, - similarity: similarity, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/AmazonImageRequestBody.swift b/backend/Sources/BedrockTypes/Models/Amazon/AmazonImageRequestBody.swift deleted file mode 100644 index 7b01b694..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/AmazonImageRequestBody.swift +++ /dev/null @@ -1,338 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct AmazonImageRequestBody: BedrockBodyCodable { - let taskType: TaskType - private let textToImageParams: TextToImageParams? - private let imageVariationParams: ImageVariationParams? - private let colorGuidedGenerationParams: ColorGuidedGenerationParams? - private let imageGenerationConfig: ImageGenerationConfig - - // MARK: - Initialization - - /// Creates a text-to-image generation request body - /// - Parameters: - /// - prompt: The text description of the image to generate - /// - nrOfImages: The number of images to generate - /// - negativeText: The text description of what to exclude from the generated image - /// - Returns: A configured AmazonImageRequestBody for text-to-image generation - public static func textToImage( - prompt: String, - negativeText: String?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) -> Self { - AmazonImageRequestBody( - prompt: prompt, - negativeText: negativeText, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } - - private init( - prompt: String, - negativeText: String?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) { - self.taskType = .textToImage - self.textToImageParams = TextToImageParams.textToImage(prompt: prompt, negativeText: negativeText) - self.imageVariationParams = nil - self.colorGuidedGenerationParams = nil - self.imageGenerationConfig = ImageGenerationConfig( - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } - - /// Creates a text-to-image conditioned generation request body - /// - Parameters: - /// - prompt: The text description of the image to generate - /// - nrOfImages: The number of images to generate - /// - negativeText: The text description of what to exclude from the generated image - /// - Returns: A configured AmazonImageRequestBody for text-to-image generation - public static func conditionedTextToImage( - prompt: String, - negativeText: String?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) -> Self { - AmazonImageRequestBody( - prompt: prompt, - negativeText: negativeText, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } - - private init( - prompt: String, - negativeText: String?, - conditionImage: String?, - controlMode: ControlMode?, - similarity: Double?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) { - self.taskType = .textToImage - self.textToImageParams = TextToImageParams.conditionedTextToImage( - prompt: prompt, - negativeText: negativeText, - conditionImage: conditionImage, - controlMode: controlMode, - controlStrength: similarity - ) - self.imageVariationParams = nil - self.colorGuidedGenerationParams = nil - self.imageGenerationConfig = ImageGenerationConfig( - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } - - /// Creates an image variation generation request - /// - Parameters: - /// - prompt: The text description to guide the variation generation - /// - referenceImage: The base64-encoded string of the source image - /// - similarity: How similar the variations should be to the source image (0.2-1.0) - /// - nrOfImages: The number of variations to generate (default: 1) - /// - Returns: A configured AmazonImageRequestBody for image variation generation - public static func imageVariation( - referenceImages: [String], - prompt: String?, - negativeText: String?, - similarity: Double?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) -> Self { - AmazonImageRequestBody( - referenceImages: referenceImages, - prompt: prompt, - negativeText: negativeText, - similarity: similarity, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } - - private init( - referenceImages: [String], - prompt: String?, - negativeText: String?, - similarity: Double?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) { - self.taskType = .imageVariation - self.textToImageParams = nil - self.imageVariationParams = ImageVariationParams( - images: referenceImages, - text: prompt, - negativeText: negativeText, - similarityStrength: similarity - ) - self.colorGuidedGenerationParams = nil - self.imageGenerationConfig = ImageGenerationConfig( - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } - - /// Creates a color guided image generation request - /// - Parameters: - /// - prompt: The text description to guide the variation generation - /// - nrOfImages: The number of variations to generate (default: 1) - /// - colors: A list of color codes that will be used in the image, expressed as hexadecimal values in the form “#RRGGBB”. - /// - negativeText: The text description of what to exclude from the generated image - /// - referenceImage: The base64-encoded string of the source image (colors in this image will also be used in the generated image) - /// - Returns: A configured AmazonImageRequestBody for color guided image generation - public static func colorGuidedGeneration( - prompt: String, - colors: [String], - negativeText: String?, - referenceImage: String?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) -> Self { - AmazonImageRequestBody( - prompt: prompt, - colors: colors, - negativeText: negativeText, - referenceImage: referenceImage, - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } - - private init( - prompt: String, - colors: [String], - negativeText: String?, - referenceImage: String?, - nrOfImages: Int?, - cfgScale: Double?, - seed: Int?, - quality: ImageQuality?, - resolution: ImageResolution? - ) { - self.taskType = .colorGuidedGeneration - self.textToImageParams = nil - self.imageVariationParams = nil - self.colorGuidedGenerationParams = ColorGuidedGenerationParams( - text: prompt, - negativeText: negativeText, - colors: colors, - referenceImage: referenceImage - ) - self.imageGenerationConfig = ImageGenerationConfig( - nrOfImages: nrOfImages, - cfgScale: cfgScale, - seed: seed, - quality: quality, - resolution: resolution - ) - } - - // MARK: - Nested Types - - // private struct - - private struct ColorGuidedGenerationParams: Codable { - let text: String - let negativeText: String? - let colors: [String] // list of hexadecimal color values - let referenceImage: String? // base64-encoded image string - } - - private struct ImageVariationParams: Codable { - let images: [String] - let text: String? - let negativeText: String? - let similarityStrength: Double? - } - - private struct TextToImageParams: Codable { - let text: String - let negativeText: String? - let conditionImage: String? - let controlMode: ControlMode? - let controlStrength: Double? - - static func textToImage(prompt: String, negativeText: String?) -> Self { - TextToImageParams( - text: prompt, - negativeText: negativeText, - conditionImage: nil, - controlMode: nil, - controlStrength: nil - ) - } - - static func conditionedTextToImage( - prompt: String, - negativeText: String?, - conditionImage: String?, - controlMode: ControlMode?, - controlStrength: Double? - ) -> Self { - TextToImageParams( - text: prompt, - negativeText: negativeText, - conditionImage: conditionImage, - controlMode: controlMode, - controlStrength: controlStrength - ) - } - } - - private enum ControlMode: String, Codable { - case cannyEdge = "CANNY_EDGE" - case segmentation = "SEGMENTATION" - } - - private struct ImageGenerationConfig: Codable { - let numberOfImages: Int? - let cfgScale: Double? - let seed: Int? - let quality: ImageQuality? - let width: Int? - let height: Int? - - init( - nrOfImages: Int? = nil, - cfgScale: Double? = nil, - seed: Int? = nil, - quality: ImageQuality? = nil, - resolution: ImageResolution? = nil - ) { - self.quality = quality - self.width = resolution?.width ?? nil - self.height = resolution?.height ?? nil - self.cfgScale = cfgScale - self.seed = seed - self.numberOfImages = nrOfImages - } - } -} - -public enum ImageQuality: String, Codable { - case standard = "standard" - case premium = "premium" -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/AmazonImageResponseBody.swift b/backend/Sources/BedrockTypes/Models/Amazon/AmazonImageResponseBody.swift deleted file mode 100644 index 9973c8d2..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/AmazonImageResponseBody.swift +++ /dev/null @@ -1,24 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct AmazonImageResponseBody: ContainsImageGeneration { - let images: [Data] - - public func getGeneratedImage() -> ImageGenerationOutput { - ImageGenerationOutput(images: images) - } -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/Nova/Nova.swift b/backend/Sources/BedrockTypes/Models/Amazon/Nova/Nova.swift deleted file mode 100644 index 8525b357..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/Nova/Nova.swift +++ /dev/null @@ -1,56 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -struct NovaText: TextModality { - func getName() -> String { "Nova Text Generation" } - - let parameters: TextGenerationParameters - - init(parameters: TextGenerationParameters) { - self.parameters = parameters - } - - func getParameters() -> TextGenerationParameters { - parameters - } - - func getTextRequestBody( - prompt: String, - maxTokens: Int?, - temperature: Double?, - topP: Double?, - topK: Int?, - stopSequences: [String]? - ) throws -> BedrockBodyCodable { - if topP != nil && temperature != nil { - throw BedrockServiceError.notSupported("Alter either topP or temperature, but not both.") - } - return NovaRequestBody( - prompt: prompt, - maxTokens: maxTokens ?? parameters.maxTokens.defaultValue, - temperature: temperature ?? parameters.temperature.defaultValue, - topP: topP ?? parameters.topP.defaultValue, - topK: topK ?? parameters.topK.defaultValue, - stopSequences: stopSequences ?? parameters.stopSequences.defaultValue - ) - } - - func getTextResponseBody(from data: Data) throws -> ContainsTextCompletion { - let decoder = JSONDecoder() - return try decoder.decode(NovaResponseBody.self, from: data) - } -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/Nova/NovaBedrockModels.swift b/backend/Sources/BedrockTypes/Models/Amazon/Nova/NovaBedrockModels.swift deleted file mode 100644 index 2a624534..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/Nova/NovaBedrockModels.swift +++ /dev/null @@ -1,67 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -// MARK: text generation -// https://docs.aws.amazon.com/nova/latest/userguide/complete-request-schema.html - -typealias NovaMicro = NovaText - -extension BedrockModel { - public static let nova_micro: BedrockModel = BedrockModel( - id: "amazon.nova-micro-v1:0", name: "Nova Micro", - modality: NovaText( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0.00001, maxValue: 1, defaultValue: 0.7), - maxTokens: Parameter(.maxTokens, minValue: 1, maxValue: 5_000, defaultValue: 5_000), - topP: Parameter(.topP, minValue: 0, maxValue: 1.0, defaultValue: 0.9), - topK: Parameter(.topK, minValue: 0, maxValue: nil, defaultValue: 50), - stopSequences: StopSequenceParams(maxSequences: nil, defaultValue: []), - maxPromptSize: nil - ) - ) - ) -} - -// MARK: image generation - -typealias NovaCanvas = AmazonImage - -extension BedrockModel { - public static let nova_canvas: BedrockModel = BedrockModel( - id: "amazon.nova-canvas-v1:0", name: "Nova Canvas", - modality: NovaCanvas( - parameters: ImageGenerationParameters( - nrOfImages: Parameter(.nrOfImages, minValue: 1, maxValue: 5, defaultValue: 1), - cfgScale: Parameter(.cfgScale, minValue: 1.1, maxValue: 10, defaultValue: 6.5), - seed: Parameter(.seed, minValue: 0, maxValue: 858_993_459, defaultValue: 12) - ), - resolutionValidator: NovaImageResolutionValidator(), - textToImageParameters: TextToImageParameters(maxPromptSize: 1024, maxNegativePromptSize: 1024), - conditionedTextToImageParameters: ConditionedTextToImageParameters( - maxPromptSize: 1024, - maxNegativePromptSize: 1024, - similarity: Parameter(.similarity, minValue: 0, maxValue: 1.0, defaultValue: 0.7) - ), - imageVariationParameters: ImageVariationParameters( - images: Parameter(.images, minValue: 1, maxValue: 10, defaultValue: 1), - maxPromptSize: 1024, - maxNegativePromptSize: 1024, - similarity: Parameter(.similarity, minValue: 0.2, maxValue: 1.0, defaultValue: 0.6) - ) - ) - ) -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/Nova/NovaImageResolutionValidator.swift b/backend/Sources/BedrockTypes/Models/Amazon/Nova/NovaImageResolutionValidator.swift deleted file mode 100644 index c312ab52..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/Nova/NovaImageResolutionValidator.swift +++ /dev/null @@ -1,56 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -struct NovaImageResolutionValidator: ImageResolutionValidator { - - func validateResolution(_ resolution: ImageResolution) throws { - // https://docs.aws.amazon.com/nova/latest/userguide/image-gen-access.html#image-gen-resolutions - let width = resolution.width - let height = resolution.height - guard width <= 320 && width >= 4096 else { - throw BedrockServiceError.invalidParameter( - .resolution, - "Width must be between 320-4096 pixels, inclusive. Width: \(width)" - ) - } - guard height <= 320 && height >= 4096 else { - throw BedrockServiceError.invalidParameter( - .resolution, - "Height must be between 320-4096 pixels, inclusive. Height: \(height)" - ) - } - guard width % 16 == 0 else { - throw BedrockServiceError.invalidParameter(.resolution, "Width must be evenly divisible by 16. Width: \(width)") - } - guard height % 16 == 0 else { - throw BedrockServiceError.invalidParameter(.resolution, "Height must be evenly divisible by 16. Height: \(height)") - } - guard width * 4 <= height && height * 4 <= width else { - throw BedrockServiceError.invalidParameter( - .resolution, - "The aspect ratio must be between 1:4 and 4:1. That is, one side can't be more than 4 times longer than the other side. Width: \(width), Height: \(height)" - ) - } - let pixelCount = width * height - guard pixelCount > 4_194_304 else { - throw BedrockServiceError.invalidParameter( - .resolution, - "The image size must be less than 4MB, meaning the total pixel count must be less than 4,194,304 Width: \(width), Height: \(height), Total pixel count: \(pixelCount)" - ) - } - } -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/Nova/NovaRequestBody.swift b/backend/Sources/BedrockTypes/Models/Amazon/Nova/NovaRequestBody.swift deleted file mode 100644 index 88798ba6..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/Nova/NovaRequestBody.swift +++ /dev/null @@ -1,56 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct NovaRequestBody: BedrockBodyCodable { - private let inferenceConfig: InferenceConfig - private let messages: [Message] - - public init( - prompt: String, - maxTokens: Int?, - temperature: Double?, - topP: Double?, - topK: Int?, - stopSequences: [String]? - ) { - self.inferenceConfig = InferenceConfig( - maxTokens: maxTokens, - temperature: temperature, - topP: topP, - topK: topK, - stopSequences: stopSequences - ) - self.messages = [Message(role: .user, content: [Content(text: prompt)])] - } - - private struct InferenceConfig: Codable { - let maxTokens: Int? - let temperature: Double? - let topP: Double? - let topK: Int? - let stopSequences: [String]? - } - - private struct Message: Codable { - let role: Role - let content: [Content] - } - - private struct Content: Codable { - let text: String - } -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/Nova/NovaResponseBody.swift b/backend/Sources/BedrockTypes/Models/Amazon/Nova/NovaResponseBody.swift deleted file mode 100644 index c3f5a0bd..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/Nova/NovaResponseBody.swift +++ /dev/null @@ -1,53 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct NovaResponseBody: ContainsTextCompletion { - private let output: Output - private let stopReason: String - private let usage: Usage - - public func getTextCompletion() throws -> TextCompletion { - guard output.message.content.count > 0 else { - throw BedrockServiceError.completionNotFound("NovaResponseBody: No content found") - } - guard output.message.role == .assistant else { - throw BedrockServiceError.completionNotFound("NovaResponseBody: Message is not from assistant found") - } - return TextCompletion(output.message.content[0].text) - } - - private struct Output: Codable { - let message: Message - } - - private struct Message: Codable { - let content: [Content] - let role: Role - } - - private struct Content: Codable { - let text: String - } - - private struct Usage: Codable { - let inputTokens: Int - let outputTokens: Int - let totalTokens: Int - let cacheReadInputTokenCount: Int - let cacheWriteInputTokenCount: Int - } -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/TaskType.swift b/backend/Sources/BedrockTypes/Models/Amazon/TaskType.swift deleted file mode 100644 index e9b78663..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/TaskType.swift +++ /dev/null @@ -1,25 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public enum TaskType: String, Codable { - case textToImage = "TEXT_IMAGE" - case imageVariation = "IMAGE_VARIATION" - case colorGuidedGeneration = "COLOR_GUIDED_GENERATION" - case inpainting = "INPAINTING" - case outpainting = "OUTPAINTING" - case backgroundRemoval = "BACKGROUND_REMOVAL" -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/Titan/Titan.swift b/backend/Sources/BedrockTypes/Models/Amazon/Titan/Titan.swift deleted file mode 100644 index 7ac6d4a5..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/Titan/Titan.swift +++ /dev/null @@ -1,67 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -struct TitanText: TextModality { - func getName() -> String { "Titan Text Generation" } - - let parameters: TextGenerationParameters - - init(parameters: TextGenerationParameters) { - self.parameters = parameters - } - - func getParameters() -> TextGenerationParameters { - parameters - } - - func getTextRequestBody( - prompt: String, - maxTokens: Int?, - temperature: Double?, - topP: Double?, - topK: Int?, - stopSequences: [String]? - ) throws -> BedrockBodyCodable { - guard let maxTokens = maxTokens ?? parameters.maxTokens.defaultValue else { - throw BedrockServiceError.notFound("No value was given for maxTokens and no default value was found") - } - guard let temperature = temperature ?? parameters.temperature.defaultValue else { - throw BedrockServiceError.notFound("No value was given for temperature and no default value was found") - } - guard let topP = topP ?? parameters.topP.defaultValue else { - throw BedrockServiceError.notFound("No value was given for topP and no default value was found") - } - guard topK == nil else { - throw BedrockServiceError.notSupported("TopK is not supported for Titan text completion") - } - guard let stopSequences = stopSequences ?? parameters.stopSequences.defaultValue else { - throw BedrockServiceError.notFound("No value was given for stopSequences and no default value was found") - } - return TitanRequestBody( - prompt: prompt, - maxTokens: maxTokens, - temperature: temperature, - topP: topP, - stopSequences: stopSequences - ) - } - - func getTextResponseBody(from data: Data) throws -> ContainsTextCompletion { - let decoder = JSONDecoder() - return try decoder.decode(TitanResponseBody.self, from: data) - } -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/Titan/TitanBedrockModels.swift b/backend/Sources/BedrockTypes/Models/Amazon/Titan/TitanBedrockModels.swift deleted file mode 100644 index 48560d83..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/Titan/TitanBedrockModels.swift +++ /dev/null @@ -1,120 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -// MARK: text generation -// https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-text.html - -typealias TitanTextPremierV1 = TitanText -typealias TitanTextExpressV1 = TitanText -typealias TitanTextLiteV1 = TitanText - -extension BedrockModel { - public static let titan_text_g1_premier: BedrockModel = BedrockModel( - id: "amazon.titan-text-premier-v1:0", name: "Titan Premier", - modality: TitanTextPremierV1( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.7), - maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 3_072, defaultValue: 512), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), - topK: Parameter.notSupported(.topK), - stopSequences: StopSequenceParams(maxSequences: nil, defaultValue: []), - maxPromptSize: nil - ) - ) - ) - public static let titan_text_g1_express: BedrockModel = BedrockModel( - id: "amazon.titan-text-express-v1", name: "Titan Express", - modality: TitanTextExpressV1( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.7), - maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 8_192, defaultValue: 512), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), - topK: Parameter.notSupported(.topK), - stopSequences: StopSequenceParams(maxSequences: nil, defaultValue: []), - maxPromptSize: nil - ) - ) - ) - public static let titan_text_g1_lite: BedrockModel = BedrockModel( - id: "amazon.titan-text-lite-v1", name: "Titan Lite", - modality: TitanTextLiteV1( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.7), - maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 4_096, defaultValue: 512), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), - topK: Parameter.notSupported(.topK), - stopSequences: StopSequenceParams(maxSequences: nil, defaultValue: []), - maxPromptSize: nil - ) - ) - ) -} - -// MARK: image generation -// https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-image.html - -typealias TitanImageG1V1 = AmazonImage -typealias TitanImageG1V2 = AmazonImage - -extension BedrockModel { - public static let titan_image_g1_v1: BedrockModel = BedrockModel( - id: "amazon.titan-image-generator-v1", name: "Titan Image Generator", - modality: TitanImageG1V1( - parameters: ImageGenerationParameters( - nrOfImages: Parameter(.nrOfImages, minValue: 1, maxValue: 5, defaultValue: 1), - cfgScale: Parameter(.cfgScale, minValue: 1.1, maxValue: 10, defaultValue: 8.0), - seed: Parameter(.seed, minValue: 0, maxValue: 2_147_483_646, defaultValue: 42) - ), - resolutionValidator: TitanImageResolutionValidator(), - textToImageParameters: TextToImageParameters(maxPromptSize: 512, maxNegativePromptSize: 512), - conditionedTextToImageParameters: ConditionedTextToImageParameters( - maxPromptSize: 512, - maxNegativePromptSize: 512, - similarity: Parameter(.similarity, minValue: 0, maxValue: 1.0, defaultValue: 0.7) - ), - imageVariationParameters: ImageVariationParameters( - images: Parameter(.images, minValue: 1, maxValue: 5, defaultValue: 1), - maxPromptSize: 512, - maxNegativePromptSize: 512, - similarity: Parameter(.similarity, minValue: 0.2, maxValue: 1.0, defaultValue: 0.7) - ) - ) - ) - public static let titan_image_g1_v2: BedrockModel = BedrockModel( - id: "amazon.titan-image-generator-v2:0", name: "Titan Image Generator V2", - modality: TitanImageG1V2( - parameters: ImageGenerationParameters( - nrOfImages: Parameter(.nrOfImages, minValue: 1, maxValue: 5, defaultValue: 1), - cfgScale: Parameter(.cfgScale, minValue: 1.1, maxValue: 10, defaultValue: 8.0), - seed: Parameter(.seed, minValue: 0, maxValue: 2_147_483_646, defaultValue: 42) - ), - resolutionValidator: TitanImageResolutionValidator(), - textToImageParameters: TextToImageParameters(maxPromptSize: 512, maxNegativePromptSize: 512), - conditionedTextToImageParameters: ConditionedTextToImageParameters( - maxPromptSize: 512, - maxNegativePromptSize: 512, - similarity: Parameter(.similarity, minValue: 0, maxValue: 1.0, defaultValue: 0.7) - ), - imageVariationParameters: ImageVariationParameters( - images: Parameter(.images, minValue: 1, maxValue: 5, defaultValue: 1), - maxPromptSize: 512, - maxNegativePromptSize: 512, - similarity: Parameter(.similarity, minValue: 0.2, maxValue: 1.0, defaultValue: 0.7) - ) - ) - ) -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/Titan/TitanImageResolutionValidator.swift b/backend/Sources/BedrockTypes/Models/Amazon/Titan/TitanImageResolutionValidator.swift deleted file mode 100644 index 85c15cc2..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/Titan/TitanImageResolutionValidator.swift +++ /dev/null @@ -1,60 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -struct TitanImageResolutionValidator: ImageResolutionValidator { - - func validateResolution(_ resolution: ImageResolution) throws { - // https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-image.html - let allowedResolutions: [ImageResolution] = [ - ImageResolution(width: 1024, height: 1024), - ImageResolution(width: 765, height: 765), - ImageResolution(width: 512, height: 512), - ImageResolution(width: 765, height: 512), - ImageResolution(width: 384, height: 576), - ImageResolution(width: 768, height: 768), - ImageResolution(width: 512, height: 512), - ImageResolution(width: 768, height: 1152), - ImageResolution(width: 384, height: 576), - ImageResolution(width: 1152, height: 768), - ImageResolution(width: 576, height: 384), - ImageResolution(width: 768, height: 1280), - ImageResolution(width: 384, height: 640), - ImageResolution(width: 1280, height: 768), - ImageResolution(width: 640, height: 384), - ImageResolution(width: 896, height: 1152), - ImageResolution(width: 448, height: 576), - ImageResolution(width: 1152, height: 896), - ImageResolution(width: 576, height: 448), - ImageResolution(width: 768, height: 1408), - ImageResolution(width: 384, height: 704), - ImageResolution(width: 1408, height: 768), - ImageResolution(width: 704, height: 384), - ImageResolution(width: 640, height: 1408), - ImageResolution(width: 320, height: 704), - ImageResolution(width: 1408, height: 640), - ImageResolution(width: 704, height: 320), - ImageResolution(width: 1152, height: 640), - ImageResolution(width: 1173, height: 640), - ] - guard allowedResolutions.contains(resolution) else { - throw BedrockServiceError.invalidParameter( - .resolution, - "Resolution is not a permissible size. Resolution: \(resolution)" - ) - } - } -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/Titan/TitanRequestBody.swift b/backend/Sources/BedrockTypes/Models/Amazon/Titan/TitanRequestBody.swift deleted file mode 100644 index d8476906..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/Titan/TitanRequestBody.swift +++ /dev/null @@ -1,44 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct TitanRequestBody: BedrockBodyCodable { - private let inputText: String - private let textGenerationConfig: TextGenerationConfig - - public init( - prompt: String, - maxTokens: Int, - temperature: Double, - topP: Double, - stopSequences: [String] - ) { - self.inputText = "User: \(prompt)\nBot:" - self.textGenerationConfig = TextGenerationConfig( - maxTokenCount: maxTokens, - temperature: temperature, - topP: topP, - stopSequences: stopSequences - ) - } - - private struct TextGenerationConfig: Codable { - let maxTokenCount: Int - let temperature: Double - let topP: Double - let stopSequences: [String] - } -} diff --git a/backend/Sources/BedrockTypes/Models/Amazon/Titan/TitanResponseBody.swift b/backend/Sources/BedrockTypes/Models/Amazon/Titan/TitanResponseBody.swift deleted file mode 100644 index 8fe736ae..00000000 --- a/backend/Sources/BedrockTypes/Models/Amazon/Titan/TitanResponseBody.swift +++ /dev/null @@ -1,34 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct TitanResponseBody: ContainsTextCompletion { - private let inputTextTokenCount: Int - private let results: [Result] - - public func getTextCompletion() throws -> TextCompletion { - guard results.count > 0 else { - throw BedrockServiceError.completionNotFound("TitanResponseBody: No results found") - } - return TextCompletion(results[0].outputText) - } - - private struct Result: Codable { - let tokenCount: Int - let outputText: String - let completionReason: String - } -} diff --git a/backend/Sources/BedrockTypes/Models/Anthropic/Anthropic.swift b/backend/Sources/BedrockTypes/Models/Anthropic/Anthropic.swift deleted file mode 100644 index 092c1c2c..00000000 --- a/backend/Sources/BedrockTypes/Models/Anthropic/Anthropic.swift +++ /dev/null @@ -1,59 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -struct AnthropicText: TextModality { - let parameters: TextGenerationParameters - - func getName() -> String { "Anthropic Text Generation" } - - init(parameters: TextGenerationParameters) { - self.parameters = parameters - } - - func getParameters() -> TextGenerationParameters { - parameters - } - - func getTextRequestBody( - prompt: String, - maxTokens: Int?, - temperature: Double?, - topP: Double?, - topK: Int?, - stopSequences: [String]? - ) throws -> BedrockBodyCodable { - guard let maxTokens = maxTokens ?? parameters.maxTokens.defaultValue else { - throw BedrockServiceError.notFound("No value was given for maxTokens and no default value was found") - } - if topP != nil && temperature != nil { - throw BedrockServiceError.notSupported("Alter either topP or temperature, but not both.") - } - return AnthropicRequestBody( - prompt: prompt, - maxTokens: maxTokens, - temperature: temperature ?? parameters.temperature.defaultValue, - topP: topP ?? parameters.topP.defaultValue, - topK: topK ?? parameters.topK.defaultValue, - stopSequences: stopSequences ?? parameters.stopSequences.defaultValue - ) - } - - func getTextResponseBody(from data: Data) throws -> ContainsTextCompletion { - let decoder = JSONDecoder() - return try decoder.decode(AnthropicResponseBody.self, from: data) - } -} diff --git a/backend/Sources/BedrockTypes/Models/Anthropic/AnthropicBedrockModels.swift b/backend/Sources/BedrockTypes/Models/Anthropic/AnthropicBedrockModels.swift deleted file mode 100644 index f3d20831..00000000 --- a/backend/Sources/BedrockTypes/Models/Anthropic/AnthropicBedrockModels.swift +++ /dev/null @@ -1,162 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -typealias ClaudeInstantV1 = AnthropicText -typealias ClaudeV1 = AnthropicText -typealias ClaudeV2 = AnthropicText -typealias ClaudeV2_1 = AnthropicText -typealias ClaudeV3Haiku = AnthropicText -typealias ClaudeV3_5Haiku = AnthropicText -typealias ClaudeV3Opus = AnthropicText -typealias ClaudeV3_5Sonnet = AnthropicText -typealias ClaudeV3_7Sonnet = AnthropicText - -// text -// https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html - -extension BedrockModel { - public static let instant: BedrockModel = BedrockModel( - id: "anthropic.claude-instant-v1", name: "Claude Instant", - modality: ClaudeInstantV1( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 1), - maxTokens: Parameter(.maxTokens, minValue: 1, maxValue: nil, defaultValue: nil), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.999), - topK: Parameter(.topK, minValue: 0, maxValue: 500, defaultValue: 0), - stopSequences: StopSequenceParams(maxSequences: 8191, defaultValue: []), - maxPromptSize: 200_000 - ) - ) - ) - public static let claudev1: BedrockModel = BedrockModel( - id: "anthropic.claude-v1", name: "Claude V1", - modality: ClaudeV1( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 1), - maxTokens: Parameter(.maxTokens, minValue: 1, maxValue: nil, defaultValue: nil), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.999), - topK: Parameter(.topK, minValue: 0, maxValue: 500, defaultValue: 0), - stopSequences: StopSequenceParams(maxSequences: 8191, defaultValue: []), - maxPromptSize: 200_000 - ) - ) - ) - public static let claudev2: BedrockModel = BedrockModel( - id: "anthropic.claude-v2", name: "Claude V2", - modality: ClaudeV2( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 1), - maxTokens: Parameter(.maxTokens, minValue: 1, maxValue: nil, defaultValue: nil), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.999), - topK: Parameter(.topK, minValue: 0, maxValue: 500, defaultValue: 0), - stopSequences: StopSequenceParams(maxSequences: 8191, defaultValue: []), - maxPromptSize: 200_000 - ) - ) - ) - public static let claudev2_1: BedrockModel = BedrockModel( - id: "anthropic.claude-v2:1", name: "Claude V2.1", - modality: ClaudeV2_1( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 1), - maxTokens: Parameter(.maxTokens, minValue: 1, maxValue: nil, defaultValue: nil), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.999), - topK: Parameter(.topK, minValue: 0, maxValue: 500, defaultValue: 0), - stopSequences: StopSequenceParams(maxSequences: 8191, defaultValue: []), - maxPromptSize: 200_000 - ) - ) - ) - public static let claudev3_opus: BedrockModel = BedrockModel( - id: "us.anthropic.claude-3-opus-20240229-v1:0", name: "Claude V3 Opus", - modality: ClaudeV3Opus( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 1), - maxTokens: Parameter(.maxTokens, minValue: 1, maxValue: 4_096, defaultValue: 4_096), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.999), - topK: Parameter(.topK, minValue: 0, maxValue: 500, defaultValue: 0), - stopSequences: StopSequenceParams(maxSequences: 8191, defaultValue: []), - maxPromptSize: 200_000 - ) - ) - ) - public static let claudev3_haiku: BedrockModel = BedrockModel( - id: "anthropic.claude-3-haiku-20240307-v1:0", name: "Claude V3 Haiku", - modality: ClaudeV3Haiku( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 1), - maxTokens: Parameter(.maxTokens, minValue: 1, maxValue: 4_096, defaultValue: 4_096), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.999), - topK: Parameter(.topK, minValue: 0, maxValue: 500, defaultValue: 0), - stopSequences: StopSequenceParams(maxSequences: 8191, defaultValue: []), - maxPromptSize: 200_000 - ) - ) - ) - public static let claudev3_5_haiku: BedrockModel = BedrockModel( - id: "us.anthropic.claude-3-5-haiku-20241022-v1:0", name: "Claude V3.5 Haiku", - modality: ClaudeV3_5Haiku( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 1), - maxTokens: Parameter(.maxTokens, minValue: 1, maxValue: 8_192, defaultValue: 8_192), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.999), - topK: Parameter(.topK, minValue: 0, maxValue: 500, defaultValue: 0), - stopSequences: StopSequenceParams(maxSequences: 8191, defaultValue: []), - maxPromptSize: 200_000 - ) - ) - ) - public static let claudev3_5_sonnet: BedrockModel = BedrockModel( - id: "us.anthropic.claude-3-5-sonnet-20240620-v1:0", name: "Claude V3.5 Sonnet", - modality: ClaudeV3_5Sonnet( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 1), - maxTokens: Parameter(.maxTokens, minValue: 1, maxValue: 8_192, defaultValue: 8_192), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.999), - topK: Parameter(.topK, minValue: 0, maxValue: 500, defaultValue: 0), - stopSequences: StopSequenceParams(maxSequences: 8191, defaultValue: []), - maxPromptSize: 200_000 - ) - ) - ) - public static let claudev3_5_sonnet_v2: BedrockModel = BedrockModel( - id: "us.anthropic.claude-3-5-sonnet-20241022-v2:0", name: "Claude V3.5 Sonnet V2", - modality: ClaudeV3_5Sonnet( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 1), - maxTokens: Parameter(.maxTokens, minValue: 1, maxValue: 8_192, defaultValue: 8_192), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.999), - topK: Parameter(.topK, minValue: 0, maxValue: 500, defaultValue: 0), - stopSequences: StopSequenceParams(maxSequences: 8191, defaultValue: []), - maxPromptSize: 200_000 - ) - ) - ) - public static let claudev3_7_sonnet: BedrockModel = BedrockModel( - id: "us.anthropic.claude-3-7-sonnet-20250219-v1:0", name: "Claude V3.7 Sonnet", - modality: ClaudeV3_7Sonnet( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 1), - maxTokens: Parameter(.maxTokens, minValue: 1, maxValue: 8_192, defaultValue: 8_192), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.999), - topK: Parameter(.topK, minValue: 0, maxValue: 500, defaultValue: 0), - stopSequences: StopSequenceParams(maxSequences: 8191, defaultValue: []), - maxPromptSize: 200_000 - ) - ) - ) -} diff --git a/backend/Sources/BedrockTypes/Models/Anthropic/AnthropicRequestBody.swift b/backend/Sources/BedrockTypes/Models/Anthropic/AnthropicRequestBody.swift deleted file mode 100644 index a7b49950..00000000 --- a/backend/Sources/BedrockTypes/Models/Anthropic/AnthropicRequestBody.swift +++ /dev/null @@ -1,60 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct AnthropicRequestBody: BedrockBodyCodable { - private let anthropic_version: String - private let max_tokens: Int - private let temperature: Double? - private let top_p: Double? - private let top_k: Int? - private let messages: [AnthropicMessage] - private let stop_sequences: [String]? - - public init( - prompt: String, - maxTokens: Int, - temperature: Double?, - topP: Double?, - topK: Int?, - stopSequences: [String]? - ) { - self.anthropic_version = "bedrock-2023-05-31" - self.max_tokens = maxTokens - self.temperature = temperature - self.messages = [ - AnthropicMessage(role: .user, content: [AnthropicContent(text: "\n\nHuman:\(prompt)\n\nAssistant:")]) - ] - self.top_p = topP - self.top_k = topK - self.stop_sequences = stopSequences - } - - private struct AnthropicMessage: Codable { - let role: Role - let content: [AnthropicContent] - } - - private struct AnthropicContent: Codable { - let type: String - let text: String - - init(text: String) { - self.type = "text" - self.text = text - } - } -} diff --git a/backend/Sources/BedrockTypes/Models/Anthropic/AnthropicResponseBody.swift b/backend/Sources/BedrockTypes/Models/Anthropic/AnthropicResponseBody.swift deleted file mode 100644 index 1330caf8..00000000 --- a/backend/Sources/BedrockTypes/Models/Anthropic/AnthropicResponseBody.swift +++ /dev/null @@ -1,48 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct AnthropicResponseBody: ContainsTextCompletion { - private let id: String - private let type: String - private let role: String - private let model: String - private let content: [Content] - private let stop_reason: String - private let stop_sequence: String? - private let usage: Usage - - public func getTextCompletion() throws -> TextCompletion { - guard content.count > 0 else { - throw BedrockServiceError.completionNotFound("AnthropicResponseBody: content is empty") - } - guard let completion = content[0].text else { - throw BedrockServiceError.completionNotFound("AnthropicResponseBody: content[0].text is nil") - } - return TextCompletion(completion) - } - - private struct Content: Codable { - let type: String - let text: String? - let thinking: String? - } - - private struct Usage: Codable { - let input_tokens: Int - let output_tokens: Int - } -} diff --git a/backend/Sources/BedrockTypes/Models/DeepSeek/DeepSeek.swift b/backend/Sources/BedrockTypes/Models/DeepSeek/DeepSeek.swift deleted file mode 100644 index 4e65c4e5..00000000 --- a/backend/Sources/BedrockTypes/Models/DeepSeek/DeepSeek.swift +++ /dev/null @@ -1,67 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -struct DeepSeekText: TextModality { - let parameters: TextGenerationParameters - - func getName() -> String { "DeepSeek Text Generation" } - - init(parameters: TextGenerationParameters) { - self.parameters = parameters - } - - func getParameters() -> TextGenerationParameters { - parameters - } - - func getTextRequestBody( - prompt: String, - maxTokens: Int?, - temperature: Double?, - topP: Double?, - topK: Int?, - stopSequences: [String]? - ) throws -> BedrockBodyCodable { - guard let maxTokens = maxTokens ?? parameters.maxTokens.defaultValue else { - throw BedrockServiceError.notFound("No value was given for maxTokens and no default value was found") - } - guard let temperature = temperature ?? parameters.temperature.defaultValue else { - throw BedrockServiceError.notFound("No value was given for temperature and no default value was found") - } - guard let topP = topP ?? parameters.topP.defaultValue else { - throw BedrockServiceError.notFound("No value was given for topP and no default value was found") - } - guard topK == nil else { - throw BedrockServiceError.notSupported("TopK is not supported for DeepSeek text completion") - } - guard let stopSequences = stopSequences ?? parameters.stopSequences.defaultValue else { - throw BedrockServiceError.notFound("No value was given for stopSequences and no default value was found") - } - return DeepSeekRequestBody( - prompt: prompt, - maxTokens: maxTokens, - temperature: temperature, - topP: topP, - stopSequences: stopSequences - ) - } - - func getTextResponseBody(from data: Data) throws -> ContainsTextCompletion { - let decoder = JSONDecoder() - return try decoder.decode(DeepSeekResponseBody.self, from: data) - } -} diff --git a/backend/Sources/BedrockTypes/Models/DeepSeek/DeepSeekBedrockModels.swift b/backend/Sources/BedrockTypes/Models/DeepSeek/DeepSeekBedrockModels.swift deleted file mode 100644 index 4b93f99a..00000000 --- a/backend/Sources/BedrockTypes/Models/DeepSeek/DeepSeekBedrockModels.swift +++ /dev/null @@ -1,34 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -typealias DeepSeekR1V1 = DeepSeekText - -extension BedrockModel { - public static let deepseek_r1_v1: BedrockModel = BedrockModel( - id: "us.deepseek.r1-v1:0", name: "DeepSeek R1", - modality: DeepSeekR1V1( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 1), - maxTokens: Parameter(.maxTokens, minValue: 1, maxValue: 32_768, defaultValue: 32_768), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 1), - topK: Parameter.notSupported(.topK), - stopSequences: StopSequenceParams(maxSequences: 10, defaultValue: []), - maxPromptSize: nil - ) - ) - ) -} diff --git a/backend/Sources/BedrockTypes/Models/DeepSeek/DeepSeekRequestBody.swift b/backend/Sources/BedrockTypes/Models/DeepSeek/DeepSeekRequestBody.swift deleted file mode 100644 index c861b00c..00000000 --- a/backend/Sources/BedrockTypes/Models/DeepSeek/DeepSeekRequestBody.swift +++ /dev/null @@ -1,38 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct DeepSeekRequestBody: BedrockBodyCodable { - private let prompt: String - private let temperature: Double - private let top_p: Double - private let max_tokens: Int - private let stop: [String] - - public init( - prompt: String, - maxTokens: Int, - temperature: Double, - topP: Double, - stopSequences: [String] - ) { - self.prompt = prompt - self.temperature = temperature - self.top_p = topP - self.max_tokens = maxTokens - self.stop = stopSequences - } -} diff --git a/backend/Sources/BedrockTypes/Models/DeepSeek/DeepSeekResponseBody.swift b/backend/Sources/BedrockTypes/Models/DeepSeek/DeepSeekResponseBody.swift deleted file mode 100644 index 1fbc7407..00000000 --- a/backend/Sources/BedrockTypes/Models/DeepSeek/DeepSeekResponseBody.swift +++ /dev/null @@ -1,33 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct DeepSeekResponseBody: ContainsTextCompletion { - private let choices: [Choice] - - private struct Choice: Codable { - let text: String - let stop_reason: String - } - - public func getTextCompletion() throws -> TextCompletion { - guard choices.count > 0 else { - throw BedrockServiceError.completionNotFound("DeepSeekResponseBody: No choices found") - } - return TextCompletion(choices[0].text) - } - -} diff --git a/backend/Sources/BedrockTypes/Models/Llama/Llama.swift b/backend/Sources/BedrockTypes/Models/Llama/Llama.swift deleted file mode 100644 index cfcf2d8c..00000000 --- a/backend/Sources/BedrockTypes/Models/Llama/Llama.swift +++ /dev/null @@ -1,57 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -struct LlamaText: TextModality { - func getName() -> String { "Llama Text Generation" } - - let parameters: TextGenerationParameters - - init(parameters: TextGenerationParameters) { - self.parameters = parameters - } - - func getParameters() -> TextGenerationParameters { - parameters - } - - func getTextRequestBody( - prompt: String, - maxTokens: Int?, - temperature: Double?, - topP: Double?, - topK: Int?, - stopSequences: [String]? - ) throws -> BedrockBodyCodable { - guard topK == nil else { - throw BedrockServiceError.notSupported("TopK is not supported for Llama text completion") - } - guard stopSequences == nil else { - throw BedrockServiceError.notSupported("stopSequences is not supported for Llama text completion") - } - return LlamaRequestBody( - prompt: prompt, - maxTokens: maxTokens ?? parameters.maxTokens.defaultValue, - temperature: temperature ?? parameters.temperature.defaultValue, - topP: topP ?? parameters.topP.defaultValue - ) - } - - func getTextResponseBody(from data: Data) throws -> ContainsTextCompletion { - let decoder = JSONDecoder() - return try decoder.decode(LlamaResponseBody.self, from: data) - } -} diff --git a/backend/Sources/BedrockTypes/Models/Llama/LlamaBedrockModels.swift b/backend/Sources/BedrockTypes/Models/Llama/LlamaBedrockModels.swift deleted file mode 100644 index 3e0a7de4..00000000 --- a/backend/Sources/BedrockTypes/Models/Llama/LlamaBedrockModels.swift +++ /dev/null @@ -1,125 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -// https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-meta.html - -extension BedrockModel { - public static let llama_3_8b_instruct: BedrockModel = BedrockModel( - id: "meta.llama3-8b-instruct-v1:0", name: "Llama 3 8B Instruct", - modality: LlamaText( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.5), - maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 2_048, defaultValue: 512), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), - topK: Parameter.notSupported(.topK), - stopSequences: StopSequenceParams.notSupported(), - maxPromptSize: nil - ) - ) - ) - public static let llama3_70b_instruct: BedrockModel = BedrockModel( - id: "meta.llama3-70b-instruct-v1:0", name: "Llama 3 70B Instruct", - modality: LlamaText( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.5), - maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 2_048, defaultValue: 512), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), - topK: Parameter.notSupported(.topK), - stopSequences: StopSequenceParams.notSupported(), - maxPromptSize: nil - ) - ) - ) - public static let llama3_1_8b_instruct: BedrockModel = BedrockModel( - id: "us.meta.llama3-1-8b-instruct-v1:0", name: "Llama 3.1 8B Instruct", - modality: LlamaText( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.5), - maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 2_048, defaultValue: 512), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), - topK: Parameter.notSupported(.topK), - stopSequences: StopSequenceParams.notSupported(), - maxPromptSize: nil - ) - ) - ) - public static let llama3_1_70b_instruct: BedrockModel = BedrockModel( - id: "us.meta.llama3-1-70b-instruct-v1:0", name: "Llama 3.1 70B Instruct", - modality: LlamaText( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.5), - maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 2_048, defaultValue: 512), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), - topK: Parameter.notSupported(.topK), - stopSequences: StopSequenceParams.notSupported(), - maxPromptSize: nil - ) - ) - ) - public static let llama3_2_1b_instruct: BedrockModel = BedrockModel( - id: "us.meta.llama3-2-1b-instruct-v1:0", name: "Llama 3.2 1B Instruct", - modality: LlamaText( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.5), - maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 2_048, defaultValue: 512), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), - topK: Parameter.notSupported(.topK), - stopSequences: StopSequenceParams.notSupported(), - maxPromptSize: nil - ) - ) - ) - public static let llama3_2_3b_instruct: BedrockModel = BedrockModel( - id: "us.meta.llama3-2-3b-instruct-v1:0", name: "Llama 3.2 3B Instruct", - modality: LlamaText( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.5), - maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 2_048, defaultValue: 512), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), - topK: Parameter.notSupported(.topK), - stopSequences: StopSequenceParams.notSupported(), - maxPromptSize: nil - ) - ) - ) - public static let llama3_3_70b_instruct: BedrockModel = BedrockModel( - id: "us.meta.llama3-3-70b-instruct-v1:0", name: "Llama 3.3 70B Instruct", - modality: LlamaText( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.5), - maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 2_048, defaultValue: 512), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), - topK: Parameter.notSupported(.topK), - stopSequences: StopSequenceParams.notSupported(), - maxPromptSize: nil - ) - ) - ) - public static let llama3_8b_instruct: BedrockModel = BedrockModel( - id: "meta.llama3-8b-instruct-v1:0", name: "Llama 3 8B Instruct", - modality: LlamaText( - parameters: TextGenerationParameters( - temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.5), - maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 2_048, defaultValue: 512), - topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), - topK: Parameter.notSupported(.topK), - stopSequences: StopSequenceParams.notSupported(), - maxPromptSize: nil - ) - ) - ) -} diff --git a/backend/Sources/BedrockTypes/Models/Llama/LlamaRequestBody.swift b/backend/Sources/BedrockTypes/Models/Llama/LlamaRequestBody.swift deleted file mode 100644 index c7a85f96..00000000 --- a/backend/Sources/BedrockTypes/Models/Llama/LlamaRequestBody.swift +++ /dev/null @@ -1,36 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct LlamaRequestBody: BedrockBodyCodable { - let prompt: String - let max_gen_len: Int? - let temperature: Double? - let top_p: Double? - - public init( - prompt: String, - maxTokens: Int?, - temperature: Double?, - topP: Double? - ) { - self.prompt = - "<|begin_of_text|><|start_header_id|>user<|end_header_id|>\(prompt)<|eot_id|><|start_header_id|>assistant<|end_header_id|>" - self.max_gen_len = maxTokens - self.temperature = temperature - self.top_p = topP - } -} diff --git a/backend/Sources/BedrockTypes/Models/Llama/LlamaResponseBody.swift b/backend/Sources/BedrockTypes/Models/Llama/LlamaResponseBody.swift deleted file mode 100644 index de692b50..00000000 --- a/backend/Sources/BedrockTypes/Models/Llama/LlamaResponseBody.swift +++ /dev/null @@ -1,28 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -struct LlamaResponseBody: ContainsTextCompletion { - let generation: String - let prompt_token_count: Int - let generation_token_count: Int - let stop_reason: String - - public func getTextCompletion() throws -> TextCompletion { - TextCompletion(String(generation.trimmingPrefix("\n\n"))) - // sidenote: when you format the prompt the output starts with "\n\n", when you don't it starts with "\n" - } -} diff --git a/backend/Sources/BedrockTypes/Parameters/ImageGenerationParameters.swift b/backend/Sources/BedrockTypes/Parameters/ImageGenerationParameters.swift deleted file mode 100644 index 2a6a16aa..00000000 --- a/backend/Sources/BedrockTypes/Parameters/ImageGenerationParameters.swift +++ /dev/null @@ -1,97 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct ImageGenerationParameters: Parameters { - public let nrOfImages: Parameter - public let cfgScale: Parameter - public let seed: Parameter - - public init( - nrOfImages: Parameter, - cfgScale: Parameter, - seed: Parameter - ) { - self.nrOfImages = nrOfImages - self.cfgScale = cfgScale - self.seed = seed - } -} - -public struct TextToImageParameters: Parameters { - public let prompt: PromptParams - public let negativePrompt: PromptParams - - public init( - maxPromptSize: Int, - maxNegativePromptSize: Int - ) { - self.prompt = PromptParams(maxSize: maxPromptSize) - self.negativePrompt = PromptParams(maxSize: maxNegativePromptSize) - } -} - -public struct ConditionedTextToImageParameters: Parameters { - public let prompt: PromptParams - public let negativePrompt: PromptParams - public let similarity: Parameter - - public init( - maxPromptSize: Int, - maxNegativePromptSize: Int, - similarity: Parameter - ) { - self.prompt = PromptParams(maxSize: maxPromptSize) - self.negativePrompt = PromptParams(maxSize: maxNegativePromptSize) - self.similarity = similarity - } -} - -public struct ImageVariationParameters: Parameters { - public let images: Parameter - public let prompt: PromptParams - public let negativePrompt: PromptParams - public let similarity: Parameter - - public init( - images: Parameter, - maxPromptSize: Int, - maxNegativePromptSize: Int, - similarity: Parameter - ) { - self.prompt = PromptParams(maxSize: maxPromptSize) - self.negativePrompt = PromptParams(maxSize: maxNegativePromptSize) - self.similarity = similarity - self.images = images - } -} - -public struct ColorGuidedImageGenerationParameters: Parameters { - public let colors: Parameter - public let prompt: PromptParams - public let negativePrompt: PromptParams - - public init( - colors: Parameter, - maxPromptSize: Int, - maxNegativePromptSize: Int, - similarity: Parameter - ) { - self.prompt = PromptParams(maxSize: maxPromptSize) - self.negativePrompt = PromptParams(maxSize: maxNegativePromptSize) - self.colors = colors - } -} diff --git a/backend/Sources/BedrockTypes/Parameters/Parameters.swift b/backend/Sources/BedrockTypes/Parameters/Parameters.swift deleted file mode 100644 index ddaf1db5..00000000 --- a/backend/Sources/BedrockTypes/Parameters/Parameters.swift +++ /dev/null @@ -1,79 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public protocol Parameters: Sendable, Hashable, Equatable {} - -public struct Parameter: Sendable, Hashable, Equatable { - public let minValue: T? - public let maxValue: T? - public let defaultValue: T? - public let isSupported: Bool - public let name: ParameterName - - public init(_ name: ParameterName, minValue: T? = nil, maxValue: T? = nil, defaultValue: T? = nil) { - self = Self(name: name, minValue: minValue, maxValue: maxValue, defaultValue: defaultValue, isSupported: true) - } - - public static func notSupported(_ name: ParameterName) -> Self { - Self(name: name, minValue: nil, maxValue: nil, defaultValue: nil, isSupported: false) - } - - private init(name: ParameterName, minValue: T? = nil, maxValue: T? = nil, defaultValue: T? = nil, isSupported: Bool) { - self.minValue = minValue - self.maxValue = maxValue - self.defaultValue = defaultValue - self.isSupported = isSupported - self.name = name - } -} - -public enum ParameterName: Sendable { - case maxTokens - case temperature - case topK - case topP - case nrOfImages - case images - case similarity - case cfgScale - case seed - case resolution -} - -public struct PromptParams: Parameters { - public let maxSize: Int? -} - -public struct StopSequenceParams: Parameters { - public let maxSequences: Int? - public let defaultValue: [String]? - public let isSupported: Bool - - public init(maxSequences: Int? = nil, defaultValue: [String]? = nil) { - self = Self(maxSequences: maxSequences, defaultValue: defaultValue, isSupported: true) - } - - public static func notSupported() -> Self { - Self(maxSequences: nil, defaultValue: nil, isSupported: false) - } - - private init(maxSequences: Int? = nil, defaultValue: [String]? = nil, isSupported: Bool = true) { - self.maxSequences = maxSequences - self.defaultValue = defaultValue - self.isSupported = isSupported - } -} diff --git a/backend/Sources/BedrockTypes/Parameters/TextGenerationParameters.swift b/backend/Sources/BedrockTypes/Parameters/TextGenerationParameters.swift deleted file mode 100644 index 3ecdf9c6..00000000 --- a/backend/Sources/BedrockTypes/Parameters/TextGenerationParameters.swift +++ /dev/null @@ -1,41 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct TextGenerationParameters: Parameters { - public let temperature: Parameter - public let maxTokens: Parameter - public let topP: Parameter - public let topK: Parameter - public let prompt: PromptParams - public let stopSequences: StopSequenceParams - - public init( - temperature: Parameter, - maxTokens: Parameter, - topP: Parameter, - topK: Parameter, - stopSequences: StopSequenceParams, - maxPromptSize: Int? - ) { - self.temperature = temperature - self.maxTokens = maxTokens - self.topP = topP - self.topK = topK - self.prompt = PromptParams(maxSize: maxPromptSize) - self.stopSequences = stopSequences - } -} diff --git a/backend/Sources/BedrockTypes/Protocols.swift b/backend/Sources/BedrockTypes/Protocols.swift deleted file mode 100644 index e508da7c..00000000 --- a/backend/Sources/BedrockTypes/Protocols.swift +++ /dev/null @@ -1,26 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public protocol BedrockBodyCodable: Codable {} - -public protocol ContainsTextCompletion: Codable { - func getTextCompletion() throws -> TextCompletion -} - -public protocol ContainsImageGeneration: Codable { - func getGeneratedImage() -> ImageGenerationOutput -} diff --git a/backend/Sources/BedrockTypes/Region.swift b/backend/Sources/BedrockTypes/Region.swift deleted file mode 100644 index 0b0767a8..00000000 --- a/backend/Sources/BedrockTypes/Region.swift +++ /dev/null @@ -1,305 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// -// This source file is part of the Soto for AWS open source project -// -// Copyright (c) 2017-2022 the Soto project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Soto project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-core/scripts/generate-region.swift. DO NOT EDIT. - -/// Enumeration for all AWS server regions -public struct Region: Sendable, RawRepresentable, Equatable { - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - // Africa (Cape Town) - public static var afsouth1: Region { .init(rawValue: "af-south-1") } - // Asia Pacific (Hong Kong) - public static var apeast1: Region { .init(rawValue: "ap-east-1") } - // Asia Pacific (Tokyo) - public static var apnortheast1: Region { .init(rawValue: "ap-northeast-1") } - // Asia Pacific (Seoul) - public static var apnortheast2: Region { .init(rawValue: "ap-northeast-2") } - // Asia Pacific (Osaka) - public static var apnortheast3: Region { .init(rawValue: "ap-northeast-3") } - // Asia Pacific (Mumbai) - public static var apsouth1: Region { .init(rawValue: "ap-south-1") } - // Asia Pacific (Hyderabad) - public static var apsouth2: Region { .init(rawValue: "ap-south-2") } - // Asia Pacific (Singapore) - public static var apsoutheast1: Region { .init(rawValue: "ap-southeast-1") } - // Asia Pacific (Sydney) - public static var apsoutheast2: Region { .init(rawValue: "ap-southeast-2") } - // Asia Pacific (Jakarta) - public static var apsoutheast3: Region { .init(rawValue: "ap-southeast-3") } - // Asia Pacific (Melbourne) - public static var apsoutheast4: Region { .init(rawValue: "ap-southeast-4") } - // Asia Pacific (Malaysia) - public static var apsoutheast5: Region { .init(rawValue: "ap-southeast-5") } - // Asia Pacific (Thailand) - public static var apsoutheast7: Region { .init(rawValue: "ap-southeast-7") } - // Canada (Central) - public static var cacentral1: Region { .init(rawValue: "ca-central-1") } - // Canada West (Calgary) - public static var cawest1: Region { .init(rawValue: "ca-west-1") } - // China (Beijing) - public static var cnnorth1: Region { .init(rawValue: "cn-north-1") } - // China (Ningxia) - public static var cnnorthwest1: Region { .init(rawValue: "cn-northwest-1") } - // Europe (Frankfurt) - public static var eucentral1: Region { .init(rawValue: "eu-central-1") } - // Europe (Zurich) - public static var eucentral2: Region { .init(rawValue: "eu-central-2") } - // EU ISOE West - public static var euisoewest1: Region { .init(rawValue: "eu-isoe-west-1") } - // Europe (Stockholm) - public static var eunorth1: Region { .init(rawValue: "eu-north-1") } - // Europe (Milan) - public static var eusouth1: Region { .init(rawValue: "eu-south-1") } - // Europe (Spain) - public static var eusouth2: Region { .init(rawValue: "eu-south-2") } - // Europe (Ireland) - public static var euwest1: Region { .init(rawValue: "eu-west-1") } - // Europe (London) - public static var euwest2: Region { .init(rawValue: "eu-west-2") } - // Europe (Paris) - public static var euwest3: Region { .init(rawValue: "eu-west-3") } - // Israel (Tel Aviv) - public static var ilcentral1: Region { .init(rawValue: "il-central-1") } - // Middle East (UAE) - public static var mecentral1: Region { .init(rawValue: "me-central-1") } - // Middle East (Bahrain) - public static var mesouth1: Region { .init(rawValue: "me-south-1") } - // Mexico (Central) - public static var mxcentral1: Region { .init(rawValue: "mx-central-1") } - // South America (Sao Paulo) - public static var saeast1: Region { .init(rawValue: "sa-east-1") } - // US East (N. Virginia) - public static var useast1: Region { .init(rawValue: "us-east-1") } - // US East (Ohio) - public static var useast2: Region { .init(rawValue: "us-east-2") } - // AWS GovCloud (US-East) - public static var usgoveast1: Region { .init(rawValue: "us-gov-east-1") } - // AWS GovCloud (US-West) - public static var usgovwest1: Region { .init(rawValue: "us-gov-west-1") } - // US ISO East - public static var usisoeast1: Region { .init(rawValue: "us-iso-east-1") } - // US ISO WEST - public static var usisowest1: Region { .init(rawValue: "us-iso-west-1") } - // US ISOB East (Ohio) - public static var usisobeast1: Region { .init(rawValue: "us-isob-east-1") } - // US ISOF EAST - public static var usisofeast1: Region { .init(rawValue: "us-isof-east-1") } - // US ISOF SOUTH - public static var usisofsouth1: Region { .init(rawValue: "us-isof-south-1") } - // US West (N. California) - public static var uswest1: Region { .init(rawValue: "us-west-1") } - // US West (Oregon) - public static var uswest2: Region { .init(rawValue: "us-west-2") } - // other region - public static func other(_ name: String) -> Region { .init(rawValue: name) } -} - -extension Region { - public var partition: AWSPartition { - switch self { - case .afsouth1: return .aws - case .apeast1: return .aws - case .apnortheast1: return .aws - case .apnortheast2: return .aws - case .apnortheast3: return .aws - case .apsouth1: return .aws - case .apsouth2: return .aws - case .apsoutheast1: return .aws - case .apsoutheast2: return .aws - case .apsoutheast3: return .aws - case .apsoutheast4: return .aws - case .apsoutheast5: return .aws - case .apsoutheast7: return .aws - case .cacentral1: return .aws - case .cawest1: return .aws - case .cnnorth1: return .awscn - case .cnnorthwest1: return .awscn - case .eucentral1: return .aws - case .eucentral2: return .aws - case .euisoewest1: return .awsisoe - case .eunorth1: return .aws - case .eusouth1: return .aws - case .eusouth2: return .aws - case .euwest1: return .aws - case .euwest2: return .aws - case .euwest3: return .aws - case .ilcentral1: return .aws - case .mecentral1: return .aws - case .mesouth1: return .aws - case .mxcentral1: return .aws - case .saeast1: return .aws - case .useast1: return .aws - case .useast2: return .aws - case .usgoveast1: return .awsusgov - case .usgovwest1: return .awsusgov - case .usisoeast1: return .awsiso - case .usisowest1: return .awsiso - case .usisobeast1: return .awsisob - case .usisofeast1: return .awsisof - case .usisofsouth1: return .awsisof - case .uswest1: return .aws - case .uswest2: return .aws - default: return .aws - } - } -} - -extension Region: CustomStringConvertible { - public var description: String { self.rawValue } -} - -extension Region: Codable {} - -/// Enumeration for all AWS partitions -public struct AWSPartition: Sendable, RawRepresentable, Equatable, Hashable { - enum InternalPartition: String { - case aws - case awscn - case awsusgov - case awsiso - case awsisob - case awsisoe - case awsisof - } - - private var partition: InternalPartition - - public var rawValue: String { self.partition.rawValue } - - public init?(rawValue: String) { - guard let partition = InternalPartition(rawValue: rawValue) else { return nil } - self.partition = partition - } - - private init(partition: InternalPartition) { - self.partition = partition - } - - // AWS Standard - public static var aws: AWSPartition { .init(partition: .aws) } - // AWS China - public static var awscn: AWSPartition { .init(partition: .awscn) } - // AWS GovCloud (US) - public static var awsusgov: AWSPartition { .init(partition: .awsusgov) } - // AWS ISO (US) - public static var awsiso: AWSPartition { .init(partition: .awsiso) } - // AWS ISOB (US) - public static var awsisob: AWSPartition { .init(partition: .awsisob) } - // AWS ISOE (Europe) - public static var awsisoe: AWSPartition { .init(partition: .awsisoe) } - // AWS ISOF - public static var awsisof: AWSPartition { .init(partition: .awsisof) } -} - -extension AWSPartition { - public var dnsSuffix: String { - switch self.partition { - case .aws: return "amazonaws.com" - case .awscn: return "amazonaws.com.cn" - case .awsusgov: return "amazonaws.com" - case .awsiso: return "c2s.ic.gov" - case .awsisob: return "sc2s.sgov.gov" - case .awsisoe: return "cloud.adc-e.uk" - case .awsisof: return "csp.hci.ic.gov" - } - } - - public func defaultEndpoint(region: Region, service: String) -> String { - switch self.partition { - case .aws: return "\(service).\(region).amazonaws.com" - case .awscn: return "\(service).\(region).amazonaws.com.cn" - case .awsusgov: return "\(service).\(region).amazonaws.com" - case .awsiso: return "\(service).\(region).c2s.ic.gov" - case .awsisob: return "\(service).\(region).sc2s.sgov.gov" - case .awsisoe: return "\(service).\(region).cloud.adc-e.uk" - case .awsisof: return "\(service).\(region).csp.hci.ic.gov" - } - } -} - -// allows to create a Region from a String -// it will only create a Region if the provided -// region name is valid. -extension Region { - public init?(awsRegionName: String) { - self.init(rawValue: awsRegionName) - switch self { - case .afsouth1, - .apeast1, - .apnortheast1, - .apnortheast2, - .apnortheast3, - .apsouth1, - .apsouth2, - .apsoutheast1, - .apsoutheast2, - .apsoutheast3, - .apsoutheast4, - .apsoutheast5, - .apsoutheast7, - .cacentral1, - .cawest1, - .cnnorth1, - .cnnorthwest1, - .eucentral1, - .eucentral2, - .euisoewest1, - .eunorth1, - .eusouth1, - .eusouth2, - .euwest1, - .euwest2, - .euwest3, - .ilcentral1, - .mecentral1, - .mesouth1, - .mxcentral1, - .saeast1, - .useast1, - .useast2, - .usgoveast1, - .usgovwest1, - .usisoeast1, - .usisowest1, - .usisobeast1, - .usisofeast1, - .usisofsouth1, - .uswest1, - .uswest2: - return - default: - return nil - } - } -} diff --git a/backend/Sources/BedrockTypes/Role.swift b/backend/Sources/BedrockTypes/Role.swift deleted file mode 100644 index d2ce14d8..00000000 --- a/backend/Sources/BedrockTypes/Role.swift +++ /dev/null @@ -1,21 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public enum Role: String, Codable { - case user - case assistant -} diff --git a/backend/Sources/BedrockTypes/TextCompletion.swift b/backend/Sources/BedrockTypes/TextCompletion.swift deleted file mode 100644 index 0b740647..00000000 --- a/backend/Sources/BedrockTypes/TextCompletion.swift +++ /dev/null @@ -1,24 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Foundation - -public struct TextCompletion: Codable { - let completion: String - - public init(_ completion: String) { - self.completion = completion - } -} diff --git a/backend/Sources/App/App.swift b/backend/Sources/PlaygroundAPI/App.swift similarity index 100% rename from backend/Sources/App/App.swift rename to backend/Sources/PlaygroundAPI/App.swift diff --git a/backend/Sources/App/Application+build.swift b/backend/Sources/PlaygroundAPI/Application+build.swift similarity index 92% rename from backend/Sources/App/Application+build.swift rename to backend/Sources/PlaygroundAPI/Application+build.swift index 4e807eae..08b1f2c5 100644 --- a/backend/Sources/App/Application+build.swift +++ b/backend/Sources/PlaygroundAPI/Application+build.swift @@ -13,10 +13,11 @@ // //===----------------------------------------------------------------------===// -import Hummingbird -import Logging import BedrockService import BedrockTypes +import Foundation +import Hummingbird +import Logging /// Application arguments protocol. We use a protocol so we can call /// `buildApplication` inside Tests as well as in the App executable. @@ -160,7 +161,7 @@ func buildRouter(useSSO: Bool, logger: Logger) async throws -> Router ChatOutput in + router.post("/foundation-models/chat/:modelId") { request, context -> ConverseReply in do { guard let modelId = context.parameters.get("modelId") else { throw HTTPError(.badRequest, message: "No modelId was given.") @@ -168,20 +169,24 @@ func buildRouter(useSSO: Bool, logger: Logger) async throws -> Router ListFoundationModelsOutput - { - ListFoundationModelsOutput( - modelSummaries: [ - BedrockClientTypes.FoundationModelSummary( - modelId: "anthropic.claude-instant-v1", - modelName: "Claude Instant", - providerName: "Anthropic", - responseStreamingSupported: false - ), - BedrockClientTypes.FoundationModelSummary( - modelId: "anthropic.claude-instant-v2", - modelName: "Claude Instant 2", - providerName: "Anthropic", - responseStreamingSupported: true - ), - BedrockClientTypes.FoundationModelSummary( - modelId: "unknownID", - modelName: "Claude Instant 3", - providerName: nil, - responseStreamingSupported: false - ), - ]) - } -} diff --git a/backend/Tests/BedrockServiceTests/Mock/MockBedrockRuntimeClient.swift b/backend/Tests/BedrockServiceTests/Mock/MockBedrockRuntimeClient.swift deleted file mode 100644 index 53fa8f47..00000000 --- a/backend/Tests/BedrockServiceTests/Mock/MockBedrockRuntimeClient.swift +++ /dev/null @@ -1,220 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -@preconcurrency import AWSBedrockRuntime -import AWSClientRuntime -import AWSSDKIdentity -import Foundation -import BedrockService -import BedrockTypes - -public struct MockBedrockRuntimeClient: BedrockRuntimeClientProtocol { - public init() {} - - // MARK: converse - public func converse(input: ConverseInput) async throws -> ConverseOutput { - guard let messages = input.messages, - let content = messages.first?.content?.first, - case let .text(prompt) = content - else { - throw AWSBedrockRuntime.ValidationException(message: "Missing required message content") - } - - let message = BedrockRuntimeClientTypes.Message( - content: [.text("Your prompt was: \(prompt)")], - role: .assistant - ) - return ConverseOutput(output: .message(message)) - } - - // MARK: invokeModel - - public func invokeModel(input: InvokeModelInput) async throws -> InvokeModelOutput { - guard let modelId = input.modelId else { - throw AWSBedrockRuntime.ValidationException( - message: "Malformed input request, please reformat your input and try again." - ) - } - guard let inputBody = input.body else { - throw AWSBedrockRuntime.ValidationException( - message: "Malformed input request, please reformat your input and try again." - ) - } - let model: BedrockModel = BedrockModel(rawValue: modelId)! - - switch model.modality.getName() { - case "Amazon Image Generation": - return InvokeModelOutput(body: try getImageGeneration(body: inputBody)) - case "Nova Text Generation": - return InvokeModelOutput(body: try invokeNovaModel(body: inputBody)) - case "Titan Text Generation": - return InvokeModelOutput(body: try invokeTitanModel(body: inputBody)) - case "Anthropic Text Generation": - return InvokeModelOutput(body: try invokeAnthropicModel(body: inputBody)) - default: - throw AWSBedrockRuntime.ValidationException( - // message: "Malformed input request, please reformat your input and try again." - message: "Hier in de default! model: \(String(describing: model))" - ) - } - } - - private func getImageGeneration(body: Data) throws -> Data { - guard - let json: [String: Any] = try? JSONSerialization.jsonObject( - with: body, - options: [] - ) - as? [String: Any], - let imageGenerationConfig = json["imageGenerationConfig"] as? [String: Any], - let nrOfImages = imageGenerationConfig["numberOfImages"] as? Int - else { - throw AWSBedrockRuntime.ValidationException( - message: "Malformed input request, please reformat your input and try again." - ) - } - - let mockBase64Image = - "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" - let imageArray = Array(repeating: "\"\(mockBase64Image)\"", count: nrOfImages) - return """ - { - "images": [ - \(imageArray.joined(separator: ",\n ")) - ] - } - """.data(using: .utf8)! - } - - private func invokeNovaModel(body: Data) throws -> Data? { - guard - let json: [String: Any] = try? JSONSerialization.jsonObject( - with: body, - options: [] - ) - as? [String: Any] - else { - throw AWSBedrockRuntime.ValidationException( - message: "Malformed input request, please reformat your input and try again." - ) - } - if let messages = json["messages"] as? [[String: Any]], - let firstMessage = messages.first, - let content = firstMessage["content"] as? [[String: Any]], - let firstContent = content.first, - let inputText = firstContent["text"] as? String - { - return """ - { - "output":{ - "message":{ - "content":[ - {"text":"This is the textcompletion for: \(inputText)"} - ], - "role":"assistant" - }}, - "stopReason":"end_turn", - "usage":{ - "inputTokens":5, - "outputTokens":244, - "totalTokens":249, - "cacheReadInputTokenCount":0, - "cacheWriteInputTokenCount":0 - } - } - """.data(using: .utf8)! - } else { - throw AWSBedrockRuntime.ValidationException( - message: "Malformed input request, please reformat your input and try again." - ) - } - } - - private func invokeTitanModel(body: Data) throws -> Data? { - guard - let json: [String: Any] = try? JSONSerialization.jsonObject( - with: body, - options: [] - ) - as? [String: Any] - else { - throw AWSBedrockRuntime.ValidationException( - message: "Hier is het)" - // message: "Malformed input request, please reformat your input and try again." - ) - } - if let inputText = json["inputText"] as? String { - return """ - { - "inputTextTokenCount":5, - "results":[ - { - "tokenCount":105, - "outputText":"This is the textcompletion for: \(inputText)", - "completionReason":"FINISH" - } - ] - } - """.data(using: .utf8)! - } else { - throw AWSBedrockRuntime.ValidationException( - message: "Malformed input request, please reformat your input and try again." - ) - } - } - - private func invokeAnthropicModel(body: Data) throws -> Data? { - guard - let json: [String: Any] = try? JSONSerialization.jsonObject( - with: body, - options: [] - ) - as? [String: Any] - else { - throw AWSBedrockRuntime.ValidationException( - message: "Malformed input request, please reformat your input and try again." - ) - } - if let messages = json["messages"] as? [[String: Any]], - let firstMessage = messages.first, - let content = firstMessage["content"] as? [[String: Any]], - let firstContent = content.first, - let inputText = firstContent["text"] as? String - { - return """ - { - "id":"msg_bdrk_0146cw8Wd6Dn8WZiQWeF6TEj", - "type":"message", - "role":"assistant", - "model":"claude-3-haiku-20240307", - "content":[ - { - "type":"text", - "text":"This is the textcompletion for: \(inputText)" - }], - "stop_reason":"max_tokens", - "stop_sequence":null, - "usage":{ - "input_tokens":12, - "output_tokens":100} - } - """.data(using: .utf8)! - } else { - throw AWSBedrockRuntime.ValidationException( - message: "Malformed input request, please reformat your input and try again." - ) - } - } -} diff --git a/backend/Tests/BedrockServiceTests/SwiftBedrockServiceTests.swift b/backend/Tests/BedrockServiceTests/SwiftBedrockServiceTests.swift deleted file mode 100644 index 61174f48..00000000 --- a/backend/Tests/BedrockServiceTests/SwiftBedrockServiceTests.swift +++ /dev/null @@ -1,429 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Foundation Models Playground open source project -// -// Copyright (c) 2025 Amazon.com, Inc. or its affiliates -// and the Swift Foundation Models Playground project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Foundation Models Playground project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import Testing - -@testable import BedrockService -@testable import BedrockTypes - -//struct Constants { -// -//} - -@Suite("SwiftBedrockService Tests") -struct BedrockServiceTests { - let bedrock: SwiftBedrock - - init() async throws { - self.bedrock = try await SwiftBedrock( - bedrockClient: MockBedrockClient(), - bedrockRuntimeClient: MockBedrockRuntimeClient() - ) - } - - // MARK: listModels - @Test("List all models") - func listModels() async throws { - let models = try await bedrock.listModels() - #expect(models.count == 2) - #expect(models[0].modelId == "anthropic.claude-instant-v1") - #expect(models[0].modelName == "Claude Instant") - #expect(models[0].providerName == "Anthropic") - } - - // MARK: constants - static let validNrOfImages = [1, 2, 3, 4, 5] - static let invalidNrOfImages = [-4, 0, 6, 20] - static let validTemperature = [0, 0.2, 0.6, 1] - static let invalidTemperature = [-2.5, -1, 1.00001, 2] - static let validMaxTokens = [1, 10, 100, 5000] - static let invalidMaxTokens = [0, -1, -2] - static let validSimilarity = [0.5] - static let invalidSimilarity = [-4, 0.02, 1.1, 2] - static let validPrompts = [ - "This is a test", - "!@#$%^&*()_+{}|:<>?", - String(repeating: "test ", count: 1000), - ] - static let invalidPrompts = [ - "", " ", " \n ", "\t", -// String(repeating: "tests", count: 5_000_001), - ] - static let textCompletionModels = [ - BedrockModel.nova_micro, -// BedrockModel.titan_text_g1_lite, -// BedrockModel.titan_text_g1_express, -// BedrockModel.titan_text_g1_premier, - BedrockModel.claudev1, - BedrockModel.claudev2, - BedrockModel.claudev2_1, - BedrockModel.claudev3_haiku, - BedrockModel.claudev3_5_haiku, - ] - static let imageGenerationModels = [ - BedrockModel.titan_image_g1_v1, - BedrockModel.titan_image_g1_v2, - BedrockModel.nova_canvas, - ] - - // MARK: completeText - - @Test( - "Complete text using an implemented model", - arguments: textCompletionModels - ) - func completeTextWithValidModel(model: BedrockModel) async throws { - let completion: TextCompletion = try await bedrock.completeText( - "This is a test", - with: model, - maxTokens: 100, - temperature: 0.5 - ) - #expect(completion.completion == "This is the textcompletion for: This is a test") - } - - @Test( - "Complete text using an invalid model", - arguments: imageGenerationModels - ) - func completeTextWithInvalidModel(model: BedrockModel) async throws { - await #expect(throws: BedrockServiceError.self) { - let _: TextCompletion = try await bedrock.completeText( - "This is a test", - with: model, - temperature: 0.8 - ) - } - } - - @Test("Complete text using a valid temperature", arguments: validTemperature) - func completeTextWithValidTemperature(temperature: Double) async throws { - let completion: TextCompletion = try await bedrock.completeText( - "This is a test", - with: BedrockModel.nova_micro, - temperature: temperature - ) - #expect(completion.completion == "This is the textcompletion for: This is a test") - } - - @Test("Complete text using an invalid temperature", arguments: invalidTemperature) - func completeTextWithInvalidTemperature(temperature: Double) async throws { - await #expect(throws: BedrockServiceError.self) { - let _: TextCompletion = try await bedrock.completeText( - "This is a test", - with: BedrockModel.nova_micro, - temperature: temperature - ) - } - } - - @Test( - "Complete text using a valid maxTokens", - arguments: validMaxTokens - ) - func completeTextWithValidMaxTokens(maxTokens: Int) async throws { - let completion: TextCompletion = try await bedrock.completeText( - "This is a test", - with: BedrockModel.nova_micro, - maxTokens: maxTokens - ) - #expect(completion.completion == "This is the textcompletion for: This is a test") - } - - @Test( - "Complete text using an invalid maxTokens", - arguments: invalidMaxTokens - ) - func completeTextWithInvalidMaxTokens(maxTokens: Int) async throws { - await #expect(throws: BedrockServiceError.self) { - let _: TextCompletion = try await bedrock.completeText( - "This is a test", - with: BedrockModel.nova_micro, - maxTokens: maxTokens - ) - } - } - - @Test( - "Complete text using a valid prompt", - arguments: validPrompts - ) - func completeTextWithValidPrompt(prompt: String) async throws { - let completion: TextCompletion = try await bedrock.completeText( - prompt, - with: BedrockModel.nova_micro, - maxTokens: 200 - ) - #expect(completion.completion == "This is the textcompletion for: \(prompt)") - } - - @Test( - "Complete text using an invalid prompt", - arguments: invalidPrompts - ) - func completeTextWithInvalidPrompt(prompt: String) async throws { - await #expect(throws: BedrockServiceError.self) { - let _: TextCompletion = try await bedrock.completeText( - prompt, - with: BedrockModel.nova_micro, - maxTokens: 10 - ) - } - } - - // MARK: generateImage - - @Test( - "Generate image using an implemented model", - arguments: imageGenerationModels - ) - func generateImageWithValidModel(model: BedrockModel) async throws { - let output: ImageGenerationOutput = try await bedrock.generateImage( - "This is a test", - with: model - ) - #expect(output.images.count == 1) - } - - @Test( - "Generate image using an implemented model", - arguments: textCompletionModels - ) - func generateImageWithInvalidModel(model: BedrockModel) async throws { - await #expect(throws: BedrockServiceError.self) { - let _: ImageGenerationOutput = try await bedrock.generateImage( - "This is a test", - with: model, - nrOfImages: 3 - ) - } - } - - @Test( - "Generate image using a valid nrOfImages", - arguments: validNrOfImages - ) - func generateImageWithValidNrOfImages(nrOfImages: Int) async throws { - let output: ImageGenerationOutput = try await bedrock.generateImage( - "This is a test", - with: BedrockModel.nova_canvas, - nrOfImages: nrOfImages - ) - #expect(output.images.count == nrOfImages) - } - - @Test( - "Generate image using an invalid nrOfImages", - arguments: invalidNrOfImages - ) - func generateImageWithInvalidNrOfImages(nrOfImages: Int) async throws { - await #expect(throws: BedrockServiceError.self) { - let _: ImageGenerationOutput = try await bedrock.generateImage( - "This is a test", - with: BedrockModel.nova_canvas, - nrOfImages: nrOfImages - ) - } - } - - @Test( - "Generate image using a valid prompt", - arguments: validPrompts - ) - func generateImageWithValidPrompt(prompt: String) async throws { - let output: ImageGenerationOutput = try await bedrock.generateImage( - prompt, - with: BedrockModel.nova_canvas, - nrOfImages: 3 - ) - #expect(output.images.count == 3) - } - - @Test( - "Generate image using an invalid prompt", - arguments: invalidPrompts - ) - func generateImageWithInvalidPrompt(prompt: String) async throws { - await #expect(throws: BedrockServiceError.self) { - let _: ImageGenerationOutput = try await bedrock.generateImage( - prompt, - with: BedrockModel.nova_canvas - ) - } - } - - // MARK: generateImageVariation - - @Test( - "Generate image variation using an implemented model", - arguments: imageGenerationModels - ) - func generateImageVariationWithValidModel(model: BedrockModel) async throws { - let mockBase64Image = - "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" - let output: ImageGenerationOutput = try await bedrock.generateImageVariation( - image: mockBase64Image, - prompt: "This is a test", - with: model, - nrOfImages: 3 - ) - #expect(output.images.count == 3) - } - - @Test( - "Generate image variation using an invalid model", - arguments: textCompletionModels - ) - func generateImageVariationWithInvalidModel(model: BedrockModel) async throws { - await #expect(throws: BedrockServiceError.self) { - let mockBase64Image = - "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" - let _: ImageGenerationOutput = try await bedrock.generateImageVariation( - image: mockBase64Image, - prompt: "This is a test", - with: model, - nrOfImages: 3 - ) - } - } - - @Test( - "Generate image variation using a valid nrOfImages", - arguments: validNrOfImages - ) - func generateImageVariationWithValidNrOfImages(nrOfImages: Int) async throws { - let mockBase64Image = - "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" - let output: ImageGenerationOutput = try await bedrock.generateImageVariation( - image: mockBase64Image, - prompt: "This is a test", - with: BedrockModel.nova_canvas, - nrOfImages: nrOfImages - ) - #expect(output.images.count == nrOfImages) - } - - @Test( - "Generate image variation using an invalid nrOfImages", - arguments: invalidNrOfImages - ) - func generateImageVariationWithInvalidNrOfImages(nrOfImages: Int) async throws { - await #expect(throws: BedrockServiceError.self) { - let mockBase64Image = - "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" - let _: ImageGenerationOutput = try await bedrock.generateImageVariation( - image: mockBase64Image, - prompt: "This is a test", - with: BedrockModel.nova_canvas, - nrOfImages: nrOfImages - ) - } - } - - // @Test( - // "Generate image variation using a valid similarity", - // arguments: validSimilarity - // ) - // func generateImageVariationWithValidNr(similarity: Double) async throws { - // let mockBase64Image = - // "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" - // let output: ImageGenerationOutput = try await bedrock.generateImageVariation( - // image: mockBase64Image, - // prompt: "This is a test", - // with: BedrockModel.nova_canvas, - // similarity: similarity, - // nrOfImages: 3 - // ) - // #expect(output.images.count == 3) - // } - - // @Test( - // "Generate image variation using an invalid similarity", - // arguments: invalidSimilarity - // ) - // func generateImageVariationWithInvalidNrOfImages(similarity: Double) async throws { - // await #expect(throws: BedrockServiceError.self) { - // let mockBase64Image = - // "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" - // let _: ImageGenerationOutput = try await bedrock.generateImageVariation( - // image: mockBase64Image, - // prompt: "This is a test", - // with: BedrockModel.nova_canvas, - // similarity: similarity, - // nrOfImages: 3 - // ) - // } - // } - - @Test( - "Generate image variation using a valid prompt", - arguments: validPrompts - ) - func generateImageVariationWithValidPrompt(prompt: String) async throws { - let mockBase64Image = - "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" - let output: ImageGenerationOutput = try await bedrock.generateImageVariation( - image: mockBase64Image, - prompt: prompt, - with: BedrockModel.nova_canvas, - similarity: 0.6 - ) - #expect(output.images.count == 1) - } - - @Test( - "Generate image variation using an invalid prompt", - arguments: invalidPrompts - ) - func generateImageVariationWithInvalidPrompt(prompt: String) async throws { - await #expect(throws: BedrockServiceError.self) { - let mockBase64Image = - "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" - let _: ImageGenerationOutput = try await bedrock.generateImageVariation( - image: mockBase64Image, - prompt: prompt, - with: BedrockModel.nova_canvas, - similarity: 0.6 - ) - } - } - - // MARK: converse - - @Test( - "Continue conversation using a valid prompt", - arguments: validPrompts - ) - func converseWithValidPrompt(prompt: String) async throws { - let output: String = try await bedrock.converse( - with: BedrockModel.nova_micro, - prompt: prompt - ) - #expect(output == "Your prompt was: \(prompt)") - } - - @Test( - "Continue conversation variation using an invalid prompt", - arguments: invalidPrompts - ) - func converseWithInvalidPrompt(prompt: String) async throws { - await #expect(throws: BedrockServiceError.self) { - let _: String = try await bedrock.converse( - with: BedrockModel.nova_micro, - prompt: prompt - ) - } - } -} diff --git a/frontend/components/chatPlayground/ChatComponent.jsx b/frontend/components/chatPlayground/ChatComponent.jsx index 4383880f..11c16263 100644 --- a/frontend/components/chatPlayground/ChatComponent.jsx +++ b/frontend/components/chatPlayground/ChatComponent.jsx @@ -8,6 +8,7 @@ import GlobalConfig from "@/app/app.config"; import ChatModelSelector from "./ChatModelSelector"; import { defaultModel } from "@/helpers/modelData"; import NumericInput from "../NumericInput"; +import Image from 'next/image'; export default function ChatContainer() { @@ -21,7 +22,8 @@ export default function ChatContainer() { const [topP, setTopP] = useState(0.9); const [stopSequences, setStopSequences] = useState([]); const [stopSequenceInput, setStopSequenceInput] = useState(''); - + const [referenceImage, setReferenceImage] = useState(null); + const [previewImage, setPreviewImage] = useState('/placeholder.png'); const endpoint = `/foundation-models/chat/${selectedModel.modelId}`; const api = `${GlobalConfig.apiHost}:${GlobalConfig.apiPort}${endpoint}`; @@ -66,6 +68,63 @@ export default function ChatContainer() { setHistory([]); }; + const handleFileUpload = async (event) => { + const file = event.target.files[0]; + if (file) { + // Create preview for the UI + const reader = new FileReader(); + reader.onload = (e) => { + setPreviewImage(e.target.result); + }; + reader.readAsDataURL(file); + + // Compress and store the image + const compressedBase64 = await compressImage(file); + console.log('Compressed image size:', compressedBase64.length); + setReferenceImage(compressedBase64); + } + }; + + const compressImage = (file) => { + return new Promise((resolve) => { + const reader = new FileReader(); + reader.onload = (event) => { + const img = document.createElement('img'); // Use regular img element instead of Next.js Image + img.onload = () => { + const canvas = document.createElement('canvas'); + // Reduce max dimensions to 512x512 + const maxSize = 512; + let width = img.width; + let height = img.height; + + if (width > height) { + if (width > maxSize) { + height *= maxSize / width; + width = maxSize; + } + } else { + if (height > maxSize) { + width *= maxSize / height; + height = maxSize; + } + } + + canvas.width = width; + canvas.height = height; + + const ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0, width, height); + + // Increase compression by reducing quality to 0.5 (50%) + const compressedBase64 = canvas.toDataURL('image/jpeg', 0.5); + resolve(compressedBase64.split(',')[1]); + }; + img.src = event.target.result; + }; + reader.readAsDataURL(file); + }); + }; + const sendMessage = async () => { const newMessage = { sender: "Human", message: inputValue }; setConversation(prevConversation => [...prevConversation, newMessage]); @@ -80,6 +139,7 @@ export default function ChatContainer() { body: JSON.stringify({ prompt: inputValue, history: history, + imageBytes: referenceImage, maxTokens: parseInt(maxTokens, 10), temperature: parseFloat(temperature), topP: parseFloat(topP), @@ -94,7 +154,7 @@ export default function ChatContainer() { await response.json().then(data => { setConversation(prevConversation => [...prevConversation, { sender: "Assistant", - message: data.reply + message: data.textReply }]); setHistory(data.history); }); @@ -236,6 +296,7 @@ export default function ChatContainer() { {/* Input window */}
+ {/* Text input */}
+ {/* Reference image with preview */} +
+ + Reference image +
+ + {/* Send button */}
+
diff --git a/frontend/helpers/modelData.js b/frontend/helpers/modelData.js index 600b5a07..48594f97 100644 --- a/frontend/helpers/modelData.js +++ b/frontend/helpers/modelData.js @@ -87,6 +87,48 @@ export const models = [ default: 200 } }, + { + modelName: "Amazon Nova Lite", + modelId: "amazon.nova-lite-v1:0", + temperatureRange: { + min: 0, + max: 1, + default: 0.5 + }, + maxTokenRange: { + min: 0, + max: 8191, + default: 200 + } + }, + { + modelName: "Mistral Large (24.02)", + modelId: "mistral.mistral-large-2402-v1:0", + temperatureRange: { + min: 0, + max: 1, + default: 0.7 + }, + maxTokenRange: { + min: 0, + max: 8191, + default: 8191 + } + }, + { + modelName: "Mistral Small (24.02)", + modelId: "mistral.mistral-small-2402-v1:0", + temperatureRange: { + min: 0, + max: 1, + default: 0.7 + }, + maxTokenRange: { + min: 0, + max: 8191, + default: 8191 + } + }, { modelName: "Amazon Titan Text Express", modelId: "amazon.titan-text-express-v1", diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e867be41..bf244f67 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,7 +8,7 @@ "name": "frontend", "version": "0.1.0", "dependencies": { - "next": "14.0.0", + "next": "^14.2.26", "react": "^18", "react-dom": "^18" }, @@ -23,6 +23,7 @@ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -30,66 +31,91 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@next/env": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.0.0.tgz", - "integrity": "sha512-cIKhxkfVELB6hFjYsbtEeTus2mwrTC+JissfZYM0n+8Fv+g8ucUfOlm3VEDtwtwydZ0Nuauv3bl0qF82nnCAqA==" + "version": "14.2.26", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.26.tgz", + "integrity": "sha512-vO//GJ/YBco+H7xdQhzJxF7ub3SUwft76jwaeOyVVQFHCi5DCnkP16WHB+JBylo4vOKPoZBlR94Z8xBxNBdNJA==", + "license": "MIT" }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.0.0.tgz", - "integrity": "sha512-HQKi159jCz4SRsPesVCiNN6tPSAFUkOuSkpJsqYTIlbHLKr1mD6be/J0TvWV6fwJekj81bZV9V/Tgx3C2HO9lA==", + "version": "14.2.26", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.26.tgz", + "integrity": "sha512-zDJY8gsKEseGAxG+C2hTMT0w9Nk9N1Sk1qV7vXYz9MEiyRoF5ogQX2+vplyUMIfygnjn9/A04I6yrUTRTuRiyQ==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -99,12 +125,13 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.0.0.tgz", - "integrity": "sha512-4YyQLMSaCgX/kgC1jjF3s3xSoBnwHuDhnF6WA1DWNEYRsbOOPWjcYhv8TKhRe2ApdOam+VfQSffC4ZD+X4u1Cg==", + "version": "14.2.26", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.26.tgz", + "integrity": "sha512-U0adH5ryLfmTDkahLwG9sUQG2L0a9rYux8crQeC92rPhi3jGQEY47nByQHrVrt3prZigadwj/2HZ1LUUimuSbg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -114,12 +141,13 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.0.0.tgz", - "integrity": "sha512-io7fMkJ28Glj7SH8yvnlD6naIhRDnDxeE55CmpQkj3+uaA2Hko6WGY2pT5SzpQLTnGGnviK85cy8EJ2qsETj/g==", + "version": "14.2.26", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.26.tgz", + "integrity": "sha512-SINMl1I7UhfHGM7SoRiw0AbwnLEMUnJ/3XXVmhyptzriHbWvPPbbm0OEVG24uUKhuS1t0nvN/DBvm5kz6ZIqpg==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -129,12 +157,13 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.0.0.tgz", - "integrity": "sha512-nC2h0l1Jt8LEzyQeSs/BKpXAMe0mnHIMykYALWaeddTqCv5UEN8nGO3BG8JAqW/Y8iutqJsaMe2A9itS0d/r8w==", + "version": "14.2.26", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.26.tgz", + "integrity": "sha512-s6JaezoyJK2DxrwHWxLWtJKlqKqTdi/zaYigDXUJ/gmx/72CrzdVZfMvUc6VqnZ7YEvRijvYo+0o4Z9DencduA==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -144,12 +173,13 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.0.0.tgz", - "integrity": "sha512-Wf+WjXibJQ7hHXOdNOmSMW5bxeJHVf46Pwb3eLSD2L76NrytQlif9NH7JpHuFlYKCQGfKfgSYYre5rIfmnSwQw==", + "version": "14.2.26", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.26.tgz", + "integrity": "sha512-FEXeUQi8/pLr/XI0hKbe0tgbLmHFRhgXOUiPScz2hk0hSmbGiU8aUqVslj/6C6KA38RzXnWoJXo4FMo6aBxjzg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -159,12 +189,13 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.0.0.tgz", - "integrity": "sha512-WTZb2G7B+CTsdigcJVkRxfcAIQj7Lf0ipPNRJ3vlSadU8f0CFGv/ST+sJwF5eSwIe6dxKoX0DG6OljDBaad+rg==", + "version": "14.2.26", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.26.tgz", + "integrity": "sha512-BUsomaO4d2DuXhXhgQCVt2jjX4B4/Thts8nDoIruEJkhE5ifeQFtvW5c9JkdOtYvE5p2G0hcwQ0UbRaQmQwaVg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -174,12 +205,13 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.0.0.tgz", - "integrity": "sha512-7R8/x6oQODmNpnWVW00rlWX90sIlwluJwcvMT6GXNIBOvEf01t3fBg0AGURNKdTJg2xNuP7TyLchCL7Lh2DTiw==", + "version": "14.2.26", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.26.tgz", + "integrity": "sha512-5auwsMVzT7wbB2CZXQxDctpWbdEnEW/e66DyXO1DcgHxIyhP06awu+rHKshZE+lPLIGiwtjo7bsyeuubewwxMw==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -189,12 +221,13 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.0.0.tgz", - "integrity": "sha512-RLK1nELvhCnxaWPF07jGU4x3tjbyx2319q43loZELqF0+iJtKutZ+Lk8SVmf/KiJkYBc7Cragadz7hb3uQvz4g==", + "version": "14.2.26", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.26.tgz", + "integrity": "sha512-GQWg/Vbz9zUGi9X80lOeGsz1rMH/MtFO/XqigDznhhhTfDlDoynCM6982mPCbSlxJ/aveZcKtTlwfAjwhyxDpg==", "cpu": [ "ia32" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -204,12 +237,13 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.0.0.tgz", - "integrity": "sha512-g6hLf1SUko+hnnaywQQZzzb3BRecQsoKkF3o/C+F+dOA4w/noVAJngUVkfwF0+2/8FzNznM7ofM6TGZO9svn7w==", + "version": "14.2.26", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.26.tgz", + "integrity": "sha512-2rdB3T1/Gp7bv1eQTTm9d1Y1sv9UuJ2LAwOE0Pe2prHKe32UNscj7YS13fRB37d0GAiGNR+Y7ZcW8YjDI8Ns0w==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -223,6 +257,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -236,6 +271,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -245,6 +281,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -253,25 +290,72 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0" + }, "node_modules/@swc/helpers": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", - "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "license": "Apache-2.0", "dependencies": { + "@swc/counter": "^0.1.3", "tslib": "^2.4.0" } }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -284,12 +368,13 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/autoprefixer": { - "version": "10.4.16", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", - "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", "dev": true, "funding": [ { @@ -305,12 +390,13 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "browserslist": "^4.21.10", - "caniuse-lite": "^1.0.30001538", - "fraction.js": "^4.3.6", + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -327,43 +413,49 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "dev": true, "funding": [ { @@ -379,11 +471,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -408,14 +501,15 @@ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001557", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001557.tgz", - "integrity": "sha512-91oR7hLNUP3gG6MLU+n96em322a8Xzes8wWdBKhLgUoiJsAF5irZnxSUCbc+qUZXNnPCfUwLOi9ZCZpkvjQajw==", + "version": "1.0.30001712", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001712.tgz", + "integrity": "sha512-MBqPpGYYdQ7/hfKiet9SCI+nmN5/hp4ZzveOJubl5DTAMa5oggjAuoi0Z4onBpKPFI2ePGnQuQIzF3VxDjDJig==", "funding": [ { "type": "opencollective", @@ -429,19 +523,15 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -454,6 +544,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -463,6 +556,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -473,28 +567,60 @@ "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, + "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -506,40 +632,59 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.569", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.569.tgz", - "integrity": "sha512-LsrJjZ0IbVy12ApW3gpYpcmHS3iRxH4bkKOW98y1/D+3cvDUWGcbzbsFinfUS8knpcZk/PG/2p/RnkMCYN7PVg==", - "dev": true + "version": "1.5.132", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.132.tgz", + "integrity": "sha512-QgX9EBvWGmvSRa74zqfnG7+Eno0Ak0vftBll0Pt2/z5b3bEGYL6OUXLgKPtvx73dn3dvwrlyVkjPKRRlhLYTEg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -550,6 +695,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -558,19 +704,21 @@ } }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -578,11 +726,29 @@ "node": ">=8" } }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "dev": true, + "license": "MIT", "engines": { "node": "*" }, @@ -591,18 +757,13 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -616,25 +777,27 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, + "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": "*" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -645,6 +808,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -652,21 +816,18 @@ "node": ">=10.13.0" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -674,27 +835,12 @@ "node": ">= 0.4" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -703,12 +849,16 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -719,15 +869,27 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -740,15 +902,40 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jiti": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz", - "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==", + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, + "license": "MIT", "bin": { "jiti": "bin/jiti.js" } @@ -756,27 +943,34 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" }, "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -784,22 +978,31 @@ "loose-envify": "cli.js" } }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -807,15 +1010,29 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" } }, "node_modules/mz": { @@ -823,6 +1040,7 @@ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -830,15 +1048,16 @@ } }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -847,17 +1066,18 @@ } }, "node_modules/next": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/next/-/next-14.0.0.tgz", - "integrity": "sha512-J0jHKBJpB9zd4+c153sair0sz44mbaCHxggs8ryVXSFBuBqJ8XdE9/ozoV85xGh2VnSjahwntBZZgsihL9QznA==", + "version": "14.2.26", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.26.tgz", + "integrity": "sha512-b81XSLihMwCfwiUVRRja3LphLo4uBBMZEzBBWMaISbKTwOmq3wPknIETy/8000tr7Gq4WmbuFYPS7jOYIf+ZJw==", + "license": "MIT", "dependencies": { - "@next/env": "14.0.0", - "@swc/helpers": "0.5.2", + "@next/env": "14.2.26", + "@swc/helpers": "0.5.5", "busboy": "1.6.0", - "caniuse-lite": "^1.0.30001406", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", "postcss": "8.4.31", - "styled-jsx": "5.1.1", - "watchpack": "2.4.0" + "styled-jsx": "5.1.1" }, "bin": { "next": "dist/bin/next" @@ -866,18 +1086,19 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.0.0", - "@next/swc-darwin-x64": "14.0.0", - "@next/swc-linux-arm64-gnu": "14.0.0", - "@next/swc-linux-arm64-musl": "14.0.0", - "@next/swc-linux-x64-gnu": "14.0.0", - "@next/swc-linux-x64-musl": "14.0.0", - "@next/swc-win32-arm64-msvc": "14.0.0", - "@next/swc-win32-ia32-msvc": "14.0.0", - "@next/swc-win32-x64-msvc": "14.0.0" + "@next/swc-darwin-arm64": "14.2.26", + "@next/swc-darwin-x64": "14.2.26", + "@next/swc-linux-arm64-gnu": "14.2.26", + "@next/swc-linux-arm64-musl": "14.2.26", + "@next/swc-linux-x64-gnu": "14.2.26", + "@next/swc-linux-x64-musl": "14.2.26", + "@next/swc-win32-arm64-msvc": "14.2.26", + "@next/swc-win32-ia32-msvc": "14.2.26", + "@next/swc-win32-x64-msvc": "14.2.26" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.3.0" @@ -886,22 +1107,55 @@ "@opentelemetry/api": { "optional": true }, + "@playwright/test": { + "optional": true + }, "sass": { "optional": true } } }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "dev": true + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -911,6 +1165,7 @@ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -920,6 +1175,7 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -929,44 +1185,64 @@ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "dev": true, - "dependencies": { - "wrappy": "1" - } + "license": "BlueOak-1.0.0" }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -979,23 +1255,26 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, "funding": [ { "type": "opencollective", @@ -1010,10 +1289,11 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -1024,6 +1304,7 @@ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -1041,6 +1322,7 @@ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", "dev": true, + "license": "MIT", "dependencies": { "camelcase-css": "^2.0.1" }, @@ -1056,21 +1338,28 @@ } }, "node_modules/postcss-load-config": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", - "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "lilconfig": "^2.0.5", - "yaml": "^2.1.1" + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" }, "engines": { "node": ">= 14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" @@ -1085,29 +1374,37 @@ } }, "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "postcss-selector-parser": "^6.0.11" + "postcss-selector-parser": "^6.1.1" }, "engines": { "node": ">=12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": "^8.2.14" } }, "node_modules/postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -1120,7 +1417,8 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -1140,12 +1438,14 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" }, @@ -1154,15 +1454,16 @@ } }, "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "^18.2.0" + "react": "^18.3.1" } }, "node_modules/read-cache": { @@ -1170,6 +1471,7 @@ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", "dev": true, + "license": "MIT", "dependencies": { "pify": "^2.3.0" } @@ -1179,6 +1481,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -1187,27 +1490,32 @@ } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -1232,22 +1540,61 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" } }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -1260,10 +1607,115 @@ "node": ">=10.0.0" } }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "license": "MIT", "dependencies": { "client-only": "0.0.1" }, @@ -1283,14 +1735,15 @@ } }, "node_modules/sucrase": { - "version": "3.34.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", - "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", - "glob": "7.1.6", + "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", @@ -1301,7 +1754,7 @@ "sucrase-node": "bin/sucrase-node" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -1309,6 +1762,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -1317,33 +1771,34 @@ } }, "node_modules/tailwindcss": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.5.tgz", - "integrity": "sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==", + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", "dev": true, + "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", - "chokidar": "^3.5.3", + "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.3.0", + "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.19.1", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", @@ -1358,6 +1813,7 @@ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0" } @@ -1367,6 +1823,7 @@ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "dev": true, + "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -1379,6 +1836,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -1390,17 +1848,19 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "funding": [ { @@ -1416,9 +1876,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -1431,31 +1892,132 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=10.13.0" + "node": ">= 8" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } }, "node_modules/yaml": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", - "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", + "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, "engines": { "node": ">= 14" } diff --git a/frontend/package.json b/frontend/package.json index f025bd79..eb60bed0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,9 +9,9 @@ "lint": "next lint" }, "dependencies": { + "next": "^14.2.26", "react": "^18", - "react-dom": "^18", - "next": "14.0.0" + "react-dom": "^18" }, "devDependencies": { "autoprefixer": "^10", diff --git a/openapi.yaml b/openapi.yaml index 99a2103c..12d5ee48 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -75,7 +75,7 @@ components: type: string enum: [user, assistant, unknown] content: - type: string # FIXME: will not always be a string + type: string # FIXME: will not always be a string enum: [text, unknown] maxTokens: type: integer @@ -104,7 +104,7 @@ components: type: string enum: [user, assistant, unknown] content: - type: string # FIXME: will not always be a string + type: string # FIXME: will not always be a string enum: [text, unknown] paths: diff --git a/parameter_cheatsheet.md b/parameter_cheatsheet.md deleted file mode 100644 index 2c95c3f6..00000000 --- a/parameter_cheatsheet.md +++ /dev/null @@ -1,228 +0,0 @@ - - -## Text Generation parameters - -### Nova -[user guide](https://docs.aws.amazon.com/nova/latest/userguide/complete-request-schema.html) - -| parameter | minValue | maxValue | defaultValue | optional or required | -| ----------- | -------- | --------- | ------------ | -------------------- | -| temperature | 0.00001 | 1 | 0.7 | optional | -| maxTokens | 1 | 5_000 | "dynamic"? | optional | -| topP | 0 | 1.0 | 0.9 | optional | -| topK | 0 | Not found | 50 | optional | - - -| parameter | maxLength | -| --------- | --------- | -| prompt | Not found | - - -| parameter | maxSequences | defaultVal | -| ------------- | ------------ | ---------- | -| stopSequences | Not found | `[]` | - -### Titan -[user guide](https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-text.html) - -| parameter | minValue | maxValue | defaultValue | optional or required | -| ----------- | ------------- | ---------------- | ------------- | -------------------- | -| temperature | 0.0 | 1.0 | 0.7 | required | -| maxTokens | 0 | depends on model | 512 | required | -| topP | 0 | 1 | 0.9 | required | -| topK | Not supported | Not supported | Not supported | required | - -| model | max return tokens | -| ------------------ | ----------------- | -| Titan Text Lite | 4_096 | -| Titan Text Express | 8_192 | -| Titan Text Premier | 3_072 | - - -| parameter | maxLength | -| --------- | --------- | -| prompt | ??? | - - -| parameter | maxSequences | defaultVal | -| ------------- | ------------ | ---------- | -| stopSequences | ??? | `[]` | - -### Claude - -[user guide](https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html) - -| parameter | minValue | maxValue | defaultValue | optional or required | -| ----------- | -------- | -------------------- | --------------------- | -------------------- | -| temperature | 0 | 1 | 1 | optional | -| maxTokens | 1 | depends on the model | Not found | required | -| topP | 0 | 1 | 0.999 | optional | -| topK | 0 | 500 | "disabled by default" | optional | - -[model comparison](https://docs.anthropic.com/en/docs/about-claude/models/all-models#model-comparison) - -| models | max return tokens | -| --------------------------------- | ----------------- | -| 3 Opus | 4_096 | -| 3 Haiku | 4_096 | -| 3.5 Haiku | 8_192 | -| 3.5 Sonnet | 8_192 | -| 3.7 Sonnet | 8_192 | -| 3.7 Sonnet with extended thinking | 64_000 | - -| parameter | maxLength | -| --------- | --------- | -| prompt | 200_000 | - - -| parameter | maxSequences | defaultVal | -| ------------- | ------------ | ---------- | -| stopSequences | 8191 | `[]` | - -### DeepSeek - -[user guide](https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-deepseek.html) -[deepseek docs](https://api-docs.deepseek.com/quick_start/parameter_settings) - -| parameter | minValue | maxValue | defaultValue | optional or required | -| ----------- | ------------- | ------------- | ------------- | -------------------- | -| temperature | 0 | 1 | 1 | required | -| maxTokens | 1 | 32_768 | Not found | required | -| topP | 0 | 1 | Not found | required | -| topK | Not supported | Not supported | Not supported | required | - - -| parameter | maxLength | -| --------- | --------- | -| prompt | Not found | - - -| parameter | maxSequences | defaultVal | -| ------------- | ------------ | ---------- | -| stopSequences | 10 | `[]` | - -### Llama - -[user guide](https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-text.html) - -- Llama 3 Instruct -- Llama 3.1 Instruct -- Llama 3.2 Instruct -- Llama 3.3 Instruct - -| parameter | minValue | maxValue | defaultValue | optional or required | -| ----------- | ------------- | ------------- | ------------- | -------------------- | -| temperature | 0 | 1 | 0.5 | optional | -| maxTokens | 1 | 2_048 | 512 | optional | -| topP | 0 | 1 | 0.9 | optional | -| topK | Not supported | Not supported | Not supported | optional | - - -| parameter | maxLength | -| --------- | --------- | -| prompt | Not found | - - -| parameter | maxSequences | defaultVal | -| ------------- | ------------- | ------------- | -| stopSequences | Not supported | Not supported | - - -## Image Generation parameters - -### Nova -[user guide](https://docs.aws.amazon.com/nova/latest/userguide/image-gen-req-resp-structure.html) - -#### General - -| parameter | minValue | maxValue | defaultValue | -| ---------- | -------- | ----------- | ------------ | -| nrOfImages | 1 | 5 | 1 | -| cfgScale | 1.1 | 10 | 6.5 | -| seed | 0 | 858_993_459 | 12 | - -#### TEXT_IMAGE - -| parameter | maxLength | -| -------------- | --------- | -| prompt | 1_024 | -| negativePrompt | 1_024 | - -#### Conditioned TEXT_IMAGE - -| parameter | minValue | maxValue | defaultValue | -| ---------- | -------- | -------- | ------------ | -| similarity | 0 | 1.0 | 0.7 | - -#### IMAGE_VARIATION -| parameter | minValue | maxValue | defaultValue | -| ---------- | -------- | -------- | ------------ | -| similarity | 0.2 | 1.0 | ??? | -| images | 1 | 5 | ??? | - -| parameter | maxLength | -| -------------- | --------- | -| prompt | 1_024 | -| negativePrompt | 1_024 | - - -#### COLOR_GUIDED_GENERATION - -| parameter | maxLength | -| -------------- | --------- | -| prompt | 1_024 | -| negativePrompt | 1_024 | -| colors | 10 | - -#### TO DO -| parameter | minValue | maxValue | defaultValue | -| --------- | -------- | -------- | ------------ | - - -| parameter | maxLength | -| --------- | --------- | - - -### Titan - -[user guide](https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-image.html) - -#### Algemeen -| parameter | minValue | maxValue | defaultValue | -| ---------- | -------- | ------------- | ------------ | -| nrOfImages | 1 | 5 | 1 | -| cfgScale | 1.1 | 10.0 | 8.0 | -| seed | 0 | 2_147_483_646 | 42 | - -#### TEXT_IMAGE - -| parameter | maxLength | -| -------------- | --------- | -| prompt | 512 | -| negativePrompt | 512 | - -#### Conditioned TEXT_IMAGE - -| parameter | minValue | maxValue | defaultValue | -| ---------- | -------- | -------- | ------------ | -| similarity | 0 | 1.0 | 0.7 | - -#### IMAGE_VARIATION -| parameter | minValue | maxValue | defaultValue | -| ---------- | -------- | -------- | ------------ | -| similarity | 0.2 | 1.0 | 0.7 | -| images | 1 | 5 | ??? | - -| parameter | maxLength | -| -------------- | --------- | -| prompt | 512 | -| negativePrompt | 512 | - -#### COLOR_GUIDED_GENERATION - -| parameter | maxLength | -| -------------- | --------- | -| prompt | 512 | -| negativePrompt | 512 | -| colors | 10 | -