geminize 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 251a4ad929a96e4773c21c159849ec415c8ee32269e3a1cda100effeda96d1ed
4
- data.tar.gz: 74b958a848f75a0cf700c3751a2fb596c5a22a4a65ea9b927ead0149fef255e7
3
+ metadata.gz: 86fb5e9a612c451c27419e3c7d17f707ed337b9f38283493a521123b515e0e03
4
+ data.tar.gz: 9743507bf4df70ea1292757b01bc5e7d4f4c32cf7ef899b3bd9ef63acfb7966a
5
5
  SHA512:
6
- metadata.gz: a1ec3f597e8f30eedf8fe12304497896ba98e7e35137d751a64f0d3430a4723db6d63997b8852e0794e44029d014408d070613a117ae0089290d0c8e852cb2bd
7
- data.tar.gz: cc0de3e6fa6949894ee531092ba02c0f07a4d828540fd1bf4f0b3d8c037f7e761212e4e4cc02dc35fedd2eea0ac8446c17c1f1ff601d64b5b5bbfa847b6702a4
6
+ metadata.gz: f279410c3e5b848ba9ac652b15cc78a4112da3d5ea5aab425a2257525aa16fdf42bd68e03329f91e98ebef9bfda3a72eb2dfd18db489eed10def917e2ba6dfb5
7
+ data.tar.gz: 608c8b726d586e66ed8ae8b81174509fa4b5ff9d3fae299efde0013afc6d7b91d7c25f6840b7f7d94d0a3a4a645657843c4a4d1d0bf61723761e771050e93c85
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [1.3.1] - 2025-05-17
2
+
3
+ ### Changed
4
+
5
+ - Refactored `Geminize::ModuleExtensions` and `Geminize::ModuleSafety` into the main `Geminize` module for a flatter internal structure. This change is internal and does not affect the public API.
6
+
1
7
  ## [1.3.0] - 2024-05-02
2
8
 
3
9
  ### Added
data/README.md CHANGED
@@ -311,7 +311,7 @@ weather_functions = [
311
311
  response = Geminize.generate_with_functions(
312
312
  "What's the weather in San Francisco?",
313
313
  weather_functions,
314
- "gemini-1.5-pro", # Make sure you use a model that supports function calling
314
+ "gemini-2.0-flash", # Make sure you use a model that supports function calling
315
315
  {
316
316
  temperature: 0.2,
317
317
  system_instruction: "Use the provided function to get weather information."
@@ -382,7 +382,7 @@ require 'geminize'
382
382
  # Request JSON-formatted data
383
383
  response = Geminize.generate_json(
384
384
  "List the three largest planets in our solar system with their diameters in km",
385
- "gemini-1.5-pro", # Use a model that supports JSON mode
385
+ "gemini-2.0-flash", # Use a model that supports JSON mode
386
386
  { temperature: 0.2 }
387
387
  )
388
388
 
@@ -417,7 +417,7 @@ safety_settings = [
417
417
  response = Geminize.generate_with_safety_settings(
418
418
  "Explain the concept of nuclear fission",
419
419
  safety_settings,
420
- "gemini-1.5-pro",
420
+ "gemini-2.0-flash",
421
421
  { temperature: 0.7 }
422
422
  )
423
423
 
@@ -426,7 +426,7 @@ puts response.text
426
426
  # For maximum safety (blocks most potentially harmful content)
427
427
  safe_response = Geminize.generate_text_safe(
428
428
  "Tell me about controversial political topics",
429
- "gemini-1.5-pro"
429
+ "gemini-2.0-flash"
430
430
  )
431
431
 
432
432
  puts "Safe response: #{safe_response.text}"
@@ -434,7 +434,7 @@ puts "Safe response: #{safe_response.text}"
434
434
  # For minimum filtering (blocks only the most harmful content)
435
435
  permissive_response = Geminize.generate_text_permissive(
436
436
  "Describe a controversial historical event",
437
- "gemini-1.5-pro"
437
+ "gemini-2.0-flash"
438
438
  )
439
439
 
440
440
  puts "Permissive response: #{permissive_response.text}"
@@ -554,7 +554,7 @@ models = Geminize.list_models
554
554
  puts "Available models: #{models.size}"
555
555
 
556
556
  # Get details about a specific model
557
- model = Geminize.get_model("gemini-1.5-pro")
557
+ model = Geminize.get_model("gemini-2.0-flash")
558
558
  puts "Model: #{model.display_name}"
559
559
  puts "Token limits: #{model.input_token_limit} input, #{model.output_token_limit} output"
560
560
 
@@ -8,7 +8,7 @@ require "json"
8
8
  # Configure the API key
9
9
  Geminize.configure do |config|
10
10
  config.api_key = ENV["GEMINI_API_KEY"] # Make sure to set your API key in the environment
11
- config.default_model = "gemini-1.5-pro-latest" # Use the latest model that supports function calling
11
+ config.default_model = "gemini-2.0-flash" # Use the latest model that supports function calling
12
12
  end
13
13
 
14
14
  # Define a weather function that can handle a location and unit
@@ -63,7 +63,7 @@ begin
63
63
  {source_type: "file", data: File.join(File.dirname(__FILE__), "ruby.png")}, # Use relative path from script
64
64
  {source_type: "file", data: File.join(File.dirname(__FILE__), "ruby.png")} # Use relative path from script
65
65
  ],
66
- "gemini-1.5-pro-latest", # Explicitly specify model
66
+ "gemini-2.0-flash", # Explicitly specify model
67
67
  max_tokens: 500
68
68
  )
69
69
 
@@ -106,7 +106,7 @@ begin
106
106
  # Create a content request
107
107
  request = Geminize::Models::ContentRequest.new(
108
108
  "Tell me about these images:",
109
- "gemini-1.5-pro-latest",
109
+ "gemini-2.0-flash",
110
110
  temperature: 0.3,
111
111
  max_tokens: 800
112
112
  )
@@ -7,7 +7,7 @@ require "geminize"
7
7
  # Configure the API key
8
8
  Geminize.configure do |config|
9
9
  config.api_key = ENV["GEMINI_API_KEY"] # Make sure to set your API key in the environment
10
- config.default_model = "gemini-1.5-pro-latest" # Use the latest model
10
+ config.default_model = "gemini-2.0-flash" # Use the latest model
11
11
  end
12
12
 
13
13
  # A prompt that might trigger safety filters
@@ -104,7 +104,7 @@ module Geminize
104
104
  # @return [Geminize::Models::Model] The model information
105
105
  # @raise [Geminize::GeminizeError] If the request fails or model is not found
106
106
  def get_model(model_name, force_refresh: false)
107
- # Handle both formats: "models/gemini-1.5-pro" or just "gemini-1.5-pro"
107
+ # Handle both formats: "models/gemini-2.0-flash" or just "gemini-2.0-flash"
108
108
  unless model_name.start_with?("models/")
109
109
  model_name = "models/#{model_name}"
110
110
  end
@@ -68,7 +68,7 @@ module Geminize
68
68
  # @param model_name [String] The model name or ID to get info for
69
69
  # @return [String] The complete API endpoint path for getting model info
70
70
  def build_get_model_endpoint(model_name)
71
- # Handle both formats: "models/gemini-1.5-pro" or just "gemini-1.5-pro"
71
+ # Handle both formats: "models/gemini-2.0-flash" or just "gemini-2.0-flash"
72
72
  unless model_name.start_with?("models/")
73
73
  model_name = "models/#{model_name}"
74
74
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Geminize
4
- VERSION = "1.3.0"
4
+ VERSION = "1.3.1"
5
5
  end
data/lib/geminize.rb CHANGED
@@ -48,8 +48,6 @@ require_relative "geminize/model_info"
48
48
  require_relative "geminize/models/content_request_extensions"
49
49
  require_relative "geminize/models/content_response_extensions"
50
50
  require_relative "geminize/models/content_request_safety"
51
- require_relative "geminize/module_extensions"
52
- require_relative "geminize/module_safety"
53
51
 
54
52
  # Main module for the Geminize gem
55
53
  module Geminize
@@ -101,7 +99,7 @@ module Geminize
101
99
  # Geminize.configure do |config|
102
100
  # config.api_key = "your-api-key"
103
101
  # config.api_version = "v1beta"
104
- # config.default_model = "gemini-1.5-pro-latest"
102
+ # config.default_model = "gemini-2.0-flash"
105
103
  # end
106
104
  def configure
107
105
  yield(configuration) if block_given?
@@ -517,7 +515,7 @@ module Geminize
517
515
  end
518
516
 
519
517
  # Get information about a specific model
520
- # @param model_name [String] The model name to retrieve (can be "models/gemini-1.5-pro" or just "gemini-1.5-pro")
518
+ # @param model_name [String] The model name to retrieve (can be "models/gemini-2.0-flash" or just "gemini-2.0-flash")
521
519
  # @param force_refresh [Boolean] Force a refresh from the API instead of using cache
522
520
  # @param client_options [Hash] Options to pass to the client
523
521
  # @return [Geminize::Models::Model] The model information
@@ -591,5 +589,413 @@ module Geminize
591
589
  validate_configuration!
592
590
  conversation_service.update_conversation_system_instruction(id, system_instruction)
593
591
  end
592
+
593
+ # Generate text with custom safety settings
594
+ # @param prompt [String] The input prompt
595
+ # @param safety_settings [Array<Hash>] Array of safety setting definitions
596
+ # @param model_name [String, nil] The model to use (optional)
597
+ # @param params [Hash] Additional generation parameters
598
+ # @option params [Float] :temperature Controls randomness (0.0-1.0)
599
+ # @option params [Integer] :max_tokens Maximum tokens to generate
600
+ # @option params [Float] :top_p Top-p value for nucleus sampling (0.0-1.0)
601
+ # @option params [Integer] :top_k Top-k value for sampling
602
+ # @option params [Array<String>] :stop_sequences Stop sequences to end generation
603
+ # @option params [String] :system_instruction System instruction to guide model behavior
604
+ # @option params [Boolean] :with_retries Enable retries for transient errors (default: true)
605
+ # @option params [Integer] :max_retries Maximum retry attempts (default: 3)
606
+ # @option params [Float] :retry_delay Initial delay between retries in seconds (default: 1.0)
607
+ # @option params [Hash] :client_options Options to pass to the client
608
+ # @return [Geminize::Models::ContentResponse] The generation response
609
+ # @raise [Geminize::GeminizeError] If the request fails
610
+ # @example Generate text with specific safety settings
611
+ # Geminize.generate_with_safety_settings(
612
+ # "Tell me a scary story",
613
+ # [
614
+ # {category: "HARM_CATEGORY_DANGEROUS_CONTENT", threshold: "BLOCK_MEDIUM_AND_ABOVE"},
615
+ # {category: "HARM_CATEGORY_HATE_SPEECH", threshold: "BLOCK_LOW_AND_ABOVE"}
616
+ # ]
617
+ # )
618
+ def generate_with_safety_settings(prompt, safety_settings, model_name = nil, params = {})
619
+ validate_configuration!
620
+
621
+ # Extract special options
622
+ with_retries = params.delete(:with_retries) != false # Default to true
623
+ max_retries = params.delete(:max_retries) || 3
624
+ retry_delay = params.delete(:retry_delay) || 1.0
625
+ client_options = params.delete(:client_options) || {}
626
+
627
+ # Create the generator and content request
628
+ generator = TextGeneration.new(nil, client_options)
629
+ content_request = Models::ContentRequest.new(
630
+ prompt,
631
+ model_name || configuration.default_model,
632
+ params
633
+ )
634
+
635
+ # Add safety settings to the request
636
+ safety_settings.each do |setting|
637
+ content_request.add_safety_setting(
638
+ setting[:category],
639
+ setting[:threshold]
640
+ )
641
+ end
642
+
643
+ # Generate with or without retries
644
+ if with_retries
645
+ generator.generate_with_retries(content_request, max_retries, retry_delay)
646
+ else
647
+ generator.generate(content_request)
648
+ end
649
+ end
650
+
651
+ # Generate text with maximum safety (blocks most potentially harmful content)
652
+ # @param prompt [String] The input prompt
653
+ # @param model_name [String, nil] The model to use (optional)
654
+ # @param params [Hash] Additional generation parameters
655
+ # @return [Geminize::Models::ContentResponse] The generation response
656
+ # @raise [Geminize::GeminizeError] If the request fails
657
+ # @example Generate text with maximum safety
658
+ # Geminize.generate_text_safe("Tell me about conflicts", nil, temperature: 0.7)
659
+ def generate_text_safe(prompt, model_name = nil, params = {})
660
+ validate_configuration!
661
+
662
+ # Extract special options
663
+ with_retries = params.delete(:with_retries) != false # Default to true
664
+ max_retries = params.delete(:max_retries) || 3
665
+ retry_delay = params.delete(:retry_delay) || 1.0
666
+ client_options = params.delete(:client_options) || {}
667
+
668
+ # Create the generator and content request
669
+ generator = TextGeneration.new(nil, client_options)
670
+ content_request = Models::ContentRequest.new(
671
+ prompt,
672
+ model_name || configuration.default_model,
673
+ params
674
+ )
675
+
676
+ # Set maximum safety (block low and above)
677
+ content_request.block_all_harmful_content
678
+
679
+ # Generate with or without retries
680
+ if with_retries
681
+ generator.generate_with_retries(content_request, max_retries, retry_delay)
682
+ else
683
+ generator.generate(content_request)
684
+ end
685
+ end
686
+
687
+ # Generate text with minimum safety (blocks only high-risk content)
688
+ # @param prompt [String] The input prompt
689
+ # @param model_name [String, nil] The model to use (optional)
690
+ # @param params [Hash] Additional generation parameters
691
+ # @return [Geminize::Models::ContentResponse] The generation response
692
+ # @raise [Geminize::GeminizeError] If the request fails
693
+ # @example Generate text with minimum safety
694
+ # Geminize.generate_text_permissive("Tell me about conflicts", nil, temperature: 0.7)
695
+ def generate_text_permissive(prompt, model_name = nil, params = {})
696
+ validate_configuration!
697
+
698
+ # Extract special options
699
+ with_retries = params.delete(:with_retries) != false # Default to true
700
+ max_retries = params.delete(:max_retries) || 3
701
+ retry_delay = params.delete(:retry_delay) || 1.0
702
+ client_options = params.delete(:client_options) || {}
703
+
704
+ # Create the generator and content request
705
+ generator = TextGeneration.new(nil, client_options)
706
+ content_request = Models::ContentRequest.new(
707
+ prompt,
708
+ model_name || configuration.default_model,
709
+ params
710
+ )
711
+
712
+ # Set minimum safety (block only high risk)
713
+ content_request.block_only_high_risk_content
714
+
715
+ # Generate with or without retries
716
+ if with_retries
717
+ generator.generate_with_retries(content_request, max_retries, retry_delay)
718
+ else
719
+ generator.generate(content_request)
720
+ end
721
+ end
722
+
723
+ # Generate text with function calling capabilities
724
+ # @param prompt [String] The input prompt
725
+ # @param functions [Array<Hash>] Array of function definitions
726
+ # @param model_name [String, nil] The model to use, defaults to the configured default model
727
+ # @param params [Hash] Additional parameters for generation
728
+ # @option params [Float] :temperature Controls randomness (0.0-1.0)
729
+ # @option params [Integer] :max_tokens Maximum tokens to generate
730
+ # @option params [Float] :top_p Top-p value for nucleus sampling (0.0-1.0)
731
+ # @option params [Integer] :top_k Top-k value for sampling
732
+ # @option params [Array<String>] :stop_sequences Stop sequences to end generation
733
+ # @option params [String] :system_instruction System instruction to guide model behavior
734
+ # @option params [String] :tool_execution_mode Tool execution mode ("AUTO", "MANUAL", or "NONE")
735
+ # @param with_retries [Boolean] Whether to retry the generation if it fails
736
+ # @param max_retries [Integer] Maximum number of retries
737
+ # @param retry_delay [Float] Delay between retries in seconds
738
+ # @param client_options [Hash] Options for the HTTP client
739
+ # @return [Geminize::Models::ContentResponse] The generated response
740
+ # @raise [Geminize::Error] If the generation fails
741
+ # @example Generate text with a function call
742
+ # Geminize.generate_with_functions(
743
+ # "What's the weather in New York?",
744
+ # [
745
+ # {
746
+ # name: "get_weather",
747
+ # description: "Get the current weather in a location",
748
+ # parameters: {
749
+ # type: "object",
750
+ # properties: {
751
+ # location: {
752
+ # type: "string",
753
+ # description: "The city and state, e.g. New York, NY"
754
+ # },
755
+ # unit: {
756
+ # type: "string",
757
+ # enum: ["celsius", "fahrenheit"],
758
+ # description: "The unit of temperature"
759
+ # }
760
+ # },
761
+ # required: ["location"]
762
+ # }
763
+ # }
764
+ # ]
765
+ # )
766
+ def generate_with_functions(prompt, functions, model_name = nil, params = {}, with_retries: true, max_retries: 3, retry_delay: 1.0, client_options: nil)
767
+ validate_configuration!
768
+
769
+ # Initialize the generator
770
+ client = client_options ? Client.new(client_options) : Client.new
771
+ generator = TextGeneration.new(client)
772
+
773
+ # Parse functions
774
+ if functions.nil? || !functions.is_a?(Array) || functions.empty?
775
+ raise Geminize::ValidationError.new(
776
+ "Functions must be a non-empty array",
777
+ "INVALID_ARGUMENT"
778
+ )
779
+ end
780
+
781
+ # Set up params with defaults
782
+ generation_params = params.dup
783
+ tool_execution_mode = generation_params.delete(:tool_execution_mode) || "AUTO"
784
+ with_retries = generation_params.delete(:with_retries) != false if generation_params.key?(:with_retries)
785
+
786
+ # Enhance the system instruction to ensure function calling
787
+ generation_params[:system_instruction] ||= ""
788
+ generation_params[:system_instruction] = "You are a helpful assistant. When you encounter a question that you can answer by calling a function, you must always use the provided function. Always respond using the function call format, not with your own text. " + generation_params[:system_instruction]
789
+
790
+ # Create the request
791
+ content_request = Models::ContentRequest.new(
792
+ prompt,
793
+ model_name || configuration.default_model,
794
+ generation_params
795
+ )
796
+
797
+ # Add functions to the request
798
+ functions.each do |function|
799
+ content_request.add_function(
800
+ function[:name],
801
+ function[:description],
802
+ function[:parameters]
803
+ )
804
+ end
805
+
806
+ # Set the tool config
807
+ content_request.set_tool_config(tool_execution_mode)
808
+
809
+ # Generate the response
810
+ if with_retries
811
+ generator.generate_with_retries(content_request, max_retries, retry_delay)
812
+ else
813
+ generator.generate(content_request)
814
+ end
815
+ end
816
+
817
+ # Generate JSON output from a prompt using the Gemini API
818
+ # @param prompt [String] The input prompt
819
+ # @param model_name [String, nil] The model to use, defaults to the configured default model
820
+ # @param params [Hash] Additional parameters for generation
821
+ # @option params [Float] :temperature Controls randomness (0.0-1.0)
822
+ # @option params [Integer] :max_tokens Maximum tokens to generate
823
+ # @option params [Float] :top_p Top-p value for nucleus sampling (0.0-1.0)
824
+ # @option params [Integer] :top_k Top-k value for sampling
825
+ # @option params [Array<String>] :stop_sequences Stop sequences to end generation
826
+ # @option params [String] :system_instruction System instruction to guide model behavior
827
+ # @param with_retries [Boolean] Whether to retry the generation if it fails
828
+ # @param max_retries [Integer] Maximum number of retries
829
+ # @param retry_delay [Float] Delay between retries in seconds
830
+ # @param client_options [Hash] Options for the HTTP client
831
+ # @option params [Hash] :json_schema Schema for the JSON output (optional)
832
+ # @return [Geminize::Models::ContentResponse] The generated response with JSON content
833
+ # @raise [Geminize::Error] If the generation fails
834
+ # @example Generate JSON output
835
+ # response = Geminize.generate_json(
836
+ # "List 3 planets with their diameter",
837
+ # nil,
838
+ # system_instruction: "Return the information as a JSON array"
839
+ # )
840
+ # planets = response.json_response # Returns parsed JSON
841
+ def generate_json(prompt, model_name = nil, params = {}, with_retries: true, max_retries: 3, retry_delay: 1.0, client_options: nil)
842
+ validate_configuration!
843
+
844
+ # Initialize the generator
845
+ client = client_options ? Client.new(client_options) : Client.new
846
+ generator = TextGeneration.new(client)
847
+
848
+ # Set up params with defaults
849
+ generation_params = params.dup
850
+ with_retries = generation_params.delete(:with_retries) != false if generation_params.key?(:with_retries)
851
+
852
+ # Enhance the system instruction for JSON output
853
+ generation_params[:system_instruction] ||= ""
854
+ generation_params[:system_instruction] = "You must respond with valid JSON only, with no explanation or other text. " + generation_params[:system_instruction]
855
+
856
+ # Create the request
857
+ content_request = Models::ContentRequest.new(
858
+ prompt,
859
+ model_name || configuration.default_model,
860
+ generation_params
861
+ )
862
+
863
+ # Enable JSON mode
864
+ content_request.enable_json_mode
865
+
866
+ # Generate the response
867
+ if with_retries
868
+ generator.generate_with_retries(content_request, max_retries, retry_delay)
869
+ else
870
+ generator.generate(content_request)
871
+ end
872
+ end
873
+
874
+ # Process a function call by executing a provided block and returning the result to Gemini
875
+ # @param response [Geminize::Models::ContentResponse] The response containing a function call
876
+ # @param model_name [String, nil] The model to use for the followup, defaults to the configured default model
877
+ # @param with_retries [Boolean] Whether to retry the generation if it fails
878
+ # @param max_retries [Integer] Maximum number of retries
879
+ # @param retry_delay [Float] Delay between retries in seconds
880
+ # @param client_options [Hash] Options for the HTTP client
881
+ # @yield [function_name, args] Block to execute the function
882
+ # @yieldparam function_name [String] The name of the function to execute
883
+ # @yieldparam args [Hash] The arguments to pass to the function
884
+ # @yieldreturn [Hash, Array, String, Numeric, Boolean, nil] The result of the function
885
+ # @return [Geminize::Models::ContentResponse] The response after processing the function
886
+ # @raise [Geminize::Error] If processing fails
887
+ # @example Process a function call
888
+ # response = Geminize.generate_with_functions("What's the weather in New York?", [...])
889
+ # if response.has_function_call?
890
+ # final_response = Geminize.process_function_call(response) do |function_name, args|
891
+ # if function_name == "get_weather"
892
+ # # Call a real weather API here
893
+ # { temperature: 72, conditions: "sunny" }
894
+ # end
895
+ # end
896
+ # puts final_response.text
897
+ # end
898
+ def process_function_call(response, model_name = nil, with_retries: true, max_retries: 3, retry_delay: 1.0, client_options: nil)
899
+ validate_configuration!
900
+
901
+ # Ensure a block is provided
902
+ unless block_given?
903
+ raise Geminize::ValidationError.new(
904
+ "A block must be provided to process the function call",
905
+ "INVALID_ARGUMENT"
906
+ )
907
+ end
908
+
909
+ # Ensure the response has a function call
910
+ unless response.has_function_call?
911
+ raise Geminize::ValidationError.new(
912
+ "The response does not contain a function call",
913
+ "INVALID_ARGUMENT"
914
+ )
915
+ end
916
+
917
+ # Extract function call information
918
+ function_call = response.function_call
919
+ function_name = function_call.name
920
+ function_args = function_call.response
921
+
922
+ # Call the provided block with the function information
923
+ result = yield(function_name, function_args)
924
+
925
+ # Create a function response
926
+ Models::FunctionResponse.new(function_name, result)
927
+
928
+ # Initialize the generator
929
+ client = client_options ? Client.new(client_options) : Client.new
930
+ generator = TextGeneration.new(client)
931
+
932
+ # Create a request with the function result
933
+ content_request = Models::ContentRequest.new(
934
+ "Function #{function_name} returned: #{result.inspect}",
935
+ model_name || configuration.default_model
936
+ )
937
+
938
+ # Generate the response
939
+ if with_retries
940
+ generator.generate_with_retries(content_request, max_retries, retry_delay)
941
+ else
942
+ generator.generate(content_request)
943
+ end
944
+ end
945
+
946
+ # Generate text with code execution capabilities
947
+ # @param prompt [String] The input prompt
948
+ # @param model_name [String, nil] The model to use, defaults to the configured default model
949
+ # @param params [Hash] Additional parameters for generation
950
+ # @option params [Float] :temperature Controls randomness (0.0-1.0)
951
+ # @option params [Integer] :max_tokens Maximum tokens to generate
952
+ # @option params [Float] :top_p Top-p value for nucleus sampling (0.0-1.0)
953
+ # @option params [Integer] :top_k Top-k value for sampling
954
+ # @option params [Array<String>] :stop_sequences Stop sequences to end generation
955
+ # @option params [String] :system_instruction System instruction to guide model behavior
956
+ # @param with_retries [Boolean] Whether to retry the generation if it fails
957
+ # @param max_retries [Integer] Maximum number of retries
958
+ # @param retry_delay [Float] Delay between retries in seconds
959
+ # @param client_options [Hash] Options for the HTTP client
960
+ # @return [Geminize::Models::ContentResponse] The generated response
961
+ # @raise [Geminize::Error] If the generation fails
962
+ # @example Generate text with code execution
963
+ # Geminize.generate_with_code_execution(
964
+ # "What is the sum of the first 50 prime numbers?",
965
+ # nil,
966
+ # { temperature: 0.2 }
967
+ # )
968
+ def generate_with_code_execution(prompt, model_name = nil, params = {}, with_retries: true, max_retries: 3, retry_delay: 1.0, client_options: nil)
969
+ validate_configuration!
970
+
971
+ # Initialize the generator
972
+ client = client_options ? Client.new(client_options) : Client.new
973
+ generator = TextGeneration.new(client)
974
+
975
+ # Set up params with defaults
976
+ generation_params = params.dup
977
+ with_retries = generation_params.delete(:with_retries) != false if generation_params.key?(:with_retries)
978
+
979
+ # Enhance the system instruction to ensure code execution is effective
980
+ generation_params[:system_instruction] ||= ""
981
+ generation_params[:system_instruction] = "You are a helpful assistant with the ability to generate and execute Python code. When appropriate, use code to solve problems or complete tasks. " + generation_params[:system_instruction]
982
+
983
+ # Create the request
984
+ content_request = Models::ContentRequest.new(
985
+ prompt,
986
+ model_name || configuration.default_model,
987
+ generation_params
988
+ )
989
+
990
+ # Enable code execution
991
+ content_request.enable_code_execution
992
+
993
+ # Generate the response
994
+ if with_retries
995
+ generator.generate_with_retries(content_request, max_retries, retry_delay)
996
+ else
997
+ generator.generate(content_request)
998
+ end
999
+ end
594
1000
  end
595
1001
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geminize
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nhat Long Nguyen
@@ -225,8 +225,6 @@ files:
225
225
  - lib/geminize/models/stream_response.rb
226
226
  - lib/geminize/models/tool.rb
227
227
  - lib/geminize/models/tool_config.rb
228
- - lib/geminize/module_extensions.rb
229
- - lib/geminize/module_safety.rb
230
228
  - lib/geminize/request_builder.rb
231
229
  - lib/geminize/text_generation.rb
232
230
  - lib/geminize/validators.rb
@@ -1,283 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Geminize
4
- class << self
5
- # Generate text with function calling capabilities
6
- # @param prompt [String] The input prompt
7
- # @param functions [Array<Hash>] Array of function definitions
8
- # @param model_name [String, nil] The model to use, defaults to the configured default model
9
- # @param params [Hash] Additional parameters for generation
10
- # @option params [Float] :temperature Controls randomness (0.0-1.0)
11
- # @option params [Integer] :max_tokens Maximum tokens to generate
12
- # @option params [Float] :top_p Top-p value for nucleus sampling (0.0-1.0)
13
- # @option params [Integer] :top_k Top-k value for sampling
14
- # @option params [Array<String>] :stop_sequences Stop sequences to end generation
15
- # @option params [String] :system_instruction System instruction to guide model behavior
16
- # @option params [String] :tool_execution_mode Tool execution mode ("AUTO", "MANUAL", or "NONE")
17
- # @param with_retries [Boolean] Whether to retry the generation if it fails
18
- # @param max_retries [Integer] Maximum number of retries
19
- # @param retry_delay [Float] Delay between retries in seconds
20
- # @param client_options [Hash] Options for the HTTP client
21
- # @return [Geminize::Models::ContentResponse] The generated response
22
- # @raise [Geminize::Error] If the generation fails
23
- # @example Generate text with a function call
24
- # Geminize.generate_with_functions(
25
- # "What's the weather in New York?",
26
- # [
27
- # {
28
- # name: "get_weather",
29
- # description: "Get the current weather in a location",
30
- # parameters: {
31
- # type: "object",
32
- # properties: {
33
- # location: {
34
- # type: "string",
35
- # description: "The city and state, e.g. New York, NY"
36
- # },
37
- # unit: {
38
- # type: "string",
39
- # enum: ["celsius", "fahrenheit"],
40
- # description: "The unit of temperature"
41
- # }
42
- # },
43
- # required: ["location"]
44
- # }
45
- # }
46
- # ]
47
- # )
48
- def generate_with_functions(prompt, functions, model_name = nil, params = {}, with_retries: true, max_retries: 3, retry_delay: 1.0, client_options: nil)
49
- validate_configuration!
50
-
51
- # Initialize the generator
52
- client = client_options ? Client.new(client_options) : Client.new
53
- generator = TextGeneration.new(client)
54
-
55
- # Parse functions
56
- if functions.nil? || !functions.is_a?(Array) || functions.empty?
57
- raise Geminize::ValidationError.new(
58
- "Functions must be a non-empty array",
59
- "INVALID_ARGUMENT"
60
- )
61
- end
62
-
63
- # Set up params with defaults
64
- generation_params = params.dup
65
- tool_execution_mode = generation_params.delete(:tool_execution_mode) || "AUTO"
66
- with_retries = generation_params.delete(:with_retries) != false if generation_params.key?(:with_retries)
67
-
68
- # Enhance the system instruction to ensure function calling
69
- generation_params[:system_instruction] ||= ""
70
- generation_params[:system_instruction] = "You are a helpful assistant. When you encounter a question that you can answer by calling a function, you must always use the provided function. Always respond using the function call format, not with your own text. " + generation_params[:system_instruction]
71
-
72
- # Create the request
73
- content_request = Models::ContentRequest.new(
74
- prompt,
75
- model_name || configuration.default_model,
76
- generation_params
77
- )
78
-
79
- # Add functions to the request
80
- functions.each do |function|
81
- content_request.add_function(
82
- function[:name],
83
- function[:description],
84
- function[:parameters]
85
- )
86
- end
87
-
88
- # Set the tool config
89
- content_request.set_tool_config(tool_execution_mode)
90
-
91
- # Generate the response
92
- if with_retries
93
- generator.generate_with_retries(content_request, max_retries, retry_delay)
94
- else
95
- generator.generate(content_request)
96
- end
97
- end
98
-
99
- # Generate JSON output from a prompt using the Gemini API
100
- # @param prompt [String] The input prompt
101
- # @param model_name [String, nil] The model to use, defaults to the configured default model
102
- # @param params [Hash] Additional parameters for generation
103
- # @option params [Float] :temperature Controls randomness (0.0-1.0)
104
- # @option params [Integer] :max_tokens Maximum tokens to generate
105
- # @option params [Float] :top_p Top-p value for nucleus sampling (0.0-1.0)
106
- # @option params [Integer] :top_k Top-k value for sampling
107
- # @option params [Array<String>] :stop_sequences Stop sequences to end generation
108
- # @option params [String] :system_instruction System instruction to guide model behavior
109
- # @param with_retries [Boolean] Whether to retry the generation if it fails
110
- # @param max_retries [Integer] Maximum number of retries
111
- # @param retry_delay [Float] Delay between retries in seconds
112
- # @param client_options [Hash] Options for the HTTP client
113
- # @option params [Hash] :json_schema Schema for the JSON output (optional)
114
- # @return [Geminize::Models::ContentResponse] The generated response with JSON content
115
- # @raise [Geminize::Error] If the generation fails
116
- # @example Generate JSON output
117
- # response = Geminize.generate_json(
118
- # "List 3 planets with their diameter",
119
- # nil,
120
- # system_instruction: "Return the information as a JSON array"
121
- # )
122
- # planets = response.json_response # Returns parsed JSON
123
- def generate_json(prompt, model_name = nil, params = {}, with_retries: true, max_retries: 3, retry_delay: 1.0, client_options: nil)
124
- validate_configuration!
125
-
126
- # Initialize the generator
127
- client = client_options ? Client.new(client_options) : Client.new
128
- generator = TextGeneration.new(client)
129
-
130
- # Set up params with defaults
131
- generation_params = params.dup
132
- with_retries = generation_params.delete(:with_retries) != false if generation_params.key?(:with_retries)
133
-
134
- # Enhance the system instruction for JSON output
135
- generation_params[:system_instruction] ||= ""
136
- generation_params[:system_instruction] = "You must respond with valid JSON only, with no explanation or other text. " + generation_params[:system_instruction]
137
-
138
- # Create the request
139
- content_request = Models::ContentRequest.new(
140
- prompt,
141
- model_name || configuration.default_model,
142
- generation_params
143
- )
144
-
145
- # Enable JSON mode
146
- content_request.enable_json_mode
147
-
148
- # Generate the response
149
- if with_retries
150
- generator.generate_with_retries(content_request, max_retries, retry_delay)
151
- else
152
- generator.generate(content_request)
153
- end
154
- end
155
-
156
- # Process a function call by executing a provided block and returning the result to Gemini
157
- # @param response [Geminize::Models::ContentResponse] The response containing a function call
158
- # @param model_name [String, nil] The model to use for the followup, defaults to the configured default model
159
- # @param with_retries [Boolean] Whether to retry the generation if it fails
160
- # @param max_retries [Integer] Maximum number of retries
161
- # @param retry_delay [Float] Delay between retries in seconds
162
- # @param client_options [Hash] Options for the HTTP client
163
- # @yield [function_name, args] Block to execute the function
164
- # @yieldparam function_name [String] The name of the function to execute
165
- # @yieldparam args [Hash] The arguments to pass to the function
166
- # @yieldreturn [Hash, Array, String, Numeric, Boolean, nil] The result of the function
167
- # @return [Geminize::Models::ContentResponse] The response after processing the function
168
- # @raise [Geminize::Error] If processing fails
169
- # @example Process a function call
170
- # response = Geminize.generate_with_functions("What's the weather in New York?", [...])
171
- # if response.has_function_call?
172
- # final_response = Geminize.process_function_call(response) do |function_name, args|
173
- # if function_name == "get_weather"
174
- # # Call a real weather API here
175
- # { temperature: 72, conditions: "sunny" }
176
- # end
177
- # end
178
- # puts final_response.text
179
- # end
180
- def process_function_call(response, model_name = nil, with_retries: true, max_retries: 3, retry_delay: 1.0, client_options: nil)
181
- validate_configuration!
182
-
183
- # Ensure a block is provided
184
- unless block_given?
185
- raise Geminize::ValidationError.new(
186
- "A block must be provided to process the function call",
187
- "INVALID_ARGUMENT"
188
- )
189
- end
190
-
191
- # Ensure the response has a function call
192
- unless response.has_function_call?
193
- raise Geminize::ValidationError.new(
194
- "The response does not contain a function call",
195
- "INVALID_ARGUMENT"
196
- )
197
- end
198
-
199
- # Extract function call information
200
- function_call = response.function_call
201
- function_name = function_call.name
202
- function_args = function_call.response
203
-
204
- # Call the provided block with the function information
205
- result = yield(function_name, function_args)
206
-
207
- # Create a function response
208
- Models::FunctionResponse.new(function_name, result)
209
-
210
- # Initialize the generator
211
- client = client_options ? Client.new(client_options) : Client.new
212
- generator = TextGeneration.new(client)
213
-
214
- # Create a request with the function result
215
- content_request = Models::ContentRequest.new(
216
- "Function #{function_name} returned: #{result.inspect}",
217
- model_name || configuration.default_model
218
- )
219
-
220
- # Generate the response
221
- if with_retries
222
- generator.generate_with_retries(content_request, max_retries, retry_delay)
223
- else
224
- generator.generate(content_request)
225
- end
226
- end
227
-
228
- # Generate text with code execution capabilities
229
- # @param prompt [String] The input prompt
230
- # @param model_name [String, nil] The model to use, defaults to the configured default model
231
- # @param params [Hash] Additional parameters for generation
232
- # @option params [Float] :temperature Controls randomness (0.0-1.0)
233
- # @option params [Integer] :max_tokens Maximum tokens to generate
234
- # @option params [Float] :top_p Top-p value for nucleus sampling (0.0-1.0)
235
- # @option params [Integer] :top_k Top-k value for sampling
236
- # @option params [Array<String>] :stop_sequences Stop sequences to end generation
237
- # @option params [String] :system_instruction System instruction to guide model behavior
238
- # @param with_retries [Boolean] Whether to retry the generation if it fails
239
- # @param max_retries [Integer] Maximum number of retries
240
- # @param retry_delay [Float] Delay between retries in seconds
241
- # @param client_options [Hash] Options for the HTTP client
242
- # @return [Geminize::Models::ContentResponse] The generated response
243
- # @raise [Geminize::Error] If the generation fails
244
- # @example Generate text with code execution
245
- # Geminize.generate_with_code_execution(
246
- # "What is the sum of the first 50 prime numbers?",
247
- # nil,
248
- # { temperature: 0.2 }
249
- # )
250
- def generate_with_code_execution(prompt, model_name = nil, params = {}, with_retries: true, max_retries: 3, retry_delay: 1.0, client_options: nil)
251
- validate_configuration!
252
-
253
- # Initialize the generator
254
- client = client_options ? Client.new(client_options) : Client.new
255
- generator = TextGeneration.new(client)
256
-
257
- # Set up params with defaults
258
- generation_params = params.dup
259
- with_retries = generation_params.delete(:with_retries) != false if generation_params.key?(:with_retries)
260
-
261
- # Enhance the system instruction to ensure code execution is effective
262
- generation_params[:system_instruction] ||= ""
263
- generation_params[:system_instruction] = "You are a helpful assistant with the ability to generate and execute Python code. When appropriate, use code to solve problems or complete tasks. " + generation_params[:system_instruction]
264
-
265
- # Create the request
266
- content_request = Models::ContentRequest.new(
267
- prompt,
268
- model_name || configuration.default_model,
269
- generation_params
270
- )
271
-
272
- # Enable code execution
273
- content_request.enable_code_execution
274
-
275
- # Generate the response
276
- if with_retries
277
- generator.generate_with_retries(content_request, max_retries, retry_delay)
278
- else
279
- generator.generate(content_request)
280
- end
281
- end
282
- end
283
- end
@@ -1,135 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Geminize
4
- class << self
5
- # Generate text with custom safety settings
6
- # @param prompt [String] The input prompt
7
- # @param safety_settings [Array<Hash>] Array of safety setting definitions
8
- # @param model_name [String, nil] The model to use (optional)
9
- # @param params [Hash] Additional generation parameters
10
- # @option params [Float] :temperature Controls randomness (0.0-1.0)
11
- # @option params [Integer] :max_tokens Maximum tokens to generate
12
- # @option params [Float] :top_p Top-p value for nucleus sampling (0.0-1.0)
13
- # @option params [Integer] :top_k Top-k value for sampling
14
- # @option params [Array<String>] :stop_sequences Stop sequences to end generation
15
- # @option params [String] :system_instruction System instruction to guide model behavior
16
- # @option params [Boolean] :with_retries Enable retries for transient errors (default: true)
17
- # @option params [Integer] :max_retries Maximum retry attempts (default: 3)
18
- # @option params [Float] :retry_delay Initial delay between retries in seconds (default: 1.0)
19
- # @option params [Hash] :client_options Options to pass to the client
20
- # @return [Geminize::Models::ContentResponse] The generation response
21
- # @raise [Geminize::GeminizeError] If the request fails
22
- # @example Generate text with specific safety settings
23
- # Geminize.generate_with_safety_settings(
24
- # "Tell me a scary story",
25
- # [
26
- # {category: "HARM_CATEGORY_DANGEROUS_CONTENT", threshold: "BLOCK_MEDIUM_AND_ABOVE"},
27
- # {category: "HARM_CATEGORY_HATE_SPEECH", threshold: "BLOCK_LOW_AND_ABOVE"}
28
- # ]
29
- # )
30
- def generate_with_safety_settings(prompt, safety_settings, model_name = nil, params = {})
31
- validate_configuration!
32
-
33
- # Extract special options
34
- with_retries = params.delete(:with_retries) != false # Default to true
35
- max_retries = params.delete(:max_retries) || 3
36
- retry_delay = params.delete(:retry_delay) || 1.0
37
- client_options = params.delete(:client_options) || {}
38
-
39
- # Create the generator and content request
40
- generator = TextGeneration.new(nil, client_options)
41
- content_request = Models::ContentRequest.new(
42
- prompt,
43
- model_name || configuration.default_model,
44
- params
45
- )
46
-
47
- # Add safety settings to the request
48
- safety_settings.each do |setting|
49
- content_request.add_safety_setting(
50
- setting[:category],
51
- setting[:threshold]
52
- )
53
- end
54
-
55
- # Generate with or without retries
56
- if with_retries
57
- generator.generate_with_retries(content_request, max_retries, retry_delay)
58
- else
59
- generator.generate(content_request)
60
- end
61
- end
62
-
63
- # Generate text with maximum safety (blocks most potentially harmful content)
64
- # @param prompt [String] The input prompt
65
- # @param model_name [String, nil] The model to use (optional)
66
- # @param params [Hash] Additional generation parameters
67
- # @return [Geminize::Models::ContentResponse] The generation response
68
- # @raise [Geminize::GeminizeError] If the request fails
69
- # @example Generate text with maximum safety
70
- # Geminize.generate_text_safe("Tell me about conflicts", nil, temperature: 0.7)
71
- def generate_text_safe(prompt, model_name = nil, params = {})
72
- validate_configuration!
73
-
74
- # Extract special options
75
- with_retries = params.delete(:with_retries) != false # Default to true
76
- max_retries = params.delete(:max_retries) || 3
77
- retry_delay = params.delete(:retry_delay) || 1.0
78
- client_options = params.delete(:client_options) || {}
79
-
80
- # Create the generator and content request
81
- generator = TextGeneration.new(nil, client_options)
82
- content_request = Models::ContentRequest.new(
83
- prompt,
84
- model_name || configuration.default_model,
85
- params
86
- )
87
-
88
- # Set maximum safety (block low and above)
89
- content_request.block_all_harmful_content
90
-
91
- # Generate with or without retries
92
- if with_retries
93
- generator.generate_with_retries(content_request, max_retries, retry_delay)
94
- else
95
- generator.generate(content_request)
96
- end
97
- end
98
-
99
- # Generate text with minimum safety (blocks only high-risk content)
100
- # @param prompt [String] The input prompt
101
- # @param model_name [String, nil] The model to use (optional)
102
- # @param params [Hash] Additional generation parameters
103
- # @return [Geminize::Models::ContentResponse] The generation response
104
- # @raise [Geminize::GeminizeError] If the request fails
105
- # @example Generate text with minimum safety
106
- # Geminize.generate_text_permissive("Tell me about conflicts", nil, temperature: 0.7)
107
- def generate_text_permissive(prompt, model_name = nil, params = {})
108
- validate_configuration!
109
-
110
- # Extract special options
111
- with_retries = params.delete(:with_retries) != false # Default to true
112
- max_retries = params.delete(:max_retries) || 3
113
- retry_delay = params.delete(:retry_delay) || 1.0
114
- client_options = params.delete(:client_options) || {}
115
-
116
- # Create the generator and content request
117
- generator = TextGeneration.new(nil, client_options)
118
- content_request = Models::ContentRequest.new(
119
- prompt,
120
- model_name || configuration.default_model,
121
- params
122
- )
123
-
124
- # Set minimum safety (block only high risk)
125
- content_request.block_only_high_risk_content
126
-
127
- # Generate with or without retries
128
- if with_retries
129
- generator.generate_with_retries(content_request, max_retries, retry_delay)
130
- else
131
- generator.generate(content_request)
132
- end
133
- end
134
- end
135
- end