From 82ce84681dc58598a015f905c67b97feb0069774 Mon Sep 17 00:00:00 2001 From: Nardos Alemu Date: Fri, 23 May 2025 20:50:56 +0000 Subject: [PATCH 1/5] feat(genai): Add generate content with routing option --- genai/go.mod | 2 +- genai/go.sum | 4 +- .../text_generation_examples_test.go | 14 +++++ .../text_generation/textgen_code_with_pdf.go | 6 +- .../textgen_config_with_txt.go | 10 ++- .../textgen_sys_instr_with_txt.go | 6 +- .../textgen_transcript_with_gcs_audio.go | 6 +- .../text_generation/textgen_with_gcs_audio.go | 6 +- .../text_generation/textgen_with_multi_img.go | 6 +- .../textgen_with_mute_video.go | 6 +- genai/text_generation/textgen_with_routing.go | 63 +++++++++++++++++++ genai/text_generation/textgen_with_txt.go | 6 +- genai/text_generation/textgen_with_txt_img.go | 6 +- .../textgen_with_txt_stream.go | 6 +- genai/text_generation/textgen_with_video.go | 6 +- .../textgen_with_youtube_video.go | 6 +- genai/tools/tools_code_exec_with_txt.go | 2 +- genai/tools/tools_func_desc_with_txt.go | 8 +-- genai/tools/tools_google_search_with_txt.go | 6 +- 19 files changed, 112 insertions(+), 63 deletions(-) create mode 100644 genai/text_generation/textgen_with_routing.go diff --git a/genai/go.mod b/genai/go.mod index a2373bf1d6..1cfac2a248 100644 --- a/genai/go.mod +++ b/genai/go.mod @@ -4,7 +4,7 @@ go 1.23.0 require ( github.com/GoogleCloudPlatform/golang-samples v0.0.0-20250201051611-5fb145d1e974 - google.golang.org/genai v0.4.0 + google.golang.org/genai v1.6.0 ) require ( diff --git a/genai/go.sum b/genai/go.sum index c1d6f9a863..8fe074ddc5 100644 --- a/genai/go.sum +++ b/genai/go.sum @@ -113,8 +113,8 @@ golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= google.golang.org/api v0.217.0 h1:GYrUtD289o4zl1AhiTZL0jvQGa2RDLyC+kX1N/lfGOU= google.golang.org/api v0.217.0/go.mod h1:qMc2E8cBAbQlRypBTBWHklNJlaZZJBwDv81B1Iu8oSI= -google.golang.org/genai v0.4.0 h1:nHLpFvp1i2nUGQ8CjIQ8j/6d3H79Echt1jiNLb9myDk= -google.golang.org/genai v0.4.0/go.mod h1:yPyKKBezIg2rqZziLhHQ5CD62HWr7sLDLc2PDzdrNVs= +google.golang.org/genai v1.6.0 h1:aG0J3QF/Ad2GsjHvY8LjRp9hiDl4hvLJN98YwkLDqFE= +google.golang.org/genai v1.6.0/go.mod h1:TyfOKRz/QyCaj6f/ZDt505x+YreXnY40l2I6k8TvgqY= google.golang.org/genproto v0.0.0-20250115164207-1a7da9e5054f h1:387Y+JbxF52bmesc8kq1NyYIp33dnxCw6eiA7JMsTmw= google.golang.org/genproto v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:0joYwWwLQh18AOj8zMYeZLjzuqcYTU3/nC5JdCvC3JI= google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA= diff --git a/genai/text_generation/text_generation_examples_test.go b/genai/text_generation/text_generation_examples_test.go index 453a57463b..f2a59b08e3 100644 --- a/genai/text_generation/text_generation_examples_test.go +++ b/genai/text_generation/text_generation_examples_test.go @@ -172,4 +172,18 @@ func TestTextGeneration(t *testing.T) { t.Error("expected non-empty output, got empty") } }) + + t.Run("generate with routing", func(t *testing.T) { + buf.Reset() + err := generateWithRouting(buf) + if err != nil { + t.Fatalf("generateWithRouting failed: %v", err) + } + + output := buf.String() + if output == "" { + t.Error("expected non-empty output, got empty") + } + }) + } diff --git a/genai/text_generation/textgen_code_with_pdf.go b/genai/text_generation/textgen_code_with_pdf.go index ded73de243..eda82fcbe1 100644 --- a/genai/text_generation/textgen_code_with_pdf.go +++ b/genai/text_generation/textgen_code_with_pdf.go @@ -51,10 +51,8 @@ func generateWithPDF(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/text_generation/textgen_config_with_txt.go b/genai/text_generation/textgen_config_with_txt.go index 04e10cdf18..dc15ea0a4c 100644 --- a/genai/text_generation/textgen_config_with_txt.go +++ b/genai/text_generation/textgen_config_with_txt.go @@ -39,8 +39,8 @@ func generateWithConfig(w io.Writer) error { contents := genai.Text("Why is the sky blue?") // See the documentation: https://googleapis.github.io/python-genai/genai.html#genai.types.GenerateContentConfig config := &genai.GenerateContentConfig{ - Temperature: genai.Ptr(0.0), - CandidateCount: genai.Ptr(int64(1)), + Temperature: genai.Ptr(float32(0.0)), + CandidateCount: int32(1), ResponseMIMEType: "application/json", } @@ -49,10 +49,8 @@ func generateWithConfig(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: // { diff --git a/genai/text_generation/textgen_sys_instr_with_txt.go b/genai/text_generation/textgen_sys_instr_with_txt.go index 69a0583560..59b08ccc8a 100644 --- a/genai/text_generation/textgen_sys_instr_with_txt.go +++ b/genai/text_generation/textgen_sys_instr_with_txt.go @@ -50,10 +50,8 @@ func generateWithSystem(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/text_generation/textgen_transcript_with_gcs_audio.go b/genai/text_generation/textgen_transcript_with_gcs_audio.go index 8b9f89aa11..e907af725f 100644 --- a/genai/text_generation/textgen_transcript_with_gcs_audio.go +++ b/genai/text_generation/textgen_transcript_with_gcs_audio.go @@ -52,10 +52,8 @@ Use speaker A, speaker B, etc. to identify speakers.`}, return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/text_generation/textgen_with_gcs_audio.go b/genai/text_generation/textgen_with_gcs_audio.go index 8b5dbc7d10..2f303fec85 100644 --- a/genai/text_generation/textgen_with_gcs_audio.go +++ b/genai/text_generation/textgen_with_gcs_audio.go @@ -53,10 +53,8 @@ Create a chapter breakdown with timestamps for key sections or topics discussed. return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/text_generation/textgen_with_multi_img.go b/genai/text_generation/textgen_with_multi_img.go index be83533ce4..c9f10a2a85 100644 --- a/genai/text_generation/textgen_with_multi_img.go +++ b/genai/text_generation/textgen_with_multi_img.go @@ -64,10 +64,8 @@ func generateWithMultiImg(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/text_generation/textgen_with_mute_video.go b/genai/text_generation/textgen_with_mute_video.go index 1591907469..ef99fdccc8 100644 --- a/genai/text_generation/textgen_with_mute_video.go +++ b/genai/text_generation/textgen_with_mute_video.go @@ -51,10 +51,8 @@ func generateWithMuteVideo(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/text_generation/textgen_with_routing.go b/genai/text_generation/textgen_with_routing.go new file mode 100644 index 0000000000..00354a7002 --- /dev/null +++ b/genai/text_generation/textgen_with_routing.go @@ -0,0 +1,63 @@ +// Copyright 2025 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 +// +// https://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. + +// Package text_generation shows examples of generating text using the GenAI SDK. +package text_generation + +// [START googlegenaisdk_textgen_with_routing] +import ( + "context" + "fmt" + "io" + + "google.golang.org/genai" +) + +// generateWithRouting shows how to generate text using a text prompt and routing configuration. +func generateWithRouting(w io.Writer) error { + ctx := context.Background() + + client, err := genai.NewClient(ctx, &genai.ClientConfig{ + HTTPOptions: genai.HTTPOptions{APIVersion: "v1beta1"}, + }) + if err != nil { + return fmt.Errorf("failed to create genai client: %w", err) + } + + generateContentConfig := &genai.GenerateContentConfig{ModelSelectionConfig: &genai.ModelSelectionConfig{FeatureSelectionPreference: genai.FeatureSelectionPreferencePrioritizeQuality}} + + resp, err := client.Models.GenerateContent(ctx, + "model-optimizer-exp-04-09", + genai.Text("How does AI work?"), + generateContentConfig, + ) + if err != nil { + return fmt.Errorf("failed to generate content: %w", err) + } + + respText := resp.Text() + if err != nil { + return fmt.Errorf("failed to convert model response to text: %w", err) + } + fmt.Fprintln(w, respText) + // Example response: + // That's a great question! Understanding how AI works can feel like ... + // ... + // **1. The Foundation: Data and Algorithms** + // ... + + return nil +} + +// [END googlegenaisdk_textgen_with_routing] diff --git a/genai/text_generation/textgen_with_txt.go b/genai/text_generation/textgen_with_txt.go index b3d2c4560b..0ac85006c0 100644 --- a/genai/text_generation/textgen_with_txt.go +++ b/genai/text_generation/textgen_with_txt.go @@ -44,10 +44,8 @@ func generateWithText(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: // That's a great question! Understanding how AI works can feel like ... diff --git a/genai/text_generation/textgen_with_txt_img.go b/genai/text_generation/textgen_with_txt_img.go index ed58832b02..e2740734f3 100644 --- a/genai/text_generation/textgen_with_txt_img.go +++ b/genai/text_generation/textgen_with_txt_img.go @@ -52,10 +52,8 @@ func generateWithTextImage(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/text_generation/textgen_with_txt_stream.go b/genai/text_generation/textgen_with_txt_stream.go index 59efe88be2..6c4762ac14 100644 --- a/genai/text_generation/textgen_with_txt_stream.go +++ b/genai/text_generation/textgen_with_txt_stream.go @@ -43,10 +43,8 @@ func generateWithTextStream(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - chunk, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + chunk := resp.Text() + fmt.Fprintln(w, chunk) } diff --git a/genai/text_generation/textgen_with_video.go b/genai/text_generation/textgen_with_video.go index 352431e38f..a4fcf98185 100644 --- a/genai/text_generation/textgen_with_video.go +++ b/genai/text_generation/textgen_with_video.go @@ -53,10 +53,8 @@ Create a chapter breakdown with timestamps for key sections or topics discussed. return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/text_generation/textgen_with_youtube_video.go b/genai/text_generation/textgen_with_youtube_video.go index b7312e3506..5051511010 100644 --- a/genai/text_generation/textgen_with_youtube_video.go +++ b/genai/text_generation/textgen_with_youtube_video.go @@ -51,10 +51,8 @@ func generateWithYTVideo(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/tools/tools_code_exec_with_txt.go b/genai/tools/tools_code_exec_with_txt.go index 6d5f7ed879..07432ff8c0 100644 --- a/genai/tools/tools_code_exec_with_txt.go +++ b/genai/tools/tools_code_exec_with_txt.go @@ -45,7 +45,7 @@ func generateWithCodeExec(w io.Writer) error { Tools: []*genai.Tool{ {CodeExecution: &genai.ToolCodeExecution{}}, }, - Temperature: genai.Ptr(0.0), + Temperature: genai.Ptr(float32(0.0)), } modelName := "gemini-2.0-flash-001" diff --git a/genai/tools/tools_func_desc_with_txt.go b/genai/tools/tools_func_desc_with_txt.go index 47c8aae758..1b752165ff 100644 --- a/genai/tools/tools_func_desc_with_txt.go +++ b/genai/tools/tools_func_desc_with_txt.go @@ -52,7 +52,7 @@ func generateWithFuncCall(w io.Writer) error { Tools: []*genai.Tool{ {FunctionDeclarations: []*genai.FunctionDeclaration{weatherFunc}}, }, - Temperature: genai.Ptr(0.0), + Temperature: genai.Ptr(float32(0.0)), } modelName := "gemini-2.0-flash-001" @@ -113,10 +113,8 @@ func generateWithFuncCall(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/tools/tools_google_search_with_txt.go b/genai/tools/tools_google_search_with_txt.go index 9214d345ce..b8bbf12315 100644 --- a/genai/tools/tools_google_search_with_txt.go +++ b/genai/tools/tools_google_search_with_txt.go @@ -52,10 +52,8 @@ func generateWithGoogleSearch(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: From e6893e6802862307aafec4aefa768f144ee3b473 Mon Sep 17 00:00:00 2001 From: Nardos Alemu Date: Fri, 23 May 2025 20:50:56 +0000 Subject: [PATCH 2/5] feat(genai): Add generate content with routing option --- genai/content_cache/contentcache_update.go | 8 ++++---- genai/content_cache/contentcache_use_with_txt.go | 6 ++---- .../ctrlgen_with_enum_schema.go | 6 ++---- .../ctrlgen_with_nullable_schema.go | 16 +++++++--------- .../ctrlgen_with_resp_schema.go | 6 ++---- 5 files changed, 17 insertions(+), 25 deletions(-) diff --git a/genai/content_cache/contentcache_update.go b/genai/content_cache/contentcache_update.go index 62ddbc6897..1c7ad775f2 100644 --- a/genai/content_cache/contentcache_update.go +++ b/genai/content_cache/contentcache_update.go @@ -38,26 +38,26 @@ func updateContentCache(w io.Writer, cacheName string) error { // Update expire time using TTL resp, err := client.Caches.Update(ctx, cacheName, &genai.UpdateCachedContentConfig{ - TTL: "36000s", + TTL: int64(36000), }) if err != nil { return fmt.Errorf("failed to update content cache exp. time with TTL: %w", err) } - fmt.Fprintf(w, "Cache expires in: %s\n", time.Until(*resp.ExpireTime)) + fmt.Fprintf(w, "Cache expires in: %s\n", time.Until(resp.ExpireTime)) // Example response: // Cache expires in: 10h0m0.005875s // Update expire time using specific time stamp inSevenDays := time.Now().Add(7 * 24 * time.Hour) resp, err = client.Caches.Update(ctx, cacheName, &genai.UpdateCachedContentConfig{ - ExpireTime: &inSevenDays, + ExpireTime: inSevenDays, }) if err != nil { return fmt.Errorf("failed to update content cache expire time: %w", err) } - fmt.Fprintf(w, "Cache expires in: %s\n", time.Until(*resp.ExpireTime)) + fmt.Fprintf(w, "Cache expires in: %s\n", time.Until(resp.ExpireTime)) // Example response: // Cache expires in: 167h59m59.80327s diff --git a/genai/content_cache/contentcache_use_with_txt.go b/genai/content_cache/contentcache_use_with_txt.go index a8b650e7cc..7cda785d2d 100644 --- a/genai/content_cache/contentcache_use_with_txt.go +++ b/genai/content_cache/contentcache_use_with_txt.go @@ -46,10 +46,8 @@ func useContentCacheWithTxt(w io.Writer, cacheName string) error { return fmt.Errorf("failed to use content cache to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/controlled_generation/ctrlgen_with_enum_schema.go b/genai/controlled_generation/ctrlgen_with_enum_schema.go index f61e3ef627..8374cba1c1 100644 --- a/genai/controlled_generation/ctrlgen_with_enum_schema.go +++ b/genai/controlled_generation/ctrlgen_with_enum_schema.go @@ -54,10 +54,8 @@ func generateWithEnumSchema(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/controlled_generation/ctrlgen_with_nullable_schema.go b/genai/controlled_generation/ctrlgen_with_nullable_schema.go index a5166f7ff3..1ea0aa21da 100644 --- a/genai/controlled_generation/ctrlgen_with_nullable_schema.go +++ b/genai/controlled_generation/ctrlgen_with_nullable_schema.go @@ -63,11 +63,11 @@ Finally, Saturday rounds off the week with sunny skies, a temperature of 80°F, Items: &genai.Schema{ Type: "object", Properties: map[string]*genai.Schema{ - "Day": {Type: "string", Nullable: true}, - "Forecast": {Type: "string", Nullable: true}, - "Temperature": {Type: "integer", Nullable: true}, - "Humidity": {Type: "string", Nullable: true}, - "Wind Speed": {Type: "integer", Nullable: true}, + "Day": {Type: "string", Nullable: genai.Ptr(true)}, + "Forecast": {Type: "string", Nullable: genai.Ptr(true)}, + "Temperature": {Type: "integer", Nullable: genai.Ptr(true)}, + "Humidity": {Type: "string", Nullable: genai.Ptr(true)}, + "Wind Speed": {Type: "integer", Nullable: genai.Ptr(true)}, }, Required: []string{"Day", "Temperature", "Forecast", "Wind Speed"}, }, @@ -81,10 +81,8 @@ Finally, Saturday rounds off the week with sunny skies, a temperature of 80°F, return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: diff --git a/genai/controlled_generation/ctrlgen_with_resp_schema.go b/genai/controlled_generation/ctrlgen_with_resp_schema.go index bfef007ee3..257675883c 100644 --- a/genai/controlled_generation/ctrlgen_with_resp_schema.go +++ b/genai/controlled_generation/ctrlgen_with_resp_schema.go @@ -66,10 +66,8 @@ func generateWithRespSchema(w io.Writer) error { return fmt.Errorf("failed to generate content: %w", err) } - respText, err := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + respText := resp.Text() + fmt.Fprintln(w, respText) // Example response: From d0321cea5e4993385af1b7d44a503808494cc03b Mon Sep 17 00:00:00 2001 From: Nardos Alemu Date: Fri, 23 May 2025 20:50:56 +0000 Subject: [PATCH 3/5] feat(genai): Add generate content with routing option --- genai/content_cache/contentcache_create_with_txt_gcs_pdf.go | 3 ++- genai/content_cache/contentcache_update.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/genai/content_cache/contentcache_create_with_txt_gcs_pdf.go b/genai/content_cache/contentcache_create_with_txt_gcs_pdf.go index c82f58c228..b8a1e7e34c 100644 --- a/genai/content_cache/contentcache_create_with_txt_gcs_pdf.go +++ b/genai/content_cache/contentcache_create_with_txt_gcs_pdf.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "io" + "time" genai "google.golang.org/genai" ) @@ -65,7 +66,7 @@ func createContentCache(w io.Writer) (string, error) { }, }, DisplayName: "example-cache", - TTL: "86400s", + TTL: time.Duration(86400), } res, err := client.Caches.Create(ctx, modelName, config) diff --git a/genai/content_cache/contentcache_update.go b/genai/content_cache/contentcache_update.go index 1c7ad775f2..68526a559e 100644 --- a/genai/content_cache/contentcache_update.go +++ b/genai/content_cache/contentcache_update.go @@ -38,7 +38,7 @@ func updateContentCache(w io.Writer, cacheName string) error { // Update expire time using TTL resp, err := client.Caches.Update(ctx, cacheName, &genai.UpdateCachedContentConfig{ - TTL: int64(36000), + TTL: time.Duration(36000), }) if err != nil { return fmt.Errorf("failed to update content cache exp. time with TTL: %w", err) From b6845ed763a726f591678ce340a326fe67cf6f19 Mon Sep 17 00:00:00 2001 From: Nardos Alemu Date: Fri, 23 May 2025 20:50:56 +0000 Subject: [PATCH 4/5] feat(genai): Add generate content with routing option --- genai/content_cache/contentcache_create_with_txt_gcs_pdf.go | 2 +- genai/content_cache/contentcache_update.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/genai/content_cache/contentcache_create_with_txt_gcs_pdf.go b/genai/content_cache/contentcache_create_with_txt_gcs_pdf.go index b8a1e7e34c..3c1414ccd3 100644 --- a/genai/content_cache/contentcache_create_with_txt_gcs_pdf.go +++ b/genai/content_cache/contentcache_create_with_txt_gcs_pdf.go @@ -66,7 +66,7 @@ func createContentCache(w io.Writer) (string, error) { }, }, DisplayName: "example-cache", - TTL: time.Duration(86400), + TTL: time.Duration(time.Duration.Seconds(86400)), } res, err := client.Caches.Create(ctx, modelName, config) diff --git a/genai/content_cache/contentcache_update.go b/genai/content_cache/contentcache_update.go index 68526a559e..7b8506ee57 100644 --- a/genai/content_cache/contentcache_update.go +++ b/genai/content_cache/contentcache_update.go @@ -38,7 +38,7 @@ func updateContentCache(w io.Writer, cacheName string) error { // Update expire time using TTL resp, err := client.Caches.Update(ctx, cacheName, &genai.UpdateCachedContentConfig{ - TTL: time.Duration(36000), + TTL: time.Duration(time.Duration.Seconds(36000)), }) if err != nil { return fmt.Errorf("failed to update content cache exp. time with TTL: %w", err) From f1487b57075b32c9fb0cb88de45ab3b4c052f827 Mon Sep 17 00:00:00 2001 From: Nardos Alemu Date: Fri, 23 May 2025 20:50:56 +0000 Subject: [PATCH 5/5] feat(genai): Add generate content with routing option --- .../ctrlgen_with_enum_schema.go | 2 +- .../ctrlgen_with_nullable_schema.go | 3 ++- .../ctrlgen_with_resp_schema.go | 3 ++- .../counttoken_compute_with_txt.go | 3 ++- .../count_tokens/counttoken_resp_with_txt.go | 3 ++- genai/count_tokens/counttoken_with_txt_vid.go | 3 ++- .../text_generation/textgen_code_with_pdf.go | 3 ++- .../textgen_transcript_with_gcs_audio.go | 3 ++- .../text_generation/textgen_with_gcs_audio.go | 3 ++- .../textgen_with_mute_video.go | 3 ++- genai/text_generation/textgen_with_routing.go | 23 +++++++++++++------ genai/text_generation/textgen_with_txt_img.go | 3 ++- genai/text_generation/textgen_with_video.go | 3 ++- .../textgen_with_youtube_video.go | 3 ++- genai/tools/tools_code_exec_with_txt.go | 3 ++- genai/tools/tools_func_desc_with_txt.go | 6 +++-- genai/tools/tools_google_search_with_txt.go | 3 ++- 17 files changed, 49 insertions(+), 24 deletions(-) diff --git a/genai/controlled_generation/ctrlgen_with_enum_schema.go b/genai/controlled_generation/ctrlgen_with_enum_schema.go index 8374cba1c1..4e6dcc2f7d 100644 --- a/genai/controlled_generation/ctrlgen_with_enum_schema.go +++ b/genai/controlled_generation/ctrlgen_with_enum_schema.go @@ -39,7 +39,7 @@ func generateWithEnumSchema(w io.Writer) error { contents := []*genai.Content{ {Parts: []*genai.Part{ {Text: "What type of instrument is an oboe?"}, - }}, + }, Role: "user"}, } config := &genai.GenerateContentConfig{ ResponseMIMEType: "text/x.enum", diff --git a/genai/controlled_generation/ctrlgen_with_nullable_schema.go b/genai/controlled_generation/ctrlgen_with_nullable_schema.go index 1ea0aa21da..49ad2c492f 100644 --- a/genai/controlled_generation/ctrlgen_with_nullable_schema.go +++ b/genai/controlled_generation/ctrlgen_with_nullable_schema.go @@ -49,7 +49,8 @@ Finally, Saturday rounds off the week with sunny skies, a temperature of 80°F, contents := []*genai.Content{ {Parts: []*genai.Part{ {Text: prompt}, - }}, + }, + Role: "user"}, } config := &genai.GenerateContentConfig{ ResponseMIMEType: "application/json", diff --git a/genai/controlled_generation/ctrlgen_with_resp_schema.go b/genai/controlled_generation/ctrlgen_with_resp_schema.go index 257675883c..5ea69f98e7 100644 --- a/genai/controlled_generation/ctrlgen_with_resp_schema.go +++ b/genai/controlled_generation/ctrlgen_with_resp_schema.go @@ -57,7 +57,8 @@ func generateWithRespSchema(w io.Writer) error { contents := []*genai.Content{ {Parts: []*genai.Part{ {Text: "List a few popular cookie recipes."}, - }}, + }, + Role: "user"}, } modelName := "gemini-2.0-flash-001" diff --git a/genai/count_tokens/counttoken_compute_with_txt.go b/genai/count_tokens/counttoken_compute_with_txt.go index f684d7afb4..ebe6427f34 100644 --- a/genai/count_tokens/counttoken_compute_with_txt.go +++ b/genai/count_tokens/counttoken_compute_with_txt.go @@ -40,7 +40,8 @@ func computeWithTxt(w io.Writer) error { contents := []*genai.Content{ {Parts: []*genai.Part{ {Text: "What's the longest word in the English language?"}, - }}, + }, + Role: "user"}, } resp, err := client.Models.ComputeTokens(ctx, modelName, contents, nil) diff --git a/genai/count_tokens/counttoken_resp_with_txt.go b/genai/count_tokens/counttoken_resp_with_txt.go index b835d8d448..18e5923bc3 100644 --- a/genai/count_tokens/counttoken_resp_with_txt.go +++ b/genai/count_tokens/counttoken_resp_with_txt.go @@ -40,7 +40,8 @@ func generateTextAndCount(w io.Writer) error { contents := []*genai.Content{ {Parts: []*genai.Part{ {Text: "Why is the sky blue?"}, - }}, + }, + Role: "user"}, } resp, err := client.Models.GenerateContent(ctx, modelName, contents, nil) diff --git a/genai/count_tokens/counttoken_with_txt_vid.go b/genai/count_tokens/counttoken_with_txt_vid.go index 8bd0a5469c..e7d4f998ad 100644 --- a/genai/count_tokens/counttoken_with_txt_vid.go +++ b/genai/count_tokens/counttoken_with_txt_vid.go @@ -43,7 +43,8 @@ func countWithTxtAndVid(w io.Writer) error { FileURI: "gs://cloud-samples-data/generative-ai/video/pixel8.mp4", MIMEType: "video/mp4", }}, - }}, + }, + Role: "user"}, } resp, err := client.Models.CountTokens(ctx, modelName, contents, nil) diff --git a/genai/text_generation/textgen_code_with_pdf.go b/genai/text_generation/textgen_code_with_pdf.go index eda82fcbe1..946ce4bc8e 100644 --- a/genai/text_generation/textgen_code_with_pdf.go +++ b/genai/text_generation/textgen_code_with_pdf.go @@ -43,7 +43,8 @@ func generateWithPDF(w io.Writer) error { FileURI: "https://storage.googleapis.com/cloud-samples-data/generative-ai/text/inefficient_fibonacci_series_python_code.pdf", MIMEType: "application/pdf", }}, - }}, + }, + Role: "user"}, } resp, err := client.Models.GenerateContent(ctx, modelName, contents, nil) diff --git a/genai/text_generation/textgen_transcript_with_gcs_audio.go b/genai/text_generation/textgen_transcript_with_gcs_audio.go index e907af725f..0d6706f4d2 100644 --- a/genai/text_generation/textgen_transcript_with_gcs_audio.go +++ b/genai/text_generation/textgen_transcript_with_gcs_audio.go @@ -44,7 +44,8 @@ Use speaker A, speaker B, etc. to identify speakers.`}, FileURI: "gs://cloud-samples-data/generative-ai/audio/pixel.mp3", MIMEType: "audio/mpeg", }}, - }}, + }, + Role: "user"}, } resp, err := client.Models.GenerateContent(ctx, modelName, contents, nil) diff --git a/genai/text_generation/textgen_with_gcs_audio.go b/genai/text_generation/textgen_with_gcs_audio.go index 2f303fec85..f941599f58 100644 --- a/genai/text_generation/textgen_with_gcs_audio.go +++ b/genai/text_generation/textgen_with_gcs_audio.go @@ -45,7 +45,8 @@ Create a chapter breakdown with timestamps for key sections or topics discussed. FileURI: "gs://cloud-samples-data/generative-ai/audio/pixel.mp3", MIMEType: "audio/mpeg", }}, - }}, + }, + Role: "user"}, } resp, err := client.Models.GenerateContent(ctx, modelName, contents, nil) diff --git a/genai/text_generation/textgen_with_mute_video.go b/genai/text_generation/textgen_with_mute_video.go index ef99fdccc8..e8bd645be9 100644 --- a/genai/text_generation/textgen_with_mute_video.go +++ b/genai/text_generation/textgen_with_mute_video.go @@ -43,7 +43,8 @@ func generateWithMuteVideo(w io.Writer) error { FileURI: "gs://cloud-samples-data/generative-ai/video/ad_copy_from_video.mp4", MIMEType: "video/mp4", }}, - }}, + }, + Role: "user"}, } resp, err := client.Models.GenerateContent(ctx, modelName, contents, nil) diff --git a/genai/text_generation/textgen_with_routing.go b/genai/text_generation/textgen_with_routing.go index 00354a7002..e5e00c2c1a 100644 --- a/genai/text_generation/textgen_with_routing.go +++ b/genai/text_generation/textgen_with_routing.go @@ -28,17 +28,28 @@ import ( func generateWithRouting(w io.Writer) error { ctx := context.Background() - client, err := genai.NewClient(ctx, &genai.ClientConfig{ + clientConfig := &genai.ClientConfig{ HTTPOptions: genai.HTTPOptions{APIVersion: "v1beta1"}, - }) + } + + client, err := genai.NewClient(ctx, clientConfig) + if err != nil { return fmt.Errorf("failed to create genai client: %w", err) } - generateContentConfig := &genai.GenerateContentConfig{ModelSelectionConfig: &genai.ModelSelectionConfig{FeatureSelectionPreference: genai.FeatureSelectionPreferencePrioritizeQuality}} + modelSelectionConfig := &genai.ModelSelectionConfig{ + FeatureSelectionPreference: genai.FeatureSelectionPreferencePrioritizeQuality, + } + + generateContentConfig := &genai.GenerateContentConfig{ + ModelSelectionConfig: modelSelectionConfig, + } + + modelName := "model-optimizer-exp-04-09" resp, err := client.Models.GenerateContent(ctx, - "model-optimizer-exp-04-09", + modelName, genai.Text("How does AI work?"), generateContentConfig, ) @@ -47,9 +58,7 @@ func generateWithRouting(w io.Writer) error { } respText := resp.Text() - if err != nil { - return fmt.Errorf("failed to convert model response to text: %w", err) - } + fmt.Fprintln(w, respText) // Example response: // That's a great question! Understanding how AI works can feel like ... diff --git a/genai/text_generation/textgen_with_txt_img.go b/genai/text_generation/textgen_with_txt_img.go index e2740734f3..67966fd9bb 100644 --- a/genai/text_generation/textgen_with_txt_img.go +++ b/genai/text_generation/textgen_with_txt_img.go @@ -44,7 +44,8 @@ func generateWithTextImage(w io.Writer) error { FileURI: "gs://cloud-samples-data/generative-ai/image/scones.jpg", MIMEType: "image/jpeg", }}, - }}, + }, + Role: "user"}, } resp, err := client.Models.GenerateContent(ctx, modelName, contents, nil) diff --git a/genai/text_generation/textgen_with_video.go b/genai/text_generation/textgen_with_video.go index a4fcf98185..a4db7ac4c1 100644 --- a/genai/text_generation/textgen_with_video.go +++ b/genai/text_generation/textgen_with_video.go @@ -45,7 +45,8 @@ Create a chapter breakdown with timestamps for key sections or topics discussed. FileURI: "gs://cloud-samples-data/generative-ai/video/pixel8.mp4", MIMEType: "video/mp4", }}, - }}, + }, + Role: "user"}, } resp, err := client.Models.GenerateContent(ctx, modelName, contents, nil) diff --git a/genai/text_generation/textgen_with_youtube_video.go b/genai/text_generation/textgen_with_youtube_video.go index 5051511010..f8c62b00cc 100644 --- a/genai/text_generation/textgen_with_youtube_video.go +++ b/genai/text_generation/textgen_with_youtube_video.go @@ -43,7 +43,8 @@ func generateWithYTVideo(w io.Writer) error { FileURI: "https://www.youtube.com/watch?v=3KtWfp0UopM", MIMEType: "video/mp4", }}, - }}, + }, + Role: "user"}, } resp, err := client.Models.GenerateContent(ctx, modelName, contents, nil) diff --git a/genai/tools/tools_code_exec_with_txt.go b/genai/tools/tools_code_exec_with_txt.go index 07432ff8c0..ef8fa6d7ce 100644 --- a/genai/tools/tools_code_exec_with_txt.go +++ b/genai/tools/tools_code_exec_with_txt.go @@ -39,7 +39,8 @@ func generateWithCodeExec(w io.Writer) error { contents := []*genai.Content{ {Parts: []*genai.Part{ {Text: prompt}, - }}, + }, + Role: "user"}, } config := &genai.GenerateContentConfig{ Tools: []*genai.Tool{ diff --git a/genai/tools/tools_func_desc_with_txt.go b/genai/tools/tools_func_desc_with_txt.go index 1b752165ff..3e471e85b3 100644 --- a/genai/tools/tools_func_desc_with_txt.go +++ b/genai/tools/tools_func_desc_with_txt.go @@ -59,7 +59,8 @@ func generateWithFuncCall(w io.Writer) error { contents := []*genai.Content{ {Parts: []*genai.Part{ {Text: "What is the weather like in Boston?"}, - }}, + }, + Role: "user"}, } resp, err := client.Models.GenerateContent(ctx, modelName, contents, config) @@ -99,7 +100,8 @@ func generateWithFuncCall(w io.Writer) error { contents = []*genai.Content{ {Parts: []*genai.Part{ {Text: "What is the weather like in Boston?"}, - }}, + }, + Role: "user"}, {Parts: []*genai.Part{ {FunctionCall: funcCall}, }}, diff --git a/genai/tools/tools_google_search_with_txt.go b/genai/tools/tools_google_search_with_txt.go index b8bbf12315..6434db51d9 100644 --- a/genai/tools/tools_google_search_with_txt.go +++ b/genai/tools/tools_google_search_with_txt.go @@ -39,7 +39,8 @@ func generateWithGoogleSearch(w io.Writer) error { contents := []*genai.Content{ {Parts: []*genai.Part{ {Text: "When is the next total solar eclipse in the United States?"}, - }}, + }, + Role: "user"}, } config := &genai.GenerateContentConfig{ Tools: []*genai.Tool{