runapi-wan 0.2.7 → 0.2.8

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: f6a0a9c2970e6074e228f6d471414471703a9f255de8e157f0d222350f7c73f8
4
- data.tar.gz: 5262e5103736aeb346183823f755e6e65e373e2d4da177e24609a8fcf0ad23a1
3
+ metadata.gz: 3ac7d4f40ceba4493f0b3759807014b881b46d80993c6e0803f062b02e76365e
4
+ data.tar.gz: be804d111c08b94f2be6562370bb2be17d841ca671ffea88cf593e4717a85e76
5
5
  SHA512:
6
- metadata.gz: f1eed621ce410ac7962200c6930ed100c010f9348dd5b3a06e276918ad5d56ab5c3dae56ca52667b7f2184573d3cbc0a58a5b6c8193d5e2a97db077b61be7b0a
7
- data.tar.gz: fbe4cff342e7da3c49bcfd27a334235f89f3838f4e5440de27c513d89a4db186f9bb8d03cc27123e892e2df055fac865fbd181861aa4392c43023bad96544338
6
+ metadata.gz: 14b6dc707f14c258f3f286b9fbee0fcb43d73c0753511135d474e4b3bf3d2e3b25bfe5fdd9d9e876adc4b6e2716a6dc1b9aa1bdf0c2fda7d14ef44f42148b2dc
7
+ data.tar.gz: ad772becf04fa4abddb64c130bb9662eaeb574f828c9308c0ff5829d4a8517e886d13b60d29e4dce7acf35c44812b2466628d458ac9ee8e514e5a7c8259f3880
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # Wan Video API Ruby SDK for RunAPI
1
+ # Wan API Ruby SDK for RunAPI
2
2
 
3
- The wan video api Ruby SDK is the language-specific package for Wan on RunAPI. Use this wan video api package for text-to-video, image-to-video, animation, and video editing flows when your application needs JSON request bodies, task status lookup, and consistent RunAPI errors in Ruby.
3
+ The Wan Ruby SDK is the language-specific package for Wan on RunAPI. Use this package for video generation, animation, and video editing workflows when your application needs request bodies, task status lookup, and consistent RunAPI errors in Ruby.
4
4
 
5
- This wan video api README is the Ruby package guide inside the public `wan-sdk` repository. For the repository overview, start at `../README.md`; for model details, use https://runapi.ai/models/wan; for API reference, use https://runapi.ai/docs#wan; for SDK docs, use https://runapi.ai/docs#sdk-wan.
5
+ This README is the Ruby package guide inside the public `wan-sdk` repository. For the repository overview, start at `../README.md`; for model details, use https://runapi.ai/models/wan; for API reference, use https://runapi.ai/docs#wan; for SDK docs, use https://runapi.ai/docs#sdk-wan.
6
6
 
7
7
  ## Install
8
8
 
@@ -13,7 +13,7 @@ gem install runapi-wan
13
13
  ## Quick start
14
14
 
15
15
  ```ruby
16
- require "runapi-wan"
16
+ require "runapi/wan"
17
17
 
18
18
  client = RunApi::Wan::Client.new
19
19
  task = client.text_to_video.create(
@@ -28,7 +28,7 @@ RunAPI-generated file URLs are temporary. Download and store generated images, v
28
28
 
29
29
  ## Language notes
30
30
 
31
- Use Ruby keyword arguments and the `RunApi::Wan` error classes when building video jobs, Rails workers, or scripts. The available resources include text to videos, image to videos, speech to videos, animations, images, and video edits. Keep `RUNAPI_API_KEY` in the environment or your secret manager; never commit API keys or callback secrets.
31
+ Use Ruby keyword arguments and the `RunApi::Wan` error classes when building video jobs, Rails workers, or scripts. The available resources are `text_to_video`, `image_to_video`, `speech_to_video`, `animate`, `text_to_image`, and `edit_video`. Keep `RUNAPI_API_KEY` in the environment or your secret manager; never commit API keys or callback secrets.
32
32
 
33
33
  ## Links
34
34
 
@@ -0,0 +1,310 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RunApi
4
+ module Wan
5
+ CONTRACT = {
6
+ "animate" => {
7
+ "models" => ["wan-2.2-animate-move", "wan-2.2-animate-replace"],
8
+ "fields_by_model" => {
9
+ "wan-2.2-animate-move" => {
10
+ "output_resolution" => {
11
+ "enum" => ["480p", "580p", "720p"]
12
+ },
13
+ "reference_video_url" => {
14
+ "required" => true
15
+ },
16
+ "source_image_url" => {
17
+ "required" => true
18
+ }
19
+ },
20
+ "wan-2.2-animate-replace" => {
21
+ "output_resolution" => {
22
+ "enum" => ["480p", "580p", "720p"]
23
+ },
24
+ "reference_video_url" => {
25
+ "required" => true
26
+ },
27
+ "source_image_url" => {
28
+ "required" => true
29
+ }
30
+ }
31
+ }
32
+ },
33
+ "edit-video" => {
34
+ "models" => ["wan-2.6-edit-video", "wan-2.6-flash-edit-video", "wan-2.7-edit-video"],
35
+ "fields_by_model" => {
36
+ "wan-2.6-edit-video" => {
37
+ "duration_seconds" => {
38
+ "type" => "integer"
39
+ },
40
+ "output_resolution" => {
41
+ "enum" => ["720p", "1080p"]
42
+ },
43
+ "prompt" => {
44
+ "required" => true
45
+ },
46
+ "seed" => {
47
+ "type" => "integer"
48
+ },
49
+ "source_video_urls" => {
50
+ "required" => true
51
+ }
52
+ },
53
+ "wan-2.6-flash-edit-video" => {
54
+ "duration_seconds" => {
55
+ "type" => "integer"
56
+ },
57
+ "prompt" => {
58
+ "required" => true
59
+ },
60
+ "seed" => {
61
+ "type" => "integer"
62
+ },
63
+ "source_video_urls" => {
64
+ "required" => true
65
+ }
66
+ },
67
+ "wan-2.7-edit-video" => {
68
+ "aspect_ratio" => {
69
+ "enum" => ["16:9", "9:16", "1:1", "4:3", "3:4"]
70
+ },
71
+ "duration_seconds" => {
72
+ "type" => "integer"
73
+ },
74
+ "output_resolution" => {
75
+ "enum" => ["720p", "1080p"]
76
+ },
77
+ "seed" => {
78
+ "type" => "integer"
79
+ },
80
+ "source_video_url" => {
81
+ "required" => true
82
+ }
83
+ }
84
+ }
85
+ },
86
+ "image-to-video" => {
87
+ "models" => ["wan-2.2-a14b-image-to-video-turbo", "wan-2.5-image-to-video", "wan-2.6-flash-image-to-video", "wan-2.6-image-to-video", "wan-2.7-image-to-video"],
88
+ "fields_by_model" => {
89
+ "wan-2.2-a14b-image-to-video-turbo" => {
90
+ "duration_seconds" => {
91
+ "type" => "integer"
92
+ },
93
+ "first_frame_image_url" => {
94
+ "required" => true
95
+ },
96
+ "output_resolution" => {
97
+ "enum" => ["480p", "720p"]
98
+ },
99
+ "seed" => {
100
+ "type" => "integer"
101
+ }
102
+ },
103
+ "wan-2.5-image-to-video" => {
104
+ "duration_seconds" => {
105
+ "required" => true,
106
+ "type" => "integer"
107
+ },
108
+ "first_frame_image_url" => {
109
+ "required" => true
110
+ },
111
+ "output_resolution" => {
112
+ "enum" => ["720p", "1080p"]
113
+ },
114
+ "seed" => {
115
+ "type" => "integer"
116
+ }
117
+ },
118
+ "wan-2.6-flash-image-to-video" => {
119
+ "audio" => {
120
+ "required" => true
121
+ },
122
+ "duration_seconds" => {
123
+ "type" => "integer"
124
+ },
125
+ "first_frame_image_url" => {
126
+ "required" => true
127
+ },
128
+ "output_resolution" => {
129
+ "enum" => ["720p", "1080p"]
130
+ },
131
+ "prompt" => {
132
+ "required" => true
133
+ }
134
+ },
135
+ "wan-2.6-image-to-video" => {
136
+ "duration_seconds" => {
137
+ "type" => "integer"
138
+ },
139
+ "first_frame_image_url" => {
140
+ "required" => true
141
+ },
142
+ "output_resolution" => {
143
+ "enum" => ["720p", "1080p"]
144
+ },
145
+ "prompt" => {
146
+ "required" => true
147
+ }
148
+ },
149
+ "wan-2.7-image-to-video" => {
150
+ "duration_seconds" => {
151
+ "type" => "integer"
152
+ },
153
+ "output_resolution" => {
154
+ "enum" => ["720p", "1080p"]
155
+ },
156
+ "prompt" => {
157
+ "required" => true
158
+ },
159
+ "seed" => {
160
+ "type" => "integer"
161
+ }
162
+ }
163
+ },
164
+ "rules" => [{
165
+ "when" => {
166
+ "model" => "wan-2.6-flash-image-to-video"
167
+ },
168
+ "forbidden" => ["seed"]
169
+ }, {
170
+ "when" => {
171
+ "model" => "wan-2.6-image-to-video"
172
+ },
173
+ "forbidden" => ["seed"]
174
+ }]
175
+ },
176
+ "speech-to-video" => {
177
+ "models" => ["wan-2.2-a14b-speech-to-video-turbo"],
178
+ "fields_by_model" => {
179
+ "wan-2.2-a14b-speech-to-video-turbo" => {
180
+ "frames_per_second" => {
181
+ "type" => "integer"
182
+ },
183
+ "num_frames" => {
184
+ "type" => "integer"
185
+ },
186
+ "num_inference_steps" => {
187
+ "type" => "integer"
188
+ },
189
+ "output_resolution" => {
190
+ "enum" => ["480p", "580p", "720p"]
191
+ },
192
+ "prompt" => {
193
+ "required" => true
194
+ },
195
+ "seed" => {
196
+ "type" => "integer"
197
+ },
198
+ "source_audio_url" => {
199
+ "required" => true
200
+ },
201
+ "source_image_url" => {
202
+ "required" => true
203
+ }
204
+ }
205
+ }
206
+ },
207
+ "text-to-image" => {
208
+ "models" => ["wan-2.7-image", "wan-2.7-image-pro"],
209
+ "fields_by_model" => {
210
+ "wan-2.7-image" => {
211
+ "aspect_ratio" => {
212
+ "enum" => ["1:1", "16:9", "4:3", "21:9", "3:4", "9:16", "8:1", "1:8"]
213
+ },
214
+ "output_count" => {
215
+ "type" => "integer"
216
+ },
217
+ "output_resolution" => {
218
+ "enum" => ["1k", "2k", "4k"]
219
+ },
220
+ "seed" => {
221
+ "type" => "integer"
222
+ }
223
+ },
224
+ "wan-2.7-image-pro" => {
225
+ "aspect_ratio" => {
226
+ "enum" => ["1:1", "16:9", "4:3", "21:9", "3:4", "9:16", "8:1", "1:8"]
227
+ },
228
+ "output_count" => {
229
+ "type" => "integer"
230
+ },
231
+ "output_resolution" => {
232
+ "enum" => ["1k", "2k", "4k"]
233
+ },
234
+ "seed" => {
235
+ "type" => "integer"
236
+ }
237
+ }
238
+ }
239
+ },
240
+ "text-to-video" => {
241
+ "models" => ["wan-2.2-a14b-text-to-video-turbo", "wan-2.5-text-to-video", "wan-2.6-text-to-video", "wan-2.7-r2v", "wan-2.7-text-to-video"],
242
+ "fields_by_model" => {
243
+ "wan-2.2-a14b-text-to-video-turbo" => {
244
+ "duration_seconds" => {
245
+ "type" => "integer"
246
+ },
247
+ "output_resolution" => {
248
+ "enum" => ["480p", "580p", "720p"]
249
+ },
250
+ "seed" => {
251
+ "type" => "integer"
252
+ }
253
+ },
254
+ "wan-2.5-text-to-video" => {
255
+ "duration_seconds" => {
256
+ "type" => "integer"
257
+ },
258
+ "output_resolution" => {
259
+ "enum" => ["720p", "1080p"]
260
+ },
261
+ "seed" => {
262
+ "type" => "integer"
263
+ }
264
+ },
265
+ "wan-2.6-text-to-video" => {
266
+ "duration_seconds" => {
267
+ "type" => "integer"
268
+ },
269
+ "output_resolution" => {
270
+ "enum" => ["720p", "1080p"]
271
+ }
272
+ },
273
+ "wan-2.7-r2v" => {
274
+ "aspect_ratio" => {
275
+ "enum" => ["16:9", "9:16", "1:1", "4:3", "3:4"]
276
+ },
277
+ "duration_seconds" => {
278
+ "min" => 2,
279
+ "max" => 10,
280
+ "type" => "integer"
281
+ },
282
+ "output_resolution" => {
283
+ "enum" => ["720p", "1080p"]
284
+ },
285
+ "seed" => {
286
+ "type" => "integer"
287
+ }
288
+ },
289
+ "wan-2.7-text-to-video" => {
290
+ "duration_seconds" => {
291
+ "type" => "integer"
292
+ },
293
+ "output_resolution" => {
294
+ "enum" => ["720p", "1080p"]
295
+ },
296
+ "seed" => {
297
+ "type" => "integer"
298
+ }
299
+ }
300
+ },
301
+ "rules" => [{
302
+ "when" => {
303
+ "model" => "wan-2.6-text-to-video"
304
+ },
305
+ "forbidden" => ["seed"]
306
+ }]
307
+ }
308
+ }.freeze
309
+ end
310
+ end
@@ -21,40 +21,33 @@ module RunApi
21
21
  #
22
22
  # @param params [Hash] animation parameters
23
23
  # @return [RunApi::Wan::Types::CompletedVideoTaskResponse] completed animation result
24
- def run(**params)
25
- task = create(**params)
26
- poll_until_complete { get(task.id) }
24
+ def run(options: nil, **params)
25
+ task = create(options: options, **params)
26
+ poll_until_complete { get(task.id, options: options) }
27
27
  end
28
28
 
29
29
  # Create an animation task.
30
30
  #
31
31
  # @param params [Hash] animation parameters
32
32
  # @return [RunApi::Wan::Types::VideoTaskResponse] task creation result with id
33
- def create(**params)
33
+ def create(options: nil, **params)
34
34
  params = compact_params(params)
35
35
  validate_params!(params)
36
- request(:post, ENDPOINT, body: params)
36
+ request(:post, ENDPOINT, body: params, options: options)
37
37
  end
38
38
 
39
39
  # Get animation status by task ID.
40
40
  #
41
41
  # @param id [String] task ID
42
42
  # @return [RunApi::Wan::Types::VideoTaskResponse] current task status
43
- def get(id)
44
- request(:get, "#{ENDPOINT}/#{id}")
43
+ def get(id, options: nil)
44
+ request(:get, "#{ENDPOINT}/#{id}", options: options)
45
45
  end
46
46
 
47
47
  private
48
48
 
49
49
  def validate_params!(params)
50
- raise Core::ValidationError, "model is required" unless param(params, :model)
51
- raise Core::ValidationError, "source_image_url is required" unless param(params, :source_image_url)
52
- raise Core::ValidationError, "reference_video_url is required" unless param(params, :reference_video_url)
53
-
54
- model = param(params, :model)
55
- unless Types::ANIMATE_MODELS.include?(model)
56
- raise Core::ValidationError, "Invalid model: #{model}. Must be one of: #{Types::ANIMATE_MODELS.join(", ")}"
57
- end
50
+ validate_contract!(CONTRACT["animate"], params)
58
51
  end
59
52
  end
60
53
  end
@@ -21,46 +21,33 @@ module RunApi
21
21
  #
22
22
  # @param params [Hash] video editing parameters
23
23
  # @return [RunApi::Wan::Types::CompletedVideoTaskResponse] completed video edit
24
- def run(**params)
25
- task = create(**params)
26
- poll_until_complete { get(task.id) }
24
+ def run(options: nil, **params)
25
+ task = create(options: options, **params)
26
+ poll_until_complete { get(task.id, options: options) }
27
27
  end
28
28
 
29
29
  # Create a video editing task.
30
30
  #
31
31
  # @param params [Hash] video editing parameters
32
32
  # @return [RunApi::Wan::Types::VideoTaskResponse] task creation result with id
33
- def create(**params)
33
+ def create(options: nil, **params)
34
34
  params = compact_params(params)
35
35
  validate_params!(params)
36
- request(:post, ENDPOINT, body: params)
36
+ request(:post, ENDPOINT, body: params, options: options)
37
37
  end
38
38
 
39
39
  # Get video editing status by task ID.
40
40
  #
41
41
  # @param id [String] task ID
42
42
  # @return [RunApi::Wan::Types::VideoTaskResponse] current task status
43
- def get(id)
44
- request(:get, "#{ENDPOINT}/#{id}")
43
+ def get(id, options: nil)
44
+ request(:get, "#{ENDPOINT}/#{id}", options: options)
45
45
  end
46
46
 
47
47
  private
48
48
 
49
49
  def validate_params!(params)
50
- raise Core::ValidationError, "model is required" unless param(params, :model)
51
-
52
- model = param(params, :model)
53
- unless Types::EDIT_VIDEO_MODELS.include?(model)
54
- raise Core::ValidationError, "Invalid model: #{model}. Must be one of: #{Types::EDIT_VIDEO_MODELS.join(", ")}"
55
- end
56
-
57
- if model.include?("2.6")
58
- raise Core::ValidationError, "prompt is required" unless param(params, :prompt)
59
- urls = param(params, :source_video_urls)
60
- raise Core::ValidationError, "source_video_urls is required" if urls.nil? || urls.empty?
61
- else
62
- raise Core::ValidationError, "source_video_url is required" unless param(params, :source_video_url)
63
- end
50
+ validate_contract!(CONTRACT["edit-video"], params)
64
51
  end
65
52
  end
66
53
  end
@@ -20,38 +20,33 @@ module RunApi
20
20
  #
21
21
  # @param params [Hash] image-to-video parameters
22
22
  # @return [RunApi::Wan::Types::CompletedVideoTaskResponse] completed video generation
23
- def run(**params)
24
- task = create(**params)
25
- poll_until_complete { get(task.id) }
23
+ def run(options: nil, **params)
24
+ task = create(options: options, **params)
25
+ poll_until_complete { get(task.id, options: options) }
26
26
  end
27
27
 
28
28
  # Create an image-to-video generation task.
29
29
  #
30
30
  # @param params [Hash] image-to-video parameters
31
31
  # @return [RunApi::Wan::Types::VideoTaskResponse] task creation result with id
32
- def create(**params)
32
+ def create(options: nil, **params)
33
33
  params = compact_params(params)
34
34
  validate_params!(params)
35
- request(:post, ENDPOINT, body: params)
35
+ request(:post, ENDPOINT, body: params, options: options)
36
36
  end
37
37
 
38
38
  # Get image-to-video status by task ID.
39
39
  #
40
40
  # @param id [String] task ID
41
41
  # @return [RunApi::Wan::Types::VideoTaskResponse] current task status
42
- def get(id)
43
- request(:get, "#{ENDPOINT}/#{id}")
42
+ def get(id, options: nil)
43
+ request(:get, "#{ENDPOINT}/#{id}", options: options)
44
44
  end
45
45
 
46
46
  private
47
47
 
48
48
  def validate_params!(params)
49
- raise Core::ValidationError, "model is required" unless param(params, :model)
50
-
51
- model = param(params, :model)
52
- unless Types::IMAGE_TO_VIDEO_MODELS.include?(model)
53
- raise Core::ValidationError, "Invalid model: #{model}. Must be one of: #{Types::IMAGE_TO_VIDEO_MODELS.join(", ")}"
54
- end
49
+ validate_contract!(CONTRACT["image-to-video"], params)
55
50
  end
56
51
  end
57
52
  end
@@ -20,40 +20,33 @@ module RunApi
20
20
  #
21
21
  # @param params [Hash] speech-to-video parameters
22
22
  # @return [RunApi::Wan::Types::CompletedVideoTaskResponse] completed video generation
23
- def run(**params)
24
- task = create(**params)
25
- poll_until_complete { get(task.id) }
23
+ def run(options: nil, **params)
24
+ task = create(options: options, **params)
25
+ poll_until_complete { get(task.id, options: options) }
26
26
  end
27
27
 
28
28
  # Create a speech-to-video generation task.
29
29
  #
30
30
  # @param params [Hash] speech-to-video parameters
31
31
  # @return [RunApi::Wan::Types::VideoTaskResponse] task creation result with id
32
- def create(**params)
32
+ def create(options: nil, **params)
33
33
  params = compact_params(params)
34
34
  validate_params!(params)
35
- request(:post, ENDPOINT, body: params)
35
+ request(:post, ENDPOINT, body: params, options: options)
36
36
  end
37
37
 
38
38
  # Get speech-to-video status by task ID.
39
39
  #
40
40
  # @param id [String] task ID
41
41
  # @return [RunApi::Wan::Types::VideoTaskResponse] current task status
42
- def get(id)
43
- request(:get, "#{ENDPOINT}/#{id}")
42
+ def get(id, options: nil)
43
+ request(:get, "#{ENDPOINT}/#{id}", options: options)
44
44
  end
45
45
 
46
46
  private
47
47
 
48
48
  def validate_params!(params)
49
- raise Core::ValidationError, "model is required" unless param(params, :model)
50
- raise Core::ValidationError, "source_image_url is required" unless param(params, :source_image_url)
51
- raise Core::ValidationError, "source_audio_url is required" unless param(params, :source_audio_url)
52
-
53
- model = param(params, :model)
54
- unless Types::SPEECH_TO_VIDEO_MODELS.include?(model)
55
- raise Core::ValidationError, "Invalid model: #{model}. Must be one of: #{Types::SPEECH_TO_VIDEO_MODELS.join(", ")}"
56
- end
49
+ validate_contract!(CONTRACT["speech-to-video"], params)
57
50
  end
58
51
  end
59
52
  end
@@ -21,39 +21,34 @@ module RunApi
21
21
  #
22
22
  # @param params [Hash] text-to-image parameters
23
23
  # @return [RunApi::Wan::Types::CompletedImageTaskResponse] completed image generation
24
- def run(**params)
25
- task = create(**params)
26
- poll_until_complete { get(task.id) }
24
+ def run(options: nil, **params)
25
+ task = create(options: options, **params)
26
+ poll_until_complete { get(task.id, options: options) }
27
27
  end
28
28
 
29
29
  # Create a text-to-image generation task.
30
30
  #
31
31
  # @param params [Hash] text-to-image parameters
32
32
  # @return [RunApi::Wan::Types::ImageTaskResponse] task creation result with id
33
- def create(**params)
33
+ def create(options: nil, **params)
34
34
  params = compact_params(params)
35
35
  validate_params!(params)
36
- request(:post, ENDPOINT, body: params)
36
+ request(:post, ENDPOINT, body: params, options: options)
37
37
  end
38
38
 
39
39
  # Get text-to-image status by task ID.
40
40
  #
41
41
  # @param id [String] task ID
42
42
  # @return [RunApi::Wan::Types::ImageTaskResponse] current task status
43
- def get(id)
44
- request(:get, "#{ENDPOINT}/#{id}")
43
+ def get(id, options: nil)
44
+ request(:get, "#{ENDPOINT}/#{id}", options: options)
45
45
  end
46
46
 
47
47
  private
48
48
 
49
49
  def validate_params!(params)
50
- raise Core::ValidationError, "model is required" unless param(params, :model)
50
+ validate_contract!(CONTRACT["text-to-image"], params)
51
51
  raise Core::ValidationError, "prompt is required" unless param(params, :prompt)
52
-
53
- model = param(params, :model)
54
- unless Types::TEXT_TO_IMAGE_MODELS.include?(model)
55
- raise Core::ValidationError, "Invalid model: #{model}. Must be one of: #{Types::TEXT_TO_IMAGE_MODELS.join(", ")}"
56
- end
57
52
  end
58
53
  end
59
54
  end
@@ -21,39 +21,34 @@ module RunApi
21
21
  #
22
22
  # @param params [Hash] text-to-video parameters
23
23
  # @return [RunApi::Wan::Types::CompletedVideoTaskResponse] completed video generation
24
- def run(**params)
25
- task = create(**params)
26
- poll_until_complete { get(task.id) }
24
+ def run(options: nil, **params)
25
+ task = create(options: options, **params)
26
+ poll_until_complete { get(task.id, options: options) }
27
27
  end
28
28
 
29
29
  # Create a text-to-video generation task.
30
30
  #
31
31
  # @param params [Hash] text-to-video parameters
32
32
  # @return [RunApi::Wan::Types::VideoTaskResponse] task creation result with id
33
- def create(**params)
33
+ def create(options: nil, **params)
34
34
  params = compact_params(params)
35
35
  validate_params!(params)
36
- request(:post, ENDPOINT, body: params)
36
+ request(:post, ENDPOINT, body: params, options: options)
37
37
  end
38
38
 
39
39
  # Get text-to-video status by task ID.
40
40
  #
41
41
  # @param id [String] task ID
42
42
  # @return [RunApi::Wan::Types::VideoTaskResponse] current task status
43
- def get(id)
44
- request(:get, "#{ENDPOINT}/#{id}")
43
+ def get(id, options: nil)
44
+ request(:get, "#{ENDPOINT}/#{id}", options: options)
45
45
  end
46
46
 
47
47
  private
48
48
 
49
49
  def validate_params!(params)
50
- raise Core::ValidationError, "model is required" unless param(params, :model)
50
+ validate_contract!(CONTRACT["text-to-video"], params)
51
51
  raise Core::ValidationError, "prompt is required" unless param(params, :prompt)
52
-
53
- model = param(params, :model)
54
- unless Types::TEXT_TO_VIDEO_MODELS.include?(model)
55
- raise Core::ValidationError, "Invalid model: #{model}. Must be one of: #{Types::TEXT_TO_VIDEO_MODELS.join(", ")}"
56
- end
57
52
  end
58
53
  end
59
54
  end
@@ -3,40 +3,6 @@
3
3
  module RunApi
4
4
  module Wan
5
5
  module Types
6
- # Text-to-video variants: 2.2 turbo (fast, lower res) through 2.7 (highest quality)
7
- # and R2V (accepts reference images, videos, first-frame, and audio).
8
- TEXT_TO_VIDEO_MODELS = %w[
9
- wan-2.2-a14b-text-to-video-turbo
10
- wan-2.5-text-to-video
11
- wan-2.6-text-to-video
12
- wan-2.7-text-to-video
13
- wan-2.7-r2v
14
- ].freeze
15
-
16
- # Image-to-video variants. Flash trades fidelity for speed; 2.7 adds last-frame
17
- # control, video continuation, driving/background audio, and watermark.
18
- IMAGE_TO_VIDEO_MODELS = %w[
19
- wan-2.2-a14b-image-to-video-turbo
20
- wan-2.5-image-to-video
21
- wan-2.6-image-to-video
22
- wan-2.6-flash-image-to-video
23
- wan-2.7-image-to-video
24
- ].freeze
25
-
26
- # Speech-driven lip-sync model for talking-head video generation.
27
- SPEECH_TO_VIDEO_MODELS = %w[wan-2.2-a14b-speech-to-video-turbo].freeze
28
- # Motion transfer: move (preserves subject) and replace (swaps subject).
29
- ANIMATE_MODELS = %w[wan-2.2-animate-move wan-2.2-animate-replace].freeze
30
- # Image generation: standard and pro. Pro model supports thinking_mode for enhanced reasoning.
31
- TEXT_TO_IMAGE_MODELS = %w[wan-2.7-image wan-2.7-image-pro].freeze
32
- # Video editing: 2.6 uses source_video_urls (plural), 2.7 uses source_video_url (singular).
33
- # Flash variants support audio generation and multi-shot mode.
34
- EDIT_VIDEO_MODELS = %w[
35
- wan-2.6-edit-video
36
- wan-2.6-flash-edit-video
37
- wan-2.7-edit-video
38
- ].freeze
39
-
40
6
  # A single generated video result.
41
7
  class Video < RunApi::Core::BaseModel
42
8
  optional :url, String
data/lib/runapi/wan.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "runapi/core"
4
4
  require_relative "wan/types"
5
+ require_relative "wan/contract_gen"
5
6
  require_relative "wan/resources/text_to_video"
6
7
  require_relative "wan/resources/image_to_video"
7
8
  require_relative "wan/resources/speech_to_video"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runapi-wan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.8
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.13
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 wan video api Ruby SDK is the language-specific package for Wan on
27
- RunAPI. Use this wan video api package for text-to-video, image-to-video, animation,
28
- and video editing flows when your application needs JSON request bodies, task status
29
- lookup, and consistent RunAPI errors in Ruby.
25
+ version: 0.2.13
26
+ description: The Wan Ruby SDK is the language-specific package for Wan on RunAPI.
27
+ Use this package for video generation, animation, and video editing workflows when
28
+ your application needs request bodies, task status lookup, and consistent RunAPI
29
+ errors in Ruby.
30
30
  email:
31
31
  - contact@runapi.ai
32
32
  executables: []
@@ -38,6 +38,7 @@ files:
38
38
  - README.md
39
39
  - lib/runapi/wan.rb
40
40
  - lib/runapi/wan/client.rb
41
+ - lib/runapi/wan/contract_gen.rb
41
42
  - lib/runapi/wan/resources/animate.rb
42
43
  - lib/runapi/wan/resources/edit_video.rb
43
44
  - lib/runapi/wan/resources/image_to_video.rb
@@ -49,9 +50,11 @@ homepage: https://runapi.ai/models/wan
49
50
  licenses:
50
51
  - Apache-2.0
51
52
  metadata:
53
+ runapi_slug: wan
52
54
  homepage_uri: https://runapi.ai/models/wan
53
55
  documentation_uri: https://github.com/runapi-ai/wan-sdk/blob/main/ruby/README.md
54
56
  source_code_uri: https://github.com/runapi-ai/wan-sdk
57
+ bug_tracker_uri: https://github.com/runapi-ai/wan-sdk/issues
55
58
  changelog_uri: https://github.com/runapi-ai/wan-sdk/blob/main/CHANGELOG.md
56
59
  rdoc_options: []
57
60
  require_paths:
@@ -69,5 +72,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
72
  requirements: []
70
73
  rubygems_version: 4.0.10
71
74
  specification_version: 4
72
- summary: Wan Video API Ruby SDK for RunAPI
75
+ summary: Wan API Ruby SDK for RunAPI
73
76
  test_files: []