-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Ryan Wilson <[email protected]> Co-authored-by: Andrew Heard <[email protected]> Co-authored-by: Peter Friese <[email protected]> Co-authored-by: Morgan Chen <[email protected]>
- Loading branch information
1 parent
f630729
commit bdcaf73
Showing
108 changed files
with
7,644 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
name: check | ||
|
||
on: | ||
pull_request: | ||
push: | ||
branches: main | ||
|
||
concurrency: | ||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} | ||
cancel-in-progress: true | ||
|
||
jobs: | ||
check: | ||
runs-on: macos-latest | ||
env: | ||
MINT_PATH: ${{ github.workspace }}/mint | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- uses: actions/setup-python@v4 | ||
with: | ||
python-version: 3.6 | ||
|
||
- name: Cache Mint packages | ||
uses: actions/cache@v3 | ||
with: | ||
path: ${{ env.MINT_PATH }} | ||
key: ${{ runner.os }}-mint-${{ hashFiles('**/Mintfile') }} | ||
restore-keys: ${{ runner.os }}-mint- | ||
|
||
- name: Setup check | ||
run: | | ||
brew update | ||
brew install mint | ||
mint bootstrap | ||
- name: Style | ||
run: scripts/style.sh test-only | ||
|
||
- name: Whitespace | ||
run: scripts/check_whitespace.sh | ||
|
||
- name: Filename spaces | ||
run: scripts/check_filename_spaces.sh | ||
|
||
- name: Copyrights | ||
run: scripts/check_copyright.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
name: cli | ||
|
||
on: | ||
pull_request: | ||
schedule: | ||
# Run every day at 11pm (PST) - cron uses UTC times | ||
- cron: '0 7 * * *' | ||
|
||
concurrency: | ||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} | ||
cancel-in-progress: true | ||
|
||
jobs: | ||
swift-build-run: | ||
strategy: | ||
matrix: | ||
target: [macOS] | ||
os: [macos-13] | ||
include: | ||
- os: macos-13 | ||
xcode: Xcode_15.0.1 | ||
runs-on: ${{ matrix.os }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Xcode | ||
run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer | ||
- name: Initialize xcodebuild | ||
run: xcodebuild -list | ||
- name: Build CLI | ||
run: scripts/third_party/travis/retry.sh scripts/build.sh GenerativeAICLI macOS build Examples/GenerativeAICLI |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
name: samples | ||
|
||
on: | ||
pull_request: | ||
schedule: | ||
# Run every day at 11pm (PST) - cron uses UTC times | ||
- cron: '0 7 * * *' | ||
|
||
concurrency: | ||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} | ||
cancel-in-progress: true | ||
|
||
jobs: | ||
swift-build-run: | ||
strategy: | ||
matrix: | ||
# Test build with debug and release configs (whether or not DEBUG is set and optimization level) | ||
build: [build, archive] | ||
os: [macos-13] | ||
include: | ||
- os: macos-13 | ||
xcode: Xcode_15.0.1 | ||
runs-on: ${{ matrix.os }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Xcode | ||
run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer | ||
- name: Initialize xcodebuild | ||
run: xcodebuild -list | ||
- name: Build the sample | ||
run: scripts/third_party/travis/retry.sh scripts/build.sh GenerativeAISample iOS ${{ matrix.build }} Examples/GenerativeAISample/GenerativeAISample.xcodeproj |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
name: spm | ||
|
||
on: | ||
pull_request: | ||
schedule: | ||
# Run every day at 11pm (PST) - cron uses UTC times | ||
- cron: '0 7 * * *' | ||
|
||
concurrency: | ||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} | ||
cancel-in-progress: true | ||
|
||
jobs: | ||
swift-build-run: | ||
strategy: | ||
matrix: | ||
target: [iOS, macOS] | ||
os: [macos-13] | ||
include: | ||
- os: macos-13 | ||
xcode: Xcode_15.0.1 | ||
runs-on: ${{ matrix.os }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Xcode | ||
run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer | ||
- name: Initialize xcodebuild | ||
run: xcodebuild -list | ||
- name: Build and unit test | ||
run: scripts/third_party/travis/retry.sh scripts/build.sh generative-ai-swift ${{ matrix.target }} test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// swift-tools-version: 5.9 | ||
// The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
||
// Copyright 2023 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "GenerativeAICLI", | ||
platforms: [.macOS(.v13)], | ||
dependencies: [ | ||
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.0"), | ||
.package(name: "GoogleGenerativeAI", path: "../../"), | ||
], | ||
targets: [ | ||
.executableTarget( | ||
name: "generate-content", | ||
dependencies: [ | ||
.product(name: "ArgumentParser", package: "swift-argument-parser"), | ||
.product(name: "GoogleGenerativeAI", package: "GoogleGenerativeAI"), | ||
], | ||
path: "Sources" | ||
), | ||
] | ||
) |
136 changes: 136 additions & 0 deletions
136
Examples/Examples/GenerativeAICLI/Sources/GenerateContent.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
// Copyright 2023 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
import ArgumentParser | ||
import Foundation | ||
import GoogleGenerativeAI | ||
|
||
@main | ||
struct GenerateContent: AsyncParsableCommand { | ||
@Option(help: "The API key to use when calling the Generative Language API.") | ||
var apiKey: String | ||
|
||
@Option(name: .customLong("model"), help: "The name of the model to use (e.g., \"gemini-pro\").") | ||
var modelName: String? | ||
|
||
@Option(help: "The text prompt for the model in natural language.") | ||
var textPrompt: String? | ||
|
||
@Option( | ||
name: .customLong("image-path"), | ||
help: "The file path of an image to pass to the model; must be in JPEG or PNG format.", | ||
transform: URL.filePath(_:) | ||
) | ||
var imageURL: URL? | ||
|
||
@Flag( | ||
name: .customLong("streaming"), | ||
help: "Stream response data, printing it incrementally as it's received." | ||
) var isStreaming = false | ||
|
||
@Flag( | ||
name: .customLong("GoogleGenerativeAIDebugLogEnabled", withSingleDash: true), | ||
help: "Enable additional debug logging." | ||
) var debugLogEnabled = false | ||
|
||
mutating func validate() throws { | ||
if textPrompt == nil && imageURL == nil { | ||
throw ValidationError( | ||
"Missing expected argument(s) '--text-prompt <text-prompt>' and/or" + | ||
" '--image-path <image-path>'." | ||
) | ||
} | ||
} | ||
|
||
mutating func run() async throws { | ||
do { | ||
let safetySettings = [SafetySetting(harmCategory: .dangerousContent, threshold: .blockNone)] | ||
// Let the server pick the default config. | ||
let config = GenerationConfig( | ||
temperature: 0.2, | ||
topP: 0.1, | ||
topK: 16, | ||
candidateCount: 1, | ||
maxOutputTokens: isStreaming ? nil : 256, | ||
stopSequences: nil | ||
) | ||
|
||
let model = GenerativeModel( | ||
name: modelNameOrDefault(), | ||
apiKey: apiKey, | ||
generationConfig: config, | ||
safetySettings: safetySettings | ||
) | ||
|
||
var parts = [ModelContent.Part]() | ||
|
||
if let textPrompt = textPrompt { | ||
parts.append(.text(textPrompt)) | ||
} | ||
|
||
if let imageURL = imageURL { | ||
let mimeType: String | ||
switch imageURL.pathExtension { | ||
case "jpg", "jpeg": | ||
mimeType = "image/jpeg" | ||
case "png": | ||
mimeType = "image/png" | ||
default: | ||
throw CLIError.unsupportedImageType | ||
} | ||
let imageData = try Data(contentsOf: imageURL) | ||
parts.append(.data(mimetype: mimeType, imageData)) | ||
} | ||
|
||
let input = [ModelContent(parts: parts)] | ||
|
||
if isStreaming { | ||
let contentStream = model.generateContentStream(input) | ||
print("Generated Content <streaming>:") | ||
for try await content in contentStream { | ||
if let text = content.text { | ||
print(text) | ||
} | ||
} | ||
} else { | ||
let content = try await model.generateContent(input) | ||
if let text = content.text { | ||
print("Generated Content:\n\(text)") | ||
} | ||
} | ||
} catch { | ||
print("Generate Content Error: \(error)") | ||
} | ||
} | ||
|
||
func modelNameOrDefault() -> String { | ||
if let modelName = modelName { | ||
return modelName | ||
} else if imageURL != nil { | ||
return "gemini-pro-vision" | ||
} else { | ||
return "gemini-pro" | ||
} | ||
} | ||
} | ||
|
||
enum CLIError: Error { | ||
case unsupportedImageType | ||
} | ||
|
||
private extension URL { | ||
static func filePath(_ filePath: String) throws -> URL { | ||
return URL(fileURLWithPath: filePath) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright 2023 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
import Foundation | ||
|
||
enum APIKey { | ||
/// Fetch the API key from `GenerativeAI-Info.plist` | ||
/// This is just *one* way how you can retrieve the API key for your app. | ||
static var `default`: String { | ||
guard let filePath = Bundle.main.path(forResource: "GenerativeAI-Info", ofType: "plist") | ||
else { | ||
fatalError("Couldn't find file 'GenerativeAI-Info.plist'.") | ||
} | ||
let plist = NSDictionary(contentsOfFile: filePath) | ||
guard let value = plist?.object(forKey: "API_KEY") as? String else { | ||
fatalError("Couldn't find key 'API_KEY' in 'GenerativeAI-Info.plist'.") | ||
} | ||
if value.starts(with: "_") { | ||
fatalError( | ||
"Follow the instructions at https://ai.google.dev/tutorials/setup to get an API key." | ||
) | ||
} | ||
return value | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
Examples/Examples/GenerativeAISample/APIKey/GenerativeAI-Info-Sample.plist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>API_KEY</key> | ||
<string>_API_KEY_</string> | ||
</dict> | ||
</plist> |
11 changes: 11 additions & 0 deletions
11
...Examples/GenerativeAISample/ChatSample/Assets.xcassets/AccentColor.colorset/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"colors" : [ | ||
{ | ||
"idiom" : "universal" | ||
} | ||
], | ||
"info" : { | ||
"author" : "xcode", | ||
"version" : 1 | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
...s/Examples/GenerativeAISample/ChatSample/Assets.xcassets/AppIcon.appiconset/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"images" : [ | ||
{ | ||
"idiom" : "universal", | ||
"platform" : "ios", | ||
"size" : "1024x1024" | ||
} | ||
], | ||
"info" : { | ||
"author" : "xcode", | ||
"version" : 1 | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
Examples/Examples/GenerativeAISample/ChatSample/Assets.xcassets/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"info" : { | ||
"author" : "xcode", | ||
"version" : 1 | ||
} | ||
} |
Oops, something went wrong.