Skip to content

Commit dfb4fa9

Browse files
feat: genai sample base (#3587)
* feat: initial base for generative-ai * # This is a combination of 16 commits. # This is the 1st commit message: refactor: updating codeowners # This is the commit message #2: add chat functions # This is the commit message #3: use correct testing project # This is the commit message #4: refactor: adding system tests + updating corresponding chat samples # This is the commit message #5: add countTokens sample # This is the commit message #6: refactor: adding in region tags, abstracting out mimetype, adding new image ur # This is the commit message #7: refactor: updating gs url in test, fix to args getting passed to sample functions # This is the commit message #8: refactor: resolving file paths in tests, adding wait helper function # This is the commit message #9: add warning about safety concerns # This is the commit message #10: refactor:filling out nonstreamingchat and streamcontent tests # This is the commit message #11: add countTokens test # This is the commit message #12: refactor: filling out more streaming tests # This is the commit message #13: add safety settings test # This is the commit message #14: refactor: adding in stream content and multipart content tests # This is the commit message #15: feat: add new sendMultiModalPromptWithImage sample # This is the commit message #16: refactor: adding region tags * refactor: updating codeowners add chat functions use correct testing project refactor: adding system tests + updating corresponding chat samples add countTokens sample refactor: adding in region tags, abstracting out mimetype, adding new image ur refactor: updating gs url in test, fix to args getting passed to sample functions refactor: resolving file paths in tests, adding wait helper function add warning about safety concerns refactor:filling out nonstreamingchat and streamcontent tests add countTokens test refactor: filling out more streaming tests add safety settings test refactor: adding in stream content and multipart content tests feat: add new sendMultiModalPromptWithImage sample refactor: adding region tags update to common prompt fix: resolve linting * refactor: remove index file --------- Co-authored-by: [email protected] <[email protected]>
1 parent 73de2e8 commit dfb4fa9

23 files changed

+1031
-0
lines changed

.github/auto-label.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ path:
4545
eventarc: "eventarc"
4646
error-reporting: "clouderrorreporting"
4747
functions: "cloudfunctions"
48+
generative-ai: "genai"
4849
game-servers: "gameservices"
4950
healthcare: "healhcare"
5051
iam: "iam"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Copyright 2023 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: generative-ai-snippets
16+
on:
17+
push:
18+
branches:
19+
- main
20+
paths:
21+
- 'generative-ai/snippets/**'
22+
- '.github/workflows/generative-ai-snippets.yaml'
23+
pull_request:
24+
paths:
25+
- 'generative-ai/snippets/**'
26+
- '.github/workflows/generative-ai-snippets.yaml'
27+
pull_request_target:
28+
types: [labeled]
29+
paths:
30+
- 'generative-ai/snippets/**'
31+
- '.github/workflows/generative-ai-snippets.yaml'
32+
schedule:
33+
- cron: '0 0 * * 0'
34+
jobs:
35+
test:
36+
if: github.event.action != 'labeled' || github.event.label.name == 'actions:force-run'
37+
runs-on: ubuntu-latest
38+
timeout-minutes: 120
39+
permissions:
40+
contents: 'read'
41+
id-token: 'write'
42+
defaults:
43+
run:
44+
working-directory: 'generative-ai/snippets'
45+
steps:
46+
- uses: actions/[email protected]
47+
with:
48+
ref: ${{github.event.pull_request.head.sha}}
49+
- uses: 'google-github-actions/[email protected]'
50+
with:
51+
workload_identity_provider: 'projects/1046198160504/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider'
52+
service_account: '[email protected]'
53+
create_credentials_file: 'true'
54+
access_token_lifetime: 600s
55+
- id: secrets
56+
uses: 'google-github-actions/get-secretmanager-secrets@v1'
57+
with:
58+
secrets: |-
59+
caip_id:nodejs-docs-samples-tests/nodejs-docs-samples-ai-platform-caip-project-id
60+
location:nodejs-docs-samples-tests/nodejs-docs-samples-ai-platform-location
61+
- uses: actions/[email protected]
62+
with:
63+
node-version: 16
64+
- name: Get npm cache directory
65+
id: npm-cache-dir
66+
shell: bash
67+
run: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT}
68+
- uses: actions/cache@v3
69+
id: npm-cache
70+
with:
71+
path: ${{ steps.npm-cache-dir.outputs.dir }}
72+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
73+
restore-keys: |
74+
${{ runner.os }}-node-
75+
- name: install repo dependencies
76+
run: npm install
77+
working-directory: .
78+
- name: install directory dependencies
79+
run: npm install
80+
- run: npm run build --if-present
81+
- name: set env vars for scheduled run
82+
if: github.event.action == 'schedule'
83+
run: |
84+
echo "MOCHA_REPORTER_SUITENAME=generative-ai-snippets" >> $GITHUB_ENV
85+
echo "MOCHA_REPORTER_OUTPUT=${{github.run_id}}_sponge_log.xml" >> $GITHUB_ENV
86+
echo "MOCHA_REPORTER=xunit" >> $GITHUB_ENV
87+
- run: npm test
88+
env:
89+
LOCATION: ${{ steps.secrets.outputs.location }}
90+
CAIP_PROJECT_ID: ${{ steps.secrets.outputs.caip_id }}
91+
- name: upload test results for FlakyBot workflow
92+
if: github.event.action == 'schedule' && always()
93+
uses: actions/upload-artifact@v3
94+
env:
95+
MOCHA_REPORTER_OUTPUT: "${{github.run_id}}_sponge_log.xml"
96+
with:
97+
name: test-results
98+
path: generative-ai/snippets/${{ env.MOCHA_REPORTER_OUTPUT }}
99+
retention-days: 1
100+
flakybot:
101+
permissions:
102+
contents: 'read'
103+
id-token: 'write'
104+
if: github.event_name == 'schedule' && always() # always() submits logs even if tests fail
105+
uses: ./.github/workflows/flakybot.yaml
106+
needs: [test]

.github/workflows/utils/workflows-secrets.json

+1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
"iam/deny",
66
"security-center/snippets",
77
"storagetransfer",
8+
"generative-ai/snippets",
89
"vision"
910
]

CODEOWNERS

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ monitoring/opencensus @GoogleCloudPlatform/nodejs-samples-reviewers
5050

5151
# Data & AI
5252
ai-platform @GoogleCloudPlatform/dee-data-ai @GoogleCloudPlatform/nodejs-samples-reviewers
53+
generative-ai @GoogleCloudPlatform/dee-data-ai @GoogleCloudPlatform/nodejs-samples-reviewers
5354
automl @GoogleCloudPlatform/dee-data-ai @GoogleCloudPlatform/nodejs-samples-reviewers
5455
cloud-language @GoogleCloudPlatform/dee-data-ai @GoogleCloudPlatform/nodejs-samples-reviewers
5556
contact-center-insights @GoogleCloudPlatform/dee-data-ai @GoogleCloudPlatform/nodejs-samples-reviewers

generative-ai/snippets/countTokens.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
const {VertexAI} = require('@google-cloud/vertexai');
16+
17+
async function countTokens(
18+
projectId = 'PROJECT_ID',
19+
location = 'LOCATION_ID',
20+
model = 'MODEL'
21+
) {
22+
// [START aiplatform_gemini_token_count]
23+
24+
/**
25+
* TODO(developer): Uncomment these variables before running the sample.
26+
*/
27+
// const projectId = 'your-project-id';
28+
// const location = 'us-central1';
29+
// const model = 'gemini-pro';
30+
31+
// Initialize Vertex with your Cloud project and location
32+
const vertex_ai = new VertexAI({project: projectId, location: location});
33+
34+
// Instantiate the model
35+
const generativeModel = vertex_ai.preview.getGenerativeModel({
36+
model: model,
37+
});
38+
39+
const req = {
40+
contents: [{role: 'user', parts: [{text: 'How are you doing today?'}]}],
41+
};
42+
43+
const countTokensResp = await generativeModel.countTokens(req);
44+
console.log('count tokens response: ', countTokensResp);
45+
46+
// [END aiplatform_gemini_token_count]
47+
}
48+
49+
countTokens(...process.argv.slice(2)).catch(err => {
50+
console.error(err.message);
51+
process.exitCode = 1;
52+
});
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
const {VertexAI} = require('@google-cloud/vertexai');
16+
17+
function wait(time) {
18+
return new Promise(resolve => {
19+
setTimeout(resolve, time);
20+
});
21+
}
22+
23+
async function createNonStreamingChat(
24+
projectId = 'PROJECT_ID',
25+
location = 'LOCATION_ID',
26+
model = 'MODEL'
27+
) {
28+
// TODO: Find better method. Setting delay to give api time to respond, otherwise it will 404
29+
// await wait(10);
30+
31+
// [START aiplatform_gemini_multiturn_chat]
32+
/**
33+
* TODO(developer): Uncomment these variables before running the sample.
34+
*/
35+
// const projectId = 'your-project-id';
36+
// const location = 'us-central1';
37+
38+
// Initialize Vertex with your Cloud project and location
39+
const vertexAI = new VertexAI({project: projectId, location: location});
40+
41+
// Instantiate the model
42+
const generativeModel = vertexAI.preview.getGenerativeModel({
43+
model: model,
44+
});
45+
46+
const chat = generativeModel.startChat({});
47+
48+
const chatInput1 = 'Hello';
49+
console.log(`User: ${chatInput1}`);
50+
51+
const result1 = await chat.sendMessage(chatInput1);
52+
const response1 = result1.response.candidates[0].content.parts[0].text;
53+
console.log('Chat bot: ', response1);
54+
55+
const chatInput2 = 'Can you tell me a scientific fun fact?';
56+
console.log(`User: ${chatInput2}`);
57+
const result2 = await chat.sendMessage(chatInput2);
58+
const response2 = result2.response.candidates[0].content.parts[0].text;
59+
console.log('Chat bot: ', response2);
60+
61+
const chatInput3 = 'How can I learn more about that?';
62+
console.log(`User: ${chatInput3}`);
63+
const result3 = await chat.sendMessage(chatInput3);
64+
const response3 = result3.response.candidates[0].content.parts[0].text;
65+
console.log('Chat bot: ', response3);
66+
67+
// [END aiplatform_gemini_multiturn_chat]
68+
}
69+
70+
createNonStreamingChat(...process.argv.slice(2)).catch(err => {
71+
console.error(err.message);
72+
process.exitCode = 1;
73+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
const {VertexAI} = require('@google-cloud/vertexai');
16+
17+
async function createNonStreamingContent(
18+
projectId = 'PROJECT_ID',
19+
location = 'LOCATION_ID',
20+
model = 'MODEL'
21+
) {
22+
// [START aiplatform_gemini_function_calling]
23+
24+
/**
25+
* TODO(developer): Uncomment these variables before running the sample.
26+
*/
27+
// const projectId = 'your-project-id';
28+
// const location = 'us-central1';
29+
30+
// Initialize Vertex with your Cloud project and location
31+
const vertexAI = new VertexAI({project: projectId, location: location});
32+
33+
// Instantiate the model
34+
const generativeModel = vertexAI.preview.getGenerativeModel({
35+
model: model,
36+
});
37+
38+
const request = {
39+
contents: [{role: 'user', parts: [{text: 'What is Node.js?'}]}],
40+
};
41+
42+
console.log('Prompt:');
43+
console.log(request.contents[0].parts[0].text);
44+
console.log('Non-Streaming Response Text:');
45+
46+
// Create the response stream
47+
const responseStream = await generativeModel.generateContentStream(request);
48+
49+
// Wait for the response stream to complete
50+
const aggregatedResponse = await responseStream.response;
51+
52+
// Select the text from the response
53+
const fullTextResponse =
54+
aggregatedResponse.candidates[0].content.parts[0].text;
55+
56+
console.log(fullTextResponse);
57+
58+
// [END aiplatform_gemini_function_calling]
59+
}
60+
61+
createNonStreamingContent(...process.argv.slice(2)).catch(err => {
62+
console.error(err.message);
63+
process.exitCode = 1;
64+
});

0 commit comments

Comments
 (0)