runapi-gemini-omni 0.2.7 → 0.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: 7befcdce5d30097c0c8ad440c86bd8cd873e14aef90f59304f60d89eed3c2a29
4
- data.tar.gz: ae2353b876a73b19681e151c46310e67edf1dc2f0c04565b5a5c7b10ff3630ce
3
+ metadata.gz: 85c5d15f2668b0387fd150f9c760b653600540475846b855ee0a69e212cea615
4
+ data.tar.gz: d7733e385a5d8905e06cec363f1ebd08822fbfedeb8e51321aa5045b42c79cc7
5
5
  SHA512:
6
- metadata.gz: 3bc31cf371de32b41d86090294fa7feb13ca132d777fa2944ec71a13e015cafed6ef6ec1a6a0f99a8b96c0401703e63d4d38f1d1c4f4e91d0b2639a9734a940e
7
- data.tar.gz: 6056184058b318efb10aaf4eacf012b571fb27d64536faa374f33e1bc182458c1e6dbd2e7cb3b0d7ef2473fc4a07fd3f655bf5d9ce259bcbb4cce672a734b3fd
6
+ metadata.gz: c9b843698b8a21b1d03233970d5036c1d5f052fd094a112e9685d053670da1ce1bb1a1f21d7a6736e8d600f977f8288b6c371d57301004981f1237abc743d98c
7
+ data.tar.gz: edd34f97fb07712d230557a012f7791182bf1e04384fcd32556b27cd4ce743956f4e7ee86a3745503292f3913775e3ddf59ada37207c4191e6c14ffe8297a882
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Gemini Omni API Ruby SDK for RunAPI
1
+ # Gemini Omni Ruby SDK for RunAPI
2
2
 
3
- The gemini omni api Ruby SDK is the language-specific package for Gemini Omni on RunAPI. Use this package for voice resources, character resources, and multimodal video workflows that need JSON request bodies, task status lookup, and consistent RunAPI errors in Ruby.
3
+ The Gemini Omni Ruby SDK is the language-specific package for Gemini Omni on RunAPI. Use this package for voice resources, character resources, and multimodal video generation workflows when your application needs request bodies, task status lookup, and consistent RunAPI errors in Ruby.
4
4
 
5
5
  ## Install
6
6
 
@@ -11,7 +11,7 @@ gem install runapi-gemini-omni
11
11
  ## Quick start
12
12
 
13
13
  ```ruby
14
- require "runapi-gemini_omni"
14
+ require "runapi/gemini_omni"
15
15
 
16
16
  client = RunApi::GeminiOmni::Client.new
17
17
  voice = client.create_audio.run(
@@ -21,14 +21,14 @@ voice = client.create_audio.run(
21
21
 
22
22
  character = client.create_character.run(
23
23
  descriptions: "A silver-haired cyberpunk guide",
24
- image_urls: ["https://file.runapi.ai/demo/character.png"]
24
+ reference_image_url: "https://cdn.runapi.ai/public/samples/reference-1.jpg"
25
25
  )
26
26
 
27
27
  video = client.text_to_video.run(
28
- prompt: "Create a neon city tracking shot with the character walking forward.",
29
- duration: "8",
30
- resolution: "1080p",
31
- character_ids: [character.id]
28
+ model: "gemini-omni-flash-preview",
29
+ prompt: "A paper airplane glides through a sunlit studio.",
30
+ aspect_ratio: "16:9",
31
+ output_resolution: "720p"
32
32
  )
33
33
  ```
34
34
 
@@ -39,7 +39,7 @@ RunAPI-generated file URLs are temporary. Download and store generated images, v
39
39
  - Model page: https://runapi.ai/models/gemini-omni
40
40
  - SDK docs: https://runapi.ai/docs#sdk-gemini-omni
41
41
  - Product docs: https://runapi.ai/docs#gemini-omni
42
- - Pricing and rate limits: https://runapi.ai/models/gemini-omni
42
+ - Flash Preview pricing and rate limits: https://runapi.ai/models/gemini-omni/flash-preview
43
43
  - Provider comparison: https://runapi.ai/providers/google
44
44
  - Full catalog: https://runapi.ai/models
45
45
 
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RunApi
4
+ module GeminiOmni
5
+ CONTRACT = {
6
+ "create-audio" => {
7
+ "models" => ["gemini-omni-audio"],
8
+ "fields_by_model" => {
9
+ "gemini-omni-audio" => {
10
+ "audio_id" => {
11
+ "required" => true
12
+ },
13
+ "name" => {
14
+ "required" => true
15
+ }
16
+ }
17
+ }
18
+ },
19
+ "create-character" => {
20
+ "models" => ["gemini-omni-character"],
21
+ "fields_by_model" => {
22
+ "gemini-omni-character" => {
23
+ "descriptions" => {
24
+ "required" => true
25
+ },
26
+ "reference_image_url" => {
27
+ "required" => true
28
+ }
29
+ }
30
+ }
31
+ },
32
+ "text-to-video" => {
33
+ "models" => ["gemini-omni-flash-preview", "gemini-omni-text-to-video"],
34
+ "fields_by_model" => {
35
+ "gemini-omni-flash-preview" => {
36
+ "aspect_ratio" => {
37
+ "enum" => ["16:9", "9:16"]
38
+ },
39
+ "duration_seconds" => {
40
+ "type" => "integer"
41
+ },
42
+ "output_resolution" => {
43
+ "enum" => ["720p"]
44
+ },
45
+ "prompt" => {
46
+ "required" => true
47
+ },
48
+ "seed" => {
49
+ "type" => "integer"
50
+ }
51
+ },
52
+ "gemini-omni-text-to-video" => {
53
+ "aspect_ratio" => {
54
+ "enum" => ["16:9", "9:16"]
55
+ },
56
+ "audio_ids" => {
57
+ "max_items" => 3
58
+ },
59
+ "character_ids" => {
60
+ "max_items" => 3
61
+ },
62
+ "duration_seconds" => {
63
+ "enum" => [4, 6, 8, 10],
64
+ "required" => true,
65
+ "type" => "integer"
66
+ },
67
+ "output_resolution" => {
68
+ "enum" => ["720p", "1080p", "4k"]
69
+ },
70
+ "prompt" => {
71
+ "required" => true
72
+ },
73
+ "reference_image_urls" => {
74
+ "max_items" => 7
75
+ },
76
+ "seed" => {
77
+ "type" => "integer"
78
+ },
79
+ "video_list" => {
80
+ "max_items" => 1
81
+ }
82
+ }
83
+ },
84
+ "rules" => [{
85
+ "when" => {
86
+ "model" => "gemini-omni-flash-preview"
87
+ },
88
+ "forbidden" => ["reference_image_urls", "audio_ids", "video_list", "character_ids", "duration_seconds", "seed"]
89
+ }]
90
+ }
91
+ }.freeze
92
+ end
93
+ end
@@ -10,6 +10,7 @@ module RunApi
10
10
 
11
11
  ENDPOINT = "/api/v1/gemini_omni/create_audio"
12
12
  RESPONSE_CLASS = Types::CreateAudioResponse
13
+ MODEL = "gemini-omni-audio"
13
14
  NAME_MAX_LENGTH = 210
14
15
  VOICE_DESCRIPTION_MAX_LENGTH = 20_000
15
16
  EXAMPLE_DIALOGUE_MAX_LENGTH = 120
@@ -18,29 +19,21 @@ module RunApi
18
19
  @http = http
19
20
  end
20
21
 
21
- def run(**params)
22
+ def run(options: nil, **params)
22
23
  params = compact_params(params)
23
24
  validate_params!(params)
24
- request(:post, ENDPOINT, body: params)
25
+ request(:post, ENDPOINT, body: params, options: options)
25
26
  end
26
27
 
27
28
  private
28
29
 
29
30
  def validate_params!(params)
30
- validate_required!(params, :audio_id)
31
- validate_required!(params, :name)
31
+ validate_contract!(CONTRACT["create-audio"], params.merge(model: MODEL))
32
32
  validate_length!(params, :name, NAME_MAX_LENGTH)
33
33
  validate_length!(params, :voice_description, VOICE_DESCRIPTION_MAX_LENGTH)
34
34
  validate_length!(params, :example_dialogue, EXAMPLE_DIALOGUE_MAX_LENGTH)
35
35
  end
36
36
 
37
- def validate_required!(params, key)
38
- value = param(params, key)
39
- return if value.is_a?(String) ? !value.empty? : !value.nil?
40
-
41
- raise Core::ValidationError, "#{key} is required"
42
- end
43
-
44
37
  def validate_length!(params, key, max_length)
45
38
  value = param(params, key)
46
39
  return if value.nil? || value.to_s.length <= max_length
@@ -11,6 +11,7 @@ module RunApi
11
11
 
12
12
  ENDPOINT = "/api/v1/gemini_omni/create_character"
13
13
  RESPONSE_CLASS = Types::CreateCharacterResponse
14
+ MODEL = "gemini-omni-character"
14
15
  DESCRIPTIONS_MAX_LENGTH = 20_000
15
16
  CHARACTER_NAME_MAX_LENGTH = 210
16
17
 
@@ -18,34 +19,21 @@ module RunApi
18
19
  @http = http
19
20
  end
20
21
 
21
- def run(**params)
22
+ def run(options: nil, **params)
22
23
  params = compact_params(params)
23
24
  validate_params!(params)
24
- request(:post, ENDPOINT, body: params)
25
+ request(:post, ENDPOINT, body: params, options: options)
25
26
  end
26
27
 
27
28
  private
28
29
 
29
30
  def validate_params!(params)
30
- validate_required!(params, :descriptions)
31
- validate_required!(params, :reference_image_url)
31
+ validate_contract!(CONTRACT["create-character"], params.merge(model: MODEL))
32
32
  validate_array!(params, :audio_ids) if param(params, :audio_ids)
33
33
  validate_length!(params, :descriptions, DESCRIPTIONS_MAX_LENGTH)
34
34
  validate_length!(params, :character_name, CHARACTER_NAME_MAX_LENGTH)
35
35
  end
36
36
 
37
- def validate_required!(params, key)
38
- value = param(params, key)
39
- present = if value.is_a?(Array)
40
- value.any?
41
- else
42
- value.is_a?(String) ? !value.empty? : !value.nil?
43
- end
44
- return if present
45
-
46
- raise Core::ValidationError, "#{key} is required"
47
- end
48
-
49
37
  def validate_array!(params, key)
50
38
  return if param(params, key).is_a?(Array)
51
39
 
@@ -12,11 +12,8 @@ module RunApi
12
12
  ENDPOINT = "/api/v1/gemini_omni/text_to_video"
13
13
  RESPONSE_CLASS = Types::TextToVideoResponse
14
14
  COMPLETED_RESPONSE_CLASS = Types::CompletedTextToVideoResponse
15
+ DEFAULT_MODEL = "gemini-omni-text-to-video"
15
16
  PROMPT_MAX_LENGTH = 20_000
16
- REFERENCE_IMAGE_URLS_MAX = 7
17
- AUDIO_IDS_MAX = 3
18
- VIDEO_LIST_MAX = 1
19
- CHARACTER_IDS_MAX = 3
20
17
  REFERENCE_UNITS_MAX = 7
21
18
  VIDEO_REFERENCE_UNITS = 2
22
19
  MAX_TRIM_SECONDS = 10
@@ -25,51 +22,33 @@ module RunApi
25
22
  @http = http
26
23
  end
27
24
 
28
- def run(**params)
29
- task = create(**params)
30
- poll_until_complete { get(task.id) }
25
+ def run(options: nil, **params)
26
+ task = create(options: options, **params)
27
+ poll_until_complete { get(task.id, options: options) }
31
28
  end
32
29
 
33
- def create(**params)
30
+ def create(options: nil, **params)
34
31
  params = compact_params(params)
35
32
  validate_params!(params)
36
- request(:post, ENDPOINT, body: params)
33
+ request(:post, ENDPOINT, body: params, options: options)
37
34
  end
38
35
 
39
- def get(id)
40
- request(:get, "#{ENDPOINT}/#{id}")
36
+ def get(id, options: nil)
37
+ request(:get, "#{ENDPOINT}/#{id}", options: options)
41
38
  end
42
39
 
43
40
  private
44
41
 
45
42
  def validate_params!(params)
46
- validate_required!(params, :prompt)
47
- validate_required!(params, :duration_seconds)
43
+ selected_model = param(params, :model)
44
+ selected_model = DEFAULT_MODEL if selected_model.nil? || selected_model.to_s.empty?
45
+ validate_contract!(CONTRACT["text-to-video"], params.merge(model: selected_model))
48
46
  validate_length!(params, :prompt, PROMPT_MAX_LENGTH)
49
- validate_optional!(params, :duration_seconds, Types::DURATIONS)
50
- validate_optional!(params, :aspect_ratio, Types::ASPECT_RATIOS)
51
- validate_optional!(params, :output_resolution, Types::OUTPUT_RESOLUTIONS)
52
- validate_array!(params, :reference_image_urls, REFERENCE_IMAGE_URLS_MAX) if param(params, :reference_image_urls)
53
- validate_array!(params, :audio_ids, AUDIO_IDS_MAX) if param(params, :audio_ids)
54
- validate_array!(params, :video_list, VIDEO_LIST_MAX) if param(params, :video_list)
55
- validate_array!(params, :character_ids, CHARACTER_IDS_MAX) if param(params, :character_ids)
56
47
  validate_video_list!(param(params, :video_list)) if param(params, :video_list)
57
48
  validate_reference_units!(params)
58
49
  validate_seed!(params)
59
50
  end
60
51
 
61
- def validate_required!(params, key)
62
- value = param(params, key)
63
- present = if value.is_a?(Array)
64
- value.any?
65
- else
66
- value.is_a?(String) ? !value.empty? : !value.nil?
67
- end
68
- return if present
69
-
70
- raise Core::ValidationError, "#{key} is required"
71
- end
72
-
73
52
  def validate_length!(params, key, max_length)
74
53
  value = param(params, key)
75
54
  return if value.nil? || value.to_s.length <= max_length
@@ -77,14 +56,6 @@ module RunApi
77
56
  raise Core::ValidationError, "#{key} must be at most #{max_length} characters"
78
57
  end
79
58
 
80
- def validate_array!(params, key, max_length)
81
- value = param(params, key)
82
- raise Core::ValidationError, "#{key} must be an array" unless value.is_a?(Array)
83
- return if value.length <= max_length
84
-
85
- raise Core::ValidationError, "#{key} accepts at most #{max_length} items"
86
- end
87
-
88
59
  def validate_video_list!(items)
89
60
  items.each_with_index do |item, index|
90
61
  url = param(item, :url)
@@ -44,12 +44,6 @@ module RunApi
44
44
  optional :error, String
45
45
  end
46
46
 
47
- # Allowed video durations in seconds. Longer durations consume more credits.
48
- DURATIONS = [4, 6, 8, 10].freeze
49
- # Output aspect ratios: landscape (16:9) or portrait (9:16).
50
- ASPECT_RATIOS = %w[16:9 9:16].freeze
51
- # Output resolutions -- higher values produce sharper video at higher cost.
52
- OUTPUT_RESOLUTIONS = %w[720p 1080p 4k].freeze
53
47
  # Valid seed range for reproducible generation.
54
48
  SEED_RANGE = (0..2_147_483_647)
55
49
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "runapi/core"
4
4
  require_relative "gemini_omni/types"
5
+ require_relative "gemini_omni/contract_gen"
5
6
  require_relative "gemini_omni/resources/create_audio"
6
7
  require_relative "gemini_omni/resources/create_character"
7
8
  require_relative "gemini_omni/resources/text_to_video"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runapi-gemini-omni
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - RunAPI
@@ -15,18 +15,18 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 0.2.6
18
+ version: 0.2.14
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: 0.2.6
26
- description: The gemini omni api Ruby SDK is the language-specific package for Gemini
25
+ version: 0.2.14
26
+ description: The Gemini Omni Ruby SDK is the language-specific package for Gemini
27
27
  Omni on RunAPI. Use this package for voice resources, character resources, and multimodal
28
- video workflows that need JSON request bodies, task status lookup, and consistent
29
- RunAPI errors in Ruby.
28
+ video generation workflows when your application needs request bodies, task status
29
+ lookup, and consistent RunAPI errors in Ruby.
30
30
  email:
31
31
  - contact@runapi.ai
32
32
  executables: []
@@ -39,6 +39,7 @@ files:
39
39
  - lib/runapi-gemini_omni.rb
40
40
  - lib/runapi/gemini_omni.rb
41
41
  - lib/runapi/gemini_omni/client.rb
42
+ - lib/runapi/gemini_omni/contract_gen.rb
42
43
  - lib/runapi/gemini_omni/resources/create_audio.rb
43
44
  - lib/runapi/gemini_omni/resources/create_character.rb
44
45
  - lib/runapi/gemini_omni/resources/text_to_video.rb
@@ -47,9 +48,11 @@ homepage: https://runapi.ai/models/gemini-omni
47
48
  licenses:
48
49
  - Apache-2.0
49
50
  metadata:
51
+ runapi_slug: gemini-omni
50
52
  homepage_uri: https://runapi.ai/models/gemini-omni
51
53
  documentation_uri: https://github.com/runapi-ai/gemini-omni-sdk/blob/main/ruby/README.md
52
54
  source_code_uri: https://github.com/runapi-ai/gemini-omni-sdk
55
+ bug_tracker_uri: https://github.com/runapi-ai/gemini-omni-sdk/issues
53
56
  changelog_uri: https://github.com/runapi-ai/gemini-omni-sdk/blob/main/CHANGELOG.md
54
57
  rdoc_options: []
55
58
  require_paths:
@@ -67,5 +70,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
70
  requirements: []
68
71
  rubygems_version: 4.0.10
69
72
  specification_version: 4
70
- summary: Gemini Omni API Ruby SDK for RunAPI
73
+ summary: Gemini Omni Ruby SDK for RunAPI
71
74
  test_files: []