geminize 0.1.0

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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.standard.yml +3 -0
  4. data/.yardopts +14 -0
  5. data/CHANGELOG.md +24 -0
  6. data/CODE_OF_CONDUCT.md +132 -0
  7. data/CONTRIBUTING.md +109 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +423 -0
  10. data/Rakefile +10 -0
  11. data/examples/README.md +75 -0
  12. data/examples/configuration.rb +58 -0
  13. data/examples/embeddings.rb +195 -0
  14. data/examples/multimodal.rb +126 -0
  15. data/examples/rails_chat/README.md +69 -0
  16. data/examples/rails_chat/app/controllers/chat_controller.rb +26 -0
  17. data/examples/rails_chat/app/views/chat/index.html.erb +112 -0
  18. data/examples/rails_chat/config/routes.rb +8 -0
  19. data/examples/rails_initializer.rb +46 -0
  20. data/examples/system_instructions.rb +101 -0
  21. data/lib/geminize/chat.rb +98 -0
  22. data/lib/geminize/client.rb +318 -0
  23. data/lib/geminize/configuration.rb +98 -0
  24. data/lib/geminize/conversation_repository.rb +161 -0
  25. data/lib/geminize/conversation_service.rb +126 -0
  26. data/lib/geminize/embeddings.rb +145 -0
  27. data/lib/geminize/error_mapper.rb +96 -0
  28. data/lib/geminize/error_parser.rb +120 -0
  29. data/lib/geminize/errors.rb +185 -0
  30. data/lib/geminize/middleware/error_handler.rb +72 -0
  31. data/lib/geminize/model_info.rb +91 -0
  32. data/lib/geminize/models/chat_request.rb +186 -0
  33. data/lib/geminize/models/chat_response.rb +118 -0
  34. data/lib/geminize/models/content_request.rb +530 -0
  35. data/lib/geminize/models/content_response.rb +99 -0
  36. data/lib/geminize/models/conversation.rb +156 -0
  37. data/lib/geminize/models/embedding_request.rb +222 -0
  38. data/lib/geminize/models/embedding_response.rb +1064 -0
  39. data/lib/geminize/models/memory.rb +88 -0
  40. data/lib/geminize/models/message.rb +140 -0
  41. data/lib/geminize/models/model.rb +171 -0
  42. data/lib/geminize/models/model_list.rb +124 -0
  43. data/lib/geminize/models/stream_response.rb +99 -0
  44. data/lib/geminize/rails/app/controllers/concerns/geminize/controller.rb +105 -0
  45. data/lib/geminize/rails/app/helpers/geminize_helper.rb +125 -0
  46. data/lib/geminize/rails/controller_additions.rb +41 -0
  47. data/lib/geminize/rails/engine.rb +29 -0
  48. data/lib/geminize/rails/helper_additions.rb +37 -0
  49. data/lib/geminize/rails.rb +50 -0
  50. data/lib/geminize/railtie.rb +33 -0
  51. data/lib/geminize/request_builder.rb +57 -0
  52. data/lib/geminize/text_generation.rb +285 -0
  53. data/lib/geminize/validators.rb +150 -0
  54. data/lib/geminize/vector_utils.rb +164 -0
  55. data/lib/geminize/version.rb +5 -0
  56. data/lib/geminize.rb +527 -0
  57. data/lib/generators/geminize/install_generator.rb +22 -0
  58. data/lib/generators/geminize/templates/README +31 -0
  59. data/lib/generators/geminize/templates/initializer.rb +38 -0
  60. data/sig/geminize.rbs +4 -0
  61. metadata +218 -0
@@ -0,0 +1,195 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "geminize"
5
+
6
+ # This example demonstrates how to use the Geminize embedding API
7
+ # to generate vector embeddings for text
8
+
9
+ # Configure with your API key
10
+ Geminize.configure do |config|
11
+ # Use environment variable or set directly
12
+ config.api_key = ENV["GEMINI_API_KEY"] || "your-api-key-here"
13
+
14
+ # Optional: Set a default embedding model
15
+ config.default_embedding_model = "text-embedding-004"
16
+ end
17
+
18
+ puts "============================================================"
19
+ puts "Example 1: Generate embedding for a single text"
20
+ puts "============================================================"
21
+
22
+ begin
23
+ # Generate embedding for a single text
24
+ text = "What is the meaning of life?"
25
+ response = Geminize.generate_embedding(text)
26
+
27
+ puts "Generated embedding with #{response.embedding_size} dimensions"
28
+ puts "First 5 values: #{response.embedding.take(5).inspect}"
29
+ puts "Total tokens: #{response.total_tokens}"
30
+ rescue => e
31
+ puts "Error: #{e.message}"
32
+ end
33
+
34
+ puts "\n============================================================"
35
+ puts "Example 2: Generate embeddings for multiple texts"
36
+ puts "============================================================"
37
+
38
+ begin
39
+ # Generate embeddings for multiple texts in a single API call
40
+ texts = [
41
+ "What is the meaning of life?",
42
+ "How much wood would a woodchuck chuck?",
43
+ "How does the brain work?"
44
+ ]
45
+
46
+ response = Geminize.generate_embedding(texts)
47
+
48
+ puts "Generated #{response.batch_size} embeddings, each with #{response.embedding_size} dimensions"
49
+
50
+ # Access individual embeddings
51
+ texts.each_with_index do |text, i|
52
+ puts "\nText: \"#{text}\""
53
+ puts "First 5 values: #{response.embedding_at(i).take(5).inspect}"
54
+ end
55
+
56
+ puts "\nTotal tokens: #{response.total_tokens}"
57
+ rescue => e
58
+ puts "Error: #{e.message}"
59
+ end
60
+
61
+ puts "\n============================================================"
62
+ puts "Example 3: Generate embeddings with task type and dimensions"
63
+ puts "============================================================"
64
+
65
+ begin
66
+ text = "This is a sample text for similarity comparison"
67
+
68
+ # Generate with specific task type for better performance
69
+ response = Geminize.generate_embedding(
70
+ text,
71
+ "text-embedding-004", # You can specify a model explicitly
72
+ task_type: "SEMANTIC_SIMILARITY", # Optimize for similarity comparisons
73
+ dimensions: 768 # Request specific dimensions (if supported by model)
74
+ )
75
+
76
+ puts "Generated embedding optimized for SEMANTIC_SIMILARITY"
77
+ puts "Dimensions: #{response.embedding_size}"
78
+ puts "First 5 values: #{response.embedding.take(5).inspect}"
79
+ rescue => e
80
+ puts "Error: #{e.message}"
81
+ end
82
+
83
+ puts "\n============================================================"
84
+ puts "Example 4: Batch processing for large arrays"
85
+ puts "============================================================"
86
+
87
+ begin
88
+ # Create a larger array of texts
89
+ many_texts = Array.new(120) { |i| "This is sample text number #{i}" }
90
+
91
+ # Generate embeddings with automatic batch processing
92
+ response = Geminize.generate_embedding(
93
+ many_texts,
94
+ nil, # Use default model
95
+ batch_size: 40 # Process in batches of 40 texts each
96
+ )
97
+
98
+ puts "Generated embeddings for #{response.batch_size} texts"
99
+ puts "First text embedding dimensions: #{response.embedding_size}"
100
+ puts "Total tokens processed: #{response.total_tokens}"
101
+ rescue => e
102
+ puts "Error: #{e.message}"
103
+ end
104
+
105
+ puts "\n============================================================"
106
+ puts "Example 5: Vector operations with embeddings"
107
+ puts "============================================================"
108
+
109
+ begin
110
+ # Generate embeddings for two related texts
111
+ text1 = "Artificial intelligence is changing the world"
112
+ text2 = "Machine learning technologies are transforming industries"
113
+
114
+ response1 = Geminize.generate_embedding(text1)
115
+ response2 = Geminize.generate_embedding(text2)
116
+
117
+ # Calculate cosine similarity
118
+ similarity = Geminize.cosine_similarity(response1.embedding, response2.embedding)
119
+
120
+ puts "Similarity between related texts: #{similarity.round(4)}"
121
+
122
+ # Compare with unrelated text
123
+ text3 = "The quick brown fox jumps over the lazy dog"
124
+ response3 = Geminize.generate_embedding(text3)
125
+
126
+ unrelated_similarity = Geminize.cosine_similarity(response1.embedding, response3.embedding)
127
+
128
+ puts "Similarity with unrelated text: #{unrelated_similarity.round(4)}"
129
+
130
+ # Calculate average embedding
131
+ avg_embedding = Geminize.average_vectors([response1.embedding, response2.embedding])
132
+ puts "Created average embedding vector with #{avg_embedding.size} dimensions"
133
+ rescue => e
134
+ puts "Error: #{e.message}"
135
+ end
136
+
137
+ puts "\n============================================================"
138
+ puts "Example 6: Using different task types for specific use cases"
139
+ puts "============================================================"
140
+
141
+ begin
142
+ # Sample texts for different use cases
143
+ question = "What is the capital of France?"
144
+ code_query = "how to sort an array in javascript"
145
+ document = "Paris is the capital and most populous city of France, with an estimated population of 2,175,601 residents."
146
+ fact = "The Earth revolves around the Sun."
147
+
148
+ puts "Demonstrating different task types for embeddings:"
149
+
150
+ # Question answering
151
+ qa_response = Geminize.generate_embedding(
152
+ question,
153
+ nil, # Use default model
154
+ task_type: Geminize::Models::EmbeddingRequest::QUESTION_ANSWERING
155
+ )
156
+ puts "\n1. QUESTION_ANSWERING task type:"
157
+ puts " Text: \"#{question}\""
158
+ puts " First 5 values: #{qa_response.embedding.take(5).inspect}"
159
+
160
+ # Code retrieval
161
+ code_response = Geminize.generate_embedding(
162
+ code_query,
163
+ nil, # Use default model
164
+ task_type: Geminize::Models::EmbeddingRequest::CODE_RETRIEVAL_QUERY
165
+ )
166
+ puts "\n2. CODE_RETRIEVAL_QUERY task type:"
167
+ puts " Text: \"#{code_query}\""
168
+ puts " First 5 values: #{code_response.embedding.take(5).inspect}"
169
+
170
+ # Document retrieval
171
+ document_response = Geminize.generate_embedding(
172
+ document,
173
+ nil, # Use default model
174
+ task_type: Geminize::Models::EmbeddingRequest::RETRIEVAL_DOCUMENT,
175
+ title: "Paris Facts" # Titles can be used with RETRIEVAL_DOCUMENT
176
+ )
177
+ puts "\n3. RETRIEVAL_DOCUMENT task type with title:"
178
+ puts " Title: \"Paris Facts\""
179
+ puts " First 5 values: #{document_response.embedding.take(5).inspect}"
180
+
181
+ # Fact verification
182
+ fact_response = Geminize.generate_embedding(
183
+ fact,
184
+ nil, # Use default model
185
+ task_type: Geminize::Models::EmbeddingRequest::FACT_VERIFICATION
186
+ )
187
+ puts "\n4. FACT_VERIFICATION task type:"
188
+ puts " Text: \"#{fact}\""
189
+ puts " First 5 values: #{fact_response.embedding.take(5).inspect}"
190
+
191
+ puts "\nNote: Different task types optimize the embeddings for different use cases."
192
+ puts "Choose the appropriate task type based on your application needs."
193
+ rescue => e
194
+ puts "Error: #{e.message}"
195
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "geminize"
4
+
5
+ # Configure with your API key
6
+ Geminize.configure do |config|
7
+ # Use environment variable or set directly
8
+ config.api_key = ENV["GEMINI_API_KEY"] || "your-api-key-here"
9
+
10
+ # Specify the model to use (optional)
11
+ config.default_model = "gemini-2.0-flash" # This model supports multimodal inputs
12
+ end
13
+
14
+ puts "============================================================"
15
+ puts "Example 1: Basic image and text input using a file path"
16
+ puts "============================================================"
17
+
18
+ begin
19
+ # Generate content with an image from a file
20
+ response = Geminize.generate_text_multimodal(
21
+ "Describe this image in detail:",
22
+ [{source_type: "file", data: "path/to/image.jpg"}]
23
+ )
24
+
25
+ puts "Response:"
26
+ puts response.text
27
+ puts "\nFinish reason: #{response.finish_reason}"
28
+ rescue => e
29
+ puts "Error: #{e.message}"
30
+ puts "Make sure to update the image path to a real image on your system."
31
+ end
32
+
33
+ puts "\n============================================================"
34
+ puts "Example 2: Using image URL"
35
+ puts "============================================================"
36
+
37
+ begin
38
+ # Generate content with an image from a URL
39
+ response = Geminize.generate_text_multimodal(
40
+ "What's in this image?",
41
+ [{source_type: "url", data: "https://example.com/sample-image.jpg"}],
42
+ nil, # Use default model
43
+ temperature: 0.7
44
+ )
45
+
46
+ puts "Response with temperature=0.7:"
47
+ puts response.text
48
+ rescue => e
49
+ puts "Error: #{e.message}"
50
+ puts "Make sure to use a valid image URL."
51
+ end
52
+
53
+ puts "\n============================================================"
54
+ puts "Example 3: Multiple images comparison"
55
+ puts "============================================================"
56
+
57
+ begin
58
+ # Generate content comparing multiple images
59
+ response = Geminize.generate_text_multimodal(
60
+ "Compare these two images and describe the differences:",
61
+ [
62
+ {source_type: "file", data: "path/to/image1.jpg"},
63
+ {source_type: "file", data: "path/to/image2.jpg"}
64
+ ],
65
+ "gemini-1.5-pro-latest", # Explicitly specify model
66
+ max_tokens: 500
67
+ )
68
+
69
+ puts "Response (max_tokens=500):"
70
+ puts response.text
71
+ rescue => e
72
+ puts "Error: #{e.message}"
73
+ puts "Make sure to update the image paths to real images on your system."
74
+ end
75
+
76
+ puts "\n============================================================"
77
+ puts "Example 4: Using raw image bytes with MIME type"
78
+ puts "============================================================"
79
+
80
+ begin
81
+ # Read image directly into bytes
82
+ image_bytes = File.binread("path/to/image.jpg")
83
+
84
+ # Generate content with raw image bytes
85
+ response = Geminize.generate_text_multimodal(
86
+ "Analyze this image:",
87
+ [{source_type: "bytes", data: image_bytes, mime_type: "image/jpeg"}]
88
+ )
89
+
90
+ puts "Response for raw bytes input:"
91
+ puts response.text
92
+ rescue => e
93
+ puts "Error: #{e.message}"
94
+ puts "Make sure to update the image path to a real image on your system."
95
+ end
96
+
97
+ puts "\n============================================================"
98
+ puts "Example 5: Using ContentRequest directly for more control"
99
+ puts "============================================================"
100
+
101
+ begin
102
+ # Create a generator
103
+ generator = Geminize::TextGeneration.new
104
+
105
+ # Create a content request
106
+ request = Geminize::Models::ContentRequest.new(
107
+ "Tell me about these images:",
108
+ "gemini-1.5-pro-latest",
109
+ temperature: 0.3,
110
+ max_tokens: 800
111
+ )
112
+
113
+ # Add multiple images using different methods
114
+ request.add_image_from_file("path/to/image1.jpg")
115
+ request.add_image_from_url("https://example.com/image2.jpg")
116
+
117
+ # Generate the response
118
+ response = generator.generate(request)
119
+
120
+ puts "Response using ContentRequest directly:"
121
+ puts response.text
122
+ puts "\nUsed #{response.usage.total_tokens} tokens total"
123
+ rescue => e
124
+ puts "Error: #{e.message}"
125
+ puts "Make sure to update the paths to real images."
126
+ end
@@ -0,0 +1,69 @@
1
+ # Rails Chat Example
2
+
3
+ This is a basic example of how to implement a chat application with the Geminize gem in a Rails application.
4
+
5
+ ## Features
6
+
7
+ - Chat interface with Google's Gemini AI
8
+ - Conversation memory between requests using Rails session
9
+ - Support for Turbo and JSON responses
10
+ - Reset conversation functionality
11
+
12
+ ## Implementation
13
+
14
+ This example demonstrates:
15
+
16
+ 1. How to include Geminize controller concerns
17
+ 2. How to use Geminize view helpers
18
+ 3. How to maintain conversation state in a Rails application
19
+
20
+ ## File Structure
21
+
22
+ - `app/controllers/chat_controller.rb` - Controller with Geminize integration
23
+ - `app/views/chat/index.html.erb` - Chat interface view
24
+ - `config/routes.rb` - Routes configuration
25
+
26
+ ## Setup in Your Application
27
+
28
+ 1. Add Geminize to your Gemfile:
29
+
30
+ ```ruby
31
+ gem 'geminize'
32
+ ```
33
+
34
+ 2. Run the installer:
35
+
36
+ ```bash
37
+ rails generate geminize:install
38
+ ```
39
+
40
+ 3. Configure your API key in `config/initializers/geminize.rb`
41
+
42
+ 4. Include the Geminize helpers in your `ApplicationHelper`
43
+
44
+ ```ruby
45
+ module ApplicationHelper
46
+ geminize_helper
47
+ end
48
+ ```
49
+
50
+ 5. Create your controller with Geminize support
51
+
52
+ ```ruby
53
+ class YourChatController < ApplicationController
54
+ geminize_controller
55
+
56
+ # ... your controller actions
57
+ end
58
+ ```
59
+
60
+ 6. Use the helper methods in your views
61
+
62
+ ```erb
63
+ <%= render_gemini_conversation %>
64
+ <%= gemini_chat_form %>
65
+ ```
66
+
67
+ ## Styling
68
+
69
+ This example includes basic CSS to style the chat interface. Feel free to customize it to match your application's design.
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ChatController < ApplicationController
4
+ # Include Geminize controller functionality
5
+ geminize_controller
6
+
7
+ def index
8
+ # Reset conversation if requested
9
+ reset_gemini_conversation("Chat with Gemini") if params[:reset]
10
+ end
11
+
12
+ def create
13
+ @response = send_gemini_message(params[:message])
14
+
15
+ respond_to do |format|
16
+ format.html { redirect_to chat_path }
17
+ format.turbo_stream
18
+ format.json { render json: {message: @response.text} }
19
+ end
20
+ end
21
+
22
+ def reset
23
+ reset_gemini_conversation("New Chat Session")
24
+ redirect_to chat_path, notice: "Started a new conversation"
25
+ end
26
+ end
@@ -0,0 +1,112 @@
1
+ <%# Chat index view %>
2
+ <div class="chat-container">
3
+ <div class="chat-header">
4
+ <h1>Chat with Gemini</h1>
5
+ <%= link_to "Start New Chat", reset_chat_path, class: "new-chat-button", data: { turbo_method: :post } %>
6
+ </div>
7
+
8
+ <div class="conversation-container">
9
+ <div class="conversation">
10
+ <%= render_gemini_conversation(nil, include_timestamps: true) %>
11
+ </div>
12
+ </div>
13
+
14
+ <div class="chat-form-container">
15
+ <%= gemini_chat_form(
16
+ placeholder: "Ask me anything...",
17
+ submit_text: "Send",
18
+ form_class: "chat-form",
19
+ input_class: "chat-input",
20
+ submit_class: "chat-submit"
21
+ ) %>
22
+ </div>
23
+ </div>
24
+
25
+ <% content_for :styles do %>
26
+ <style>
27
+ .chat-container {
28
+ max-width: 800px;
29
+ margin: 0 auto;
30
+ padding: 20px;
31
+ font-family: system-ui, -apple-system, sans-serif;
32
+ }
33
+
34
+ .chat-header {
35
+ display: flex;
36
+ justify-content: space-between;
37
+ align-items: center;
38
+ margin-bottom: 20px;
39
+ }
40
+
41
+ .new-chat-button {
42
+ background: #6200ee;
43
+ color: white;
44
+ padding: 8px 16px;
45
+ border-radius: 4px;
46
+ text-decoration: none;
47
+ }
48
+
49
+ .conversation-container {
50
+ height: 400px;
51
+ overflow-y: auto;
52
+ border: 1px solid #e0e0e0;
53
+ border-radius: 8px;
54
+ margin-bottom: 20px;
55
+ padding: 16px;
56
+ background: #f8f9fa;
57
+ }
58
+
59
+ .gemini-message {
60
+ margin-bottom: 16px;
61
+ padding: 12px;
62
+ border-radius: 8px;
63
+ }
64
+
65
+ .gemini-user-message {
66
+ background: #e3f2fd;
67
+ margin-left: 20px;
68
+ }
69
+
70
+ .gemini-ai-message {
71
+ background: #f1f3f4;
72
+ margin-right: 20px;
73
+ }
74
+
75
+ .gemini-message-role {
76
+ font-weight: bold;
77
+ margin-bottom: 8px;
78
+ }
79
+
80
+ .gemini-message-timestamp {
81
+ font-size: 0.8em;
82
+ color: #666;
83
+ margin-top: 8px;
84
+ text-align: right;
85
+ }
86
+
87
+ .chat-form {
88
+ display: flex;
89
+ gap: 8px;
90
+ }
91
+
92
+ .chat-input {
93
+ flex: 1;
94
+ padding: 12px;
95
+ border: 1px solid #e0e0e0;
96
+ border-radius: 4px;
97
+ font-family: inherit;
98
+ resize: none;
99
+ height: 80px;
100
+ }
101
+
102
+ .chat-submit {
103
+ background: #6200ee;
104
+ color: white;
105
+ border: none;
106
+ padding: 12px 24px;
107
+ border-radius: 4px;
108
+ cursor: pointer;
109
+ align-self: flex-end;
110
+ }
111
+ </style>
112
+ <% end %>
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ Rails.application.routes.draw do
4
+ # Chat routes
5
+ get "chat", to: "chat#index"
6
+ post "chat", to: "chat#create"
7
+ post "chat/reset", to: "chat#reset", as: :reset_chat
8
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ # config/initializers/geminize.rb
4
+
5
+ # This is an example of how to configure the Geminize gem in a Rails application.
6
+ # Place this file in your config/initializers directory.
7
+
8
+ # Configure the Geminize gem with your API key and any other settings
9
+ Geminize.configure do |config|
10
+ # Required settings
11
+
12
+ # Get the API key from environment variables (recommended approach)
13
+ # config.api_key = ENV["GEMINI_API_KEY"]
14
+
15
+ # Or set it directly (not recommended for production)
16
+ config.api_key = "your-api-key-here"
17
+
18
+ # Optional settings with defaults
19
+
20
+ # API version to use
21
+ config.api_version = "v1beta"
22
+
23
+ # Default model to use when not specified in requests
24
+ config.default_model = "gemini-1.5-pro-latest"
25
+
26
+ # Request timeout in seconds
27
+ config.timeout = 30
28
+
29
+ # Connection open timeout in seconds
30
+ config.open_timeout = 10
31
+
32
+ # Enable request logging for development/debugging
33
+ # In production, keep this false unless debugging an issue
34
+ config.log_requests = Rails.env.development?
35
+ end
36
+
37
+ # Optionally validate the configuration during app initialization
38
+ # This will raise Geminize::ConfigurationError if the configuration is invalid
39
+ begin
40
+ Geminize.validate_configuration!
41
+ Rails.logger.info "Geminize configured successfully"
42
+ rescue Geminize::ConfigurationError => e
43
+ Rails.logger.error "Geminize configuration error: #{e.message}"
44
+ # You might want to raise the error in development but not in production
45
+ raise e if Rails.env.development?
46
+ end
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "geminize"
6
+
7
+ # This example demonstrates how to use system instructions with Geminize
8
+ # System instructions allow you to guide the model's behavior and provide context
9
+ # that influences all responses.
10
+
11
+ # Configure with your API key
12
+ Geminize.configure do |config|
13
+ config.api_key = ENV["GOOGLE_AI_API_KEY"] || ENV["GEMINI_API_KEY"]
14
+ end
15
+
16
+ puts "EXAMPLE 1: Basic system instruction with generate_text"
17
+ puts "====================================================="
18
+
19
+ response = Geminize.generate_text(
20
+ "Tell me about yourself",
21
+ "gemini-2.0-flash",
22
+ system_instruction: "You are a cat named Whiskers. Always speak like a cat."
23
+ )
24
+
25
+ puts "Response:\n#{response.text}"
26
+ puts "\n"
27
+
28
+ puts "EXAMPLE 2: Using system instructions with ContentRequest directly"
29
+ puts "=============================================================="
30
+
31
+ request = Geminize::Models::ContentRequest.new(
32
+ "Explain quantum computing",
33
+ "gemini-2.0-flash",
34
+ temperature: 0.7,
35
+ max_tokens: 150
36
+ )
37
+
38
+ request.system_instruction = "You are a science teacher speaking to a 10-year-old. Use simple language."
39
+
40
+ generator = Geminize::TextGeneration.new
41
+ response = generator.generate(request)
42
+
43
+ puts "Response:\n#{response.text}"
44
+ puts "\n"
45
+
46
+ puts "EXAMPLE 3: System instructions with conversation"
47
+ puts "=============================================="
48
+
49
+ # Start a new conversation with a system instruction
50
+ conversation = Geminize.create_chat("Role-playing Chat")
51
+
52
+ # The system instruction guides the entire conversation
53
+ conversation.set_system_instruction("You are a ship's computer named HAL on a spaceship. Respond in a calm, slightly robotic manner with space-related terminology.")
54
+
55
+ # First message
56
+ response_hash = Geminize.chat("Hello there, who are you?", conversation)
57
+ puts "Response 1:\n#{response_hash[:response].text}\n"
58
+
59
+ # Follow-up
60
+ response_hash = Geminize.chat("What can you help me with?", conversation)
61
+ puts "Response 2:\n#{response_hash[:response].text}\n"
62
+
63
+ puts "EXAMPLE 4: Streaming with system instructions"
64
+ puts "==========================================="
65
+
66
+ puts "Response:"
67
+ Geminize.generate_text_stream(
68
+ "Write a short introduction to a mystery novel",
69
+ "gemini-2.0-flash",
70
+ {
71
+ stream_mode: :delta,
72
+ max_tokens: 150,
73
+ system_instruction: "You are a noir detective writer from the 1940s."
74
+ }
75
+ ) do |chunk|
76
+ print chunk unless chunk.is_a?(Hash)
77
+ end
78
+
79
+ puts "\n\nEXAMPLE 5: Different personas with system instructions"
80
+ puts "====================================================="
81
+
82
+ personas = [
83
+ "You are a Victorian-era poet. Use flowery, elaborate language.",
84
+ "You are a modern tech startup founder. Use buzzwords and be enthusiastic.",
85
+ "You are a grumpy old professor. Be critical and reference obscure theories."
86
+ ]
87
+
88
+ prompt = "What do you think about social media?"
89
+
90
+ personas.each_with_index do |persona, i|
91
+ puts "\nPersona #{i + 1}:"
92
+ puts "-" * 50
93
+ response = Geminize.generate_text(
94
+ prompt,
95
+ "gemini-2.0-flash",
96
+ system_instruction: persona,
97
+ max_tokens: 150
98
+ )
99
+ puts response.text
100
+ puts "-" * 50
101
+ end