-
Notifications
You must be signed in to change notification settings - Fork 2
add a text chat example #24
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,30 @@ | ||
| // swift-tools-version: 6.0 | ||
| // The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
|
||
| import PackageDescription | ||
|
|
||
| let package = Package( | ||
| name: "TextChat", | ||
| platforms: [.macOS(.v15), .iOS(.v18), .tvOS(.v18)], | ||
| products: [ | ||
| .executable(name: "TextChat", targets: ["TextChat"]) | ||
| ], | ||
| 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: "TextChat", | ||
| dependencies: [ | ||
| .product(name: "BedrockService", package: "swift-bedrock-library"), | ||
| .product(name: "Logging", package: "swift-log"), | ||
| ] | ||
| ) | ||
| ] | ||
| ) |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,102 @@ | ||||||||||||
| //===----------------------------------------------------------------------===// | ||||||||||||
| // | ||||||||||||
| // 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 | ||||||||||||
|
|
||||||||||||
| @main | ||||||||||||
| struct TextChat { | ||||||||||||
| static func main() async throws { | ||||||||||||
| do { | ||||||||||||
| try await TextChat.run() | ||||||||||||
| } catch { | ||||||||||||
| print("Error:\n\(error)") | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| static func run() async throws { | ||||||||||||
| var logger = Logger(label: "TextChat") | ||||||||||||
| logger.logLevel = .debug | ||||||||||||
|
|
||||||||||||
| let bedrock = try await BedrockService( | ||||||||||||
| region: .useast1, | ||||||||||||
| logger: logger | ||||||||||||
| // uncomment if you use SSO with AWS Identity Center | ||||||||||||
| // authentication: .sso | ||||||||||||
| ) | ||||||||||||
|
|
||||||||||||
| // select a model that supports the converse modality | ||||||||||||
| // models must be enabled in your AWS account | ||||||||||||
| let model: BedrockModel = .claudev3_7_sonnet | ||||||||||||
|
|
||||||||||||
| guard model.hasConverseModality() else { | ||||||||||||
| throw MyError.incorrectModality("\(model.name) does not support converse") | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // a reusable var to build the requests | ||||||||||||
| var request: ConverseRequestBuilder? = nil | ||||||||||||
|
|
||||||||||||
| // we keep track of the history of the conversation | ||||||||||||
| var history: [Message] = [] | ||||||||||||
|
|
||||||||||||
| // while the user doesn't type "exit" or "quit" | ||||||||||||
| while true { | ||||||||||||
|
|
||||||||||||
| print("\nYou: ", terminator: "") | ||||||||||||
| let prompt: String = readLine() ?? "" | ||||||||||||
| guard prompt.isEmpty == false else { continue } | ||||||||||||
| if ["exit", "quit"].contains(prompt.lowercased()) { | ||||||||||||
| break | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| print("\nAssistant: ", terminator: "") | ||||||||||||
|
|
||||||||||||
| if request == nil { | ||||||||||||
| // create a new request | ||||||||||||
| request = try ConverseRequestBuilder(with: model) | ||||||||||||
| .withPrompt(prompt) | ||||||||||||
| } else { | ||||||||||||
| // append the new prompt to the existing request | ||||||||||||
| // ConverseRequestBuilder is stateless, it doesn't keep track of the history | ||||||||||||
| // thanks to the `if` above, we're sure `request` is not nil | ||||||||||||
| request = try ConverseRequestBuilder(from: request!) | ||||||||||||
|
||||||||||||
| request = try ConverseRequestBuilder(from: request!) | |
| guard let existingRequest = request else { | |
| throw MyError.incorrectModality("Request is unexpectedly nil") | |
| } | |
| request = try ConverseRequestBuilder(from: existingRequest) |
Copilot
AI
Jun 6, 2025
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.
Force-unwrapping 'request' here may crash if nil; ensure it's non-nil with a guard or unwrap earlier.
| let reply = try await bedrock.converseStream(with: request!) | |
| guard let unwrappedRequest = request else { | |
| throw MyError.incorrectModality("Request is unexpectedly nil") | |
| } | |
| let reply = try await bedrock.converseStream(with: unwrappedRequest) |
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.
[nitpick] Consider using 'logger.error' instead of 'print' for error messages to maintain consistent logging and support structured logs.