-
Notifications
You must be signed in to change notification settings - Fork 2
add support for OpenAI models #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| .DS_Store | ||
| /.build | ||
| /Packages | ||
| xcuserdata/ | ||
| DerivedData/ | ||
| .swiftpm/configuration/registries.json | ||
| .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata | ||
| .netrc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| // swift-tools-version: 6.1 | ||
| // The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
|
||
| import PackageDescription | ||
|
|
||
| let package = Package( | ||
| name: "OpenAI", | ||
| platforms: [.macOS(.v15), .iOS(.v18), .tvOS(.v18)], | ||
| dependencies: [ | ||
| // for production use, uncomment the following line | ||
| // .package(url: "https://github.com/build-on-aws/swift-bedrock-library.git", branch: "main"), | ||
|
|
||
| // for local development, use the following line | ||
| .package(name: "swift-bedrock-library", path: "../.."), | ||
|
|
||
| .package(url: "https://github.com/apple/swift-log.git", from: "1.5.0"), | ||
| ], | ||
| targets: [ | ||
| .executableTarget( | ||
| name: "OpenAIInvoke", | ||
| dependencies: [ | ||
| .product(name: "BedrockService", package: "swift-bedrock-library"), | ||
| .product(name: "Logging", package: "swift-log"), | ||
| ], | ||
| path: "Sources/Invoke" | ||
| ), | ||
| .executableTarget( | ||
| name: "OpenAIConverse", | ||
| dependencies: [ | ||
| .product(name: "BedrockService", package: "swift-bedrock-library"), | ||
| .product(name: "Logging", package: "swift-log"), | ||
| ], | ||
| path: "Sources/Converse" | ||
| ), | ||
| ] | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This source file is part of the Swift Bedrock Library open source project | ||
| // | ||
| // Copyright (c) 2025 Amazon.com, Inc. or its affiliates | ||
| // and the Swift Bedrock Library project authors | ||
| // Licensed under Apache License v2.0 | ||
| // | ||
| // See LICENSE.txt for license information | ||
| // See CONTRIBUTORS.txt for the list of Swift Bedrock Library project authors | ||
| // | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| import BedrockService | ||
| import Logging | ||
|
|
||
| var logger = Logger(label: "OpenAIConverse") | ||
| logger.logLevel = .debug | ||
|
|
||
| let bedrock = try await BedrockService( | ||
| region: .uswest2, | ||
| logger: logger, | ||
| ) | ||
|
|
||
| var builder = try ConverseRequestBuilder(with: .openai_gpt_oss_20b) | ||
| .withPrompt("Who are you?") | ||
|
|
||
| var reply = try await bedrock.converse(with: builder) | ||
|
|
||
| print("Assistant: \(reply)") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This source file is part of the Swift Bedrock Library open source project | ||
| // | ||
| // Copyright (c) 2025 Amazon.com, Inc. or its affiliates | ||
| // and the Swift Bedrock Library project authors | ||
| // Licensed under Apache License v2.0 | ||
| // | ||
| // See LICENSE.txt for license information | ||
| // See CONTRIBUTORS.txt for the list of Swift Bedrock Library project authors | ||
| // | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| import BedrockService | ||
| import Logging | ||
|
|
||
| var logger = Logger(label: "OpenAIInvoke") | ||
| logger.logLevel = .debug | ||
|
|
||
| let bedrock = try await BedrockService( | ||
| region: .uswest2, | ||
| logger: logger | ||
| ) | ||
|
|
||
| let textCompletion = try await bedrock.completeText( | ||
| "Who are you?", | ||
| with: .openai_gpt_oss_20b | ||
| ) | ||
|
|
||
| if let reasoning = textCompletion.reasoning { | ||
| print("------- Reasoning ----------\n\(reasoning)\n----------------------------\n") | ||
| } | ||
| print(textCompletion.completion) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,74 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| //===----------------------------------------------------------------------===// | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // This source file is part of the Swift Bedrock Library open source project | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Copyright (c) 2025 Amazon.com, Inc. or its affiliates | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // and the Swift Bedrock Library project authors | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // Licensed under Apache License v2.0 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // See LICENSE.txt for license information | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // See CONTRIBUTORS.txt for the list of Swift Bedrock Library project authors | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // SPDX-License-Identifier: Apache-2.0 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||
| //===----------------------------------------------------------------------===// | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| import Foundation | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| struct OpenAIText: TextModality, ConverseModality { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let parameters: TextGenerationParameters | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let converseParameters: ConverseParameters | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let converseFeatures: [ConverseFeature] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let maxReasoningTokens: Parameter<Int> | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| func getName() -> String { "OpenAI Text Generation" } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| init( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| parameters: TextGenerationParameters, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| features: [ConverseFeature] = [.textGeneration, .systemPrompts, .document], | ||||||||||||||||||||||||||||||||||||||||||||||||||
| maxReasoningTokens: Parameter<Int> = .notSupported(.maxReasoningTokens) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.parameters = parameters | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.converseFeatures = features | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.converseParameters = ConverseParameters( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| textGenerationParameters: parameters, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| maxReasoningTokens: maxReasoningTokens | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| self.maxReasoningTokens = maxReasoningTokens | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| func getParameters() -> TextGenerationParameters { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| parameters | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| func getConverseParameters() -> ConverseParameters { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ConverseParameters(textGenerationParameters: parameters, maxReasoningTokens: maxReasoningTokens) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| 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 BedrockLibraryError.notFound("No value was given for maxTokens and no default value was found") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if topP != nil && temperature != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| throw BedrockLibraryError.notSupported("Alter either topP or temperature, but not both.") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return OpenAIRequestBody( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| prompt: prompt, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| maxTokens: maxTokens, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| temperature: temperature ?? parameters.temperature.defaultValue, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| topP: topP ?? parameters.topP.defaultValue, | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+62
to
+66
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| return OpenAIRequestBody( | |
| prompt: prompt, | |
| maxTokens: maxTokens, | |
| temperature: temperature ?? parameters.temperature.defaultValue, | |
| topP: topP ?? parameters.topP.defaultValue, | |
| // If both are nil, prefer topP and set temperature to nil | |
| let resolvedTemperature: Double? | |
| let resolvedTopP: Double? | |
| if let t = temperature { | |
| resolvedTemperature = t | |
| resolvedTopP = nil | |
| } else if let p = topP { | |
| resolvedTemperature = nil | |
| resolvedTopP = p | |
| } else { | |
| // Both are nil: prefer topP default, temperature nil | |
| resolvedTemperature = nil | |
| resolvedTopP = parameters.topP.defaultValue | |
| } | |
| return OpenAIRequestBody( | |
| prompt: prompt, | |
| maxTokens: maxTokens, | |
| temperature: resolvedTemperature, | |
| topP: resolvedTopP, |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This source file is part of the Swift Bedrock Library open source project | ||
| // | ||
| // Copyright (c) 2025 Amazon.com, Inc. or its affiliates | ||
| // and the Swift Bedrock Library project authors | ||
| // Licensed under Apache License v2.0 | ||
| // | ||
| // See LICENSE.txt for license information | ||
| // See CONTRIBUTORS.txt for the list of Swift Bedrock Library project authors | ||
| // | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| import Foundation | ||
|
|
||
| // https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-openai.html | ||
|
|
||
| extension BedrockModel { | ||
| public static let openai_gpt_oss_20b: BedrockModel = BedrockModel( | ||
| id: "openai.gpt-oss-20b-1:0", | ||
| name: "OpenAI GPT OSS 20b", | ||
| modality: OpenAIText( | ||
| parameters: TextGenerationParameters( | ||
| temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.7), | ||
| maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 2_048, defaultValue: 150), | ||
| topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), | ||
| topK: Parameter.notSupported(.topK), | ||
| stopSequences: StopSequenceParams.notSupported(), | ||
| maxPromptSize: nil | ||
| ), | ||
| features: [.textGeneration, .systemPrompts, .document] | ||
| ) | ||
| ) | ||
| public static let openai_gpt_oss_120b: BedrockModel = BedrockModel( | ||
| id: "openai.gpt-oss-120b-1:0", | ||
| name: "OpenAI GPT OSS 120b", | ||
| modality: OpenAIText( | ||
| parameters: TextGenerationParameters( | ||
| temperature: Parameter(.temperature, minValue: 0, maxValue: 1, defaultValue: 0.7), | ||
| maxTokens: Parameter(.maxTokens, minValue: 0, maxValue: 2_048, defaultValue: 150), | ||
| topP: Parameter(.topP, minValue: 0, maxValue: 1, defaultValue: 0.9), | ||
| topK: Parameter.notSupported(.topK), | ||
| stopSequences: StopSequenceParams.notSupported(), | ||
| maxPromptSize: nil | ||
| ), | ||
| features: [.textGeneration, .systemPrompts, .document] | ||
| ) | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This source file is part of the Swift Bedrock Library open source project | ||
| // | ||
| // Copyright (c) 2025 Amazon.com, Inc. or its affiliates | ||
| // and the Swift Bedrock Library project authors | ||
| // Licensed under Apache License v2.0 | ||
| // | ||
| // See LICENSE.txt for license information | ||
| // See CONTRIBUTORS.txt for the list of Swift Bedrock Library project authors | ||
| // | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| import Foundation | ||
|
|
||
| public struct OpenAIRequestBody: BedrockBodyCodable { | ||
| private let max_completion_tokens: Int | ||
| private let temperature: Double? | ||
| private let top_p: Double? | ||
| private let messages: [OpenAIMessage] | ||
|
|
||
| public init( | ||
| prompt: String, | ||
| maxTokens: Int, | ||
| temperature: Double?, | ||
| topP: Double? | ||
| ) { | ||
| self.max_completion_tokens = maxTokens | ||
| self.temperature = temperature | ||
| self.messages = [ | ||
| OpenAIMessage(role: .user, content: prompt) | ||
| ] | ||
| self.top_p = topP | ||
| } | ||
|
|
||
| private struct OpenAIMessage: Codable { | ||
|
||
| let role: Role | ||
| let content: String | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The validation logic prevents using both topP and temperature simultaneously, but this restriction may not align with OpenAI's actual API capabilities. Consider verifying this constraint against OpenAI's documentation.