runapi-kling 0.2.8 → 0.2.10
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 +4 -4
- data/README.md +7 -7
- data/lib/runapi/kling/contract_gen.rb +347 -0
- data/lib/runapi/kling/resources/ai_avatar.rb +8 -16
- data/lib/runapi/kling/resources/image_to_video.rb +44 -20
- data/lib/runapi/kling/resources/motion_control.rb +8 -21
- data/lib/runapi/kling/resources/text_to_video.rb +35 -25
- data/lib/runapi/kling/types.rb +2 -46
- data/lib/runapi/kling.rb +1 -0
- metadata +11 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e320ba4bacde45051ec892890b4538a8fe2c415d86facc8c3c950bfeb43bd94e
|
|
4
|
+
data.tar.gz: 4ae9148e0a4b579a47f65c6b02ba40d3cc1c95bec9254fd423bf45b442ea99f3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c1bc8ee1eb14d11292751fa2c24318335bb07b4a7bfa02b82454c30f9da7889281bf29067d5fc34d7d29c337d12fbadf934924c9a61c7df34b64bfe6ad937939
|
|
7
|
+
data.tar.gz: e64c06c27bebb03e97c45801a268ad752ab63a3b22cd24e85b7d3baf9d8fc4f7b16cb0547336c820c7a5c560a326fbf49614bf6806e6e9d3e9ec4561e486265d
|
data/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Kling
|
|
1
|
+
# Kling API Ruby SDK for RunAPI
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
The Kling Ruby SDK is the language-specific package for Kling 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
|
|
5
|
+
This README is the Ruby package guide inside the public `kling-sdk` repository. For the repository overview, start at `../README.md`; for model details, use https://runapi.ai/models/kling; for API reference, use https://runapi.ai/docs#kling; for SDK docs, use https://runapi.ai/docs#sdk-kling.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -13,13 +13,13 @@ gem install runapi-kling
|
|
|
13
13
|
## Quick start
|
|
14
14
|
|
|
15
15
|
```ruby
|
|
16
|
-
require "runapi
|
|
16
|
+
require "runapi/kling"
|
|
17
17
|
|
|
18
18
|
client = RunApi::Kling::Client.new
|
|
19
|
-
task = client.
|
|
19
|
+
task = client.text_to_video.create(
|
|
20
20
|
# Pass the Kling JSON request body from https://runapi.ai/docs#kling.
|
|
21
21
|
)
|
|
22
|
-
status = client.
|
|
22
|
+
status = client.text_to_video.get(task.id)
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
Use `create` when you want to submit a task and return quickly, `get` when you need the latest task state, and `run` when a script should create and poll until completion. In web request handlers, prefer `create` plus webhook or later `get` polling so a worker is not held open.
|
|
@@ -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::Kling` error classes when building video jobs, Rails workers, or scripts. The available resources
|
|
31
|
+
Use Ruby keyword arguments and the `RunApi::Kling` error classes when building video jobs, Rails workers, or scripts. The available resources are `text_to_video`, `ai_avatar`, `image_to_video`, and `motion_control`. 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,347 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RunApi
|
|
4
|
+
module Kling
|
|
5
|
+
CONTRACT = {
|
|
6
|
+
"avatar" => {
|
|
7
|
+
"models" => ["kling-ai-avatar-pro", "kling-ai-avatar-standard", "kling-ai-avatar-v1-pro", "kling-v1-avatar-standard"],
|
|
8
|
+
"fields_by_model" => {
|
|
9
|
+
"kling-ai-avatar-pro" => {
|
|
10
|
+
"model" => {
|
|
11
|
+
"required" => true
|
|
12
|
+
},
|
|
13
|
+
"prompt" => {
|
|
14
|
+
"required" => true
|
|
15
|
+
},
|
|
16
|
+
"source_audio_url" => {
|
|
17
|
+
"required" => true
|
|
18
|
+
},
|
|
19
|
+
"source_image_url" => {
|
|
20
|
+
"required" => true
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"kling-ai-avatar-standard" => {
|
|
24
|
+
"model" => {
|
|
25
|
+
"required" => true
|
|
26
|
+
},
|
|
27
|
+
"prompt" => {
|
|
28
|
+
"required" => true
|
|
29
|
+
},
|
|
30
|
+
"source_audio_url" => {
|
|
31
|
+
"required" => true
|
|
32
|
+
},
|
|
33
|
+
"source_image_url" => {
|
|
34
|
+
"required" => true
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"kling-ai-avatar-v1-pro" => {
|
|
38
|
+
"model" => {
|
|
39
|
+
"required" => true
|
|
40
|
+
},
|
|
41
|
+
"prompt" => {
|
|
42
|
+
"required" => true
|
|
43
|
+
},
|
|
44
|
+
"source_audio_url" => {
|
|
45
|
+
"required" => true
|
|
46
|
+
},
|
|
47
|
+
"source_image_url" => {
|
|
48
|
+
"required" => true
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"kling-v1-avatar-standard" => {
|
|
52
|
+
"model" => {
|
|
53
|
+
"required" => true
|
|
54
|
+
},
|
|
55
|
+
"prompt" => {
|
|
56
|
+
"required" => true
|
|
57
|
+
},
|
|
58
|
+
"source_audio_url" => {
|
|
59
|
+
"required" => true
|
|
60
|
+
},
|
|
61
|
+
"source_image_url" => {
|
|
62
|
+
"required" => true
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"image-to-video" => {
|
|
68
|
+
"models" => ["kling-v2.1-master-image-to-video", "kling-v2.1-pro", "kling-v2.1-standard", "kling-v2.5-turbo-image-to-video-pro", "kling-v2.6", "kling-v3-turbo-image-to-video"],
|
|
69
|
+
"fields_by_model" => {
|
|
70
|
+
"kling-v2.1-master-image-to-video" => {
|
|
71
|
+
"duration_seconds" => {
|
|
72
|
+
"enum" => [5, 10],
|
|
73
|
+
"type" => "integer"
|
|
74
|
+
},
|
|
75
|
+
"first_frame_image_url" => {
|
|
76
|
+
"required" => true
|
|
77
|
+
},
|
|
78
|
+
"model" => {
|
|
79
|
+
"required" => true
|
|
80
|
+
},
|
|
81
|
+
"prompt" => {
|
|
82
|
+
"required" => true
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"kling-v2.1-pro" => {
|
|
86
|
+
"duration_seconds" => {
|
|
87
|
+
"enum" => [5, 10],
|
|
88
|
+
"type" => "integer"
|
|
89
|
+
},
|
|
90
|
+
"first_frame_image_url" => {
|
|
91
|
+
"required" => true
|
|
92
|
+
},
|
|
93
|
+
"model" => {
|
|
94
|
+
"required" => true
|
|
95
|
+
},
|
|
96
|
+
"prompt" => {
|
|
97
|
+
"required" => true
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"kling-v2.1-standard" => {
|
|
101
|
+
"duration_seconds" => {
|
|
102
|
+
"enum" => [5, 10],
|
|
103
|
+
"type" => "integer"
|
|
104
|
+
},
|
|
105
|
+
"first_frame_image_url" => {
|
|
106
|
+
"required" => true
|
|
107
|
+
},
|
|
108
|
+
"model" => {
|
|
109
|
+
"required" => true
|
|
110
|
+
},
|
|
111
|
+
"prompt" => {
|
|
112
|
+
"required" => true
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"kling-v2.5-turbo-image-to-video-pro" => {
|
|
116
|
+
"duration_seconds" => {
|
|
117
|
+
"enum" => [5, 10],
|
|
118
|
+
"type" => "integer"
|
|
119
|
+
},
|
|
120
|
+
"first_frame_image_url" => {
|
|
121
|
+
"required" => true
|
|
122
|
+
},
|
|
123
|
+
"model" => {
|
|
124
|
+
"required" => true
|
|
125
|
+
},
|
|
126
|
+
"prompt" => {
|
|
127
|
+
"required" => true
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
"kling-v2.6" => {
|
|
131
|
+
"aspect_ratio" => {
|
|
132
|
+
"enum" => ["16:9", "9:16", "1:1"]
|
|
133
|
+
},
|
|
134
|
+
"duration_seconds" => {
|
|
135
|
+
"enum" => [5, 10],
|
|
136
|
+
"type" => "integer"
|
|
137
|
+
},
|
|
138
|
+
"first_frame_image_url" => {
|
|
139
|
+
"required" => true
|
|
140
|
+
},
|
|
141
|
+
"mode" => {
|
|
142
|
+
"enum" => ["std", "pro"]
|
|
143
|
+
},
|
|
144
|
+
"model" => {
|
|
145
|
+
"required" => true
|
|
146
|
+
},
|
|
147
|
+
"prompt" => {
|
|
148
|
+
"required" => true,
|
|
149
|
+
"min" => 1,
|
|
150
|
+
"max" => 2500,
|
|
151
|
+
"length" => true
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"kling-v3-turbo-image-to-video" => {
|
|
155
|
+
"duration_seconds" => {
|
|
156
|
+
"enum" => [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
|
157
|
+
"type" => "integer"
|
|
158
|
+
},
|
|
159
|
+
"first_frame_image_url" => {
|
|
160
|
+
"required" => true
|
|
161
|
+
},
|
|
162
|
+
"model" => {
|
|
163
|
+
"required" => true
|
|
164
|
+
},
|
|
165
|
+
"output_resolution" => {
|
|
166
|
+
"enum" => ["720p", "1080p"]
|
|
167
|
+
},
|
|
168
|
+
"prompt" => {
|
|
169
|
+
"required" => true,
|
|
170
|
+
"min" => 1,
|
|
171
|
+
"max" => 2500,
|
|
172
|
+
"length" => true
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
"rules" => [{
|
|
177
|
+
"when" => {
|
|
178
|
+
"model" => "kling-v2.1-master-image-to-video"
|
|
179
|
+
},
|
|
180
|
+
"forbidden" => ["output_resolution", "mode", "enable_sound"]
|
|
181
|
+
}, {
|
|
182
|
+
"when" => {
|
|
183
|
+
"model" => "kling-v2.1-pro"
|
|
184
|
+
},
|
|
185
|
+
"forbidden" => ["output_resolution", "mode", "enable_sound"]
|
|
186
|
+
}, {
|
|
187
|
+
"when" => {
|
|
188
|
+
"model" => "kling-v2.1-standard"
|
|
189
|
+
},
|
|
190
|
+
"forbidden" => ["output_resolution", "mode", "enable_sound"]
|
|
191
|
+
}, {
|
|
192
|
+
"when" => {
|
|
193
|
+
"model" => "kling-v2.5-turbo-image-to-video-pro"
|
|
194
|
+
},
|
|
195
|
+
"forbidden" => ["output_resolution", "mode", "enable_sound"]
|
|
196
|
+
}, {
|
|
197
|
+
"when" => {
|
|
198
|
+
"model" => "kling-v2.6"
|
|
199
|
+
},
|
|
200
|
+
"forbidden" => ["output_resolution", "negative_prompt", "cfg_scale"]
|
|
201
|
+
}, {
|
|
202
|
+
"when" => {
|
|
203
|
+
"model" => "kling-v3-turbo-image-to-video"
|
|
204
|
+
},
|
|
205
|
+
"forbidden" => ["mode", "enable_sound", "aspect_ratio", "negative_prompt", "cfg_scale", "last_frame_image_url"]
|
|
206
|
+
}]
|
|
207
|
+
},
|
|
208
|
+
"motion-control" => {
|
|
209
|
+
"models" => ["kling-3.0"],
|
|
210
|
+
"fields_by_model" => {
|
|
211
|
+
"kling-3.0" => {
|
|
212
|
+
"background_source" => {
|
|
213
|
+
"enum" => ["video", "image"]
|
|
214
|
+
},
|
|
215
|
+
"character_orientation" => {
|
|
216
|
+
"enum" => ["video", "image"]
|
|
217
|
+
},
|
|
218
|
+
"model" => {
|
|
219
|
+
"required" => true
|
|
220
|
+
},
|
|
221
|
+
"output_resolution" => {
|
|
222
|
+
"enum" => ["720p", "1080p"]
|
|
223
|
+
},
|
|
224
|
+
"reference_video_url" => {
|
|
225
|
+
"required" => true
|
|
226
|
+
},
|
|
227
|
+
"source_image_url" => {
|
|
228
|
+
"required" => true
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
"text-to-video" => {
|
|
234
|
+
"models" => ["kling-3.0", "kling-v2.1-master-text-to-video", "kling-v2.5-turbo-text-to-video-pro", "kling-v2.6", "kling-v3-turbo-text-to-video"],
|
|
235
|
+
"fields_by_model" => {
|
|
236
|
+
"kling-3.0" => {
|
|
237
|
+
"aspect_ratio" => {
|
|
238
|
+
"enum" => ["16:9", "9:16", "1:1"]
|
|
239
|
+
},
|
|
240
|
+
"duration_seconds" => {
|
|
241
|
+
"enum" => [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
|
242
|
+
"type" => "integer"
|
|
243
|
+
},
|
|
244
|
+
"model" => {
|
|
245
|
+
"required" => true
|
|
246
|
+
},
|
|
247
|
+
"output_resolution" => {
|
|
248
|
+
"enum" => ["720p", "1080p", "4k"]
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
"kling-v2.1-master-text-to-video" => {
|
|
252
|
+
"aspect_ratio" => {
|
|
253
|
+
"enum" => ["16:9", "9:16", "1:1"]
|
|
254
|
+
},
|
|
255
|
+
"duration_seconds" => {
|
|
256
|
+
"enum" => [5, 10],
|
|
257
|
+
"type" => "integer"
|
|
258
|
+
},
|
|
259
|
+
"model" => {
|
|
260
|
+
"required" => true
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
"kling-v2.5-turbo-text-to-video-pro" => {
|
|
264
|
+
"aspect_ratio" => {
|
|
265
|
+
"enum" => ["16:9", "9:16", "1:1"]
|
|
266
|
+
},
|
|
267
|
+
"duration_seconds" => {
|
|
268
|
+
"enum" => [5, 10],
|
|
269
|
+
"type" => "integer"
|
|
270
|
+
},
|
|
271
|
+
"model" => {
|
|
272
|
+
"required" => true
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
"kling-v2.6" => {
|
|
276
|
+
"aspect_ratio" => {
|
|
277
|
+
"enum" => ["16:9", "9:16", "1:1"]
|
|
278
|
+
},
|
|
279
|
+
"duration_seconds" => {
|
|
280
|
+
"enum" => [5, 10],
|
|
281
|
+
"type" => "integer"
|
|
282
|
+
},
|
|
283
|
+
"mode" => {
|
|
284
|
+
"enum" => ["std", "pro"]
|
|
285
|
+
},
|
|
286
|
+
"model" => {
|
|
287
|
+
"required" => true
|
|
288
|
+
},
|
|
289
|
+
"prompt" => {
|
|
290
|
+
"required" => true,
|
|
291
|
+
"min" => 1,
|
|
292
|
+
"max" => 2500,
|
|
293
|
+
"length" => true
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
"kling-v3-turbo-text-to-video" => {
|
|
297
|
+
"aspect_ratio" => {
|
|
298
|
+
"enum" => ["16:9", "9:16", "1:1"]
|
|
299
|
+
},
|
|
300
|
+
"duration_seconds" => {
|
|
301
|
+
"enum" => [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
|
302
|
+
"type" => "integer"
|
|
303
|
+
},
|
|
304
|
+
"model" => {
|
|
305
|
+
"required" => true
|
|
306
|
+
},
|
|
307
|
+
"output_resolution" => {
|
|
308
|
+
"enum" => ["720p", "1080p"]
|
|
309
|
+
},
|
|
310
|
+
"prompt" => {
|
|
311
|
+
"required" => true,
|
|
312
|
+
"min" => 1,
|
|
313
|
+
"max" => 2500,
|
|
314
|
+
"length" => true
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
"rules" => [{
|
|
319
|
+
"when" => {
|
|
320
|
+
"model" => "kling-3.0"
|
|
321
|
+
},
|
|
322
|
+
"forbidden" => ["mode"]
|
|
323
|
+
}, {
|
|
324
|
+
"when" => {
|
|
325
|
+
"model" => "kling-v2.1-master-text-to-video"
|
|
326
|
+
},
|
|
327
|
+
"forbidden" => ["mode"]
|
|
328
|
+
}, {
|
|
329
|
+
"when" => {
|
|
330
|
+
"model" => "kling-v2.5-turbo-text-to-video-pro"
|
|
331
|
+
},
|
|
332
|
+
"forbidden" => ["mode"]
|
|
333
|
+
}, {
|
|
334
|
+
"when" => {
|
|
335
|
+
"model" => "kling-v2.6"
|
|
336
|
+
},
|
|
337
|
+
"forbidden" => ["output_resolution", "negative_prompt", "cfg_scale", "multi_shots", "multi_prompt", "first_frame_image_url", "last_frame_image_url", "kling_elements"]
|
|
338
|
+
}, {
|
|
339
|
+
"when" => {
|
|
340
|
+
"model" => "kling-v3-turbo-text-to-video"
|
|
341
|
+
},
|
|
342
|
+
"forbidden" => ["mode", "enable_sound", "negative_prompt", "cfg_scale", "multi_shots", "multi_prompt", "first_frame_image_url", "last_frame_image_url", "kling_elements"]
|
|
343
|
+
}]
|
|
344
|
+
}
|
|
345
|
+
}.freeze
|
|
346
|
+
end
|
|
347
|
+
end
|
|
@@ -21,41 +21,33 @@ module RunApi
|
|
|
21
21
|
#
|
|
22
22
|
# @param params [Hash] AI avatar parameters
|
|
23
23
|
# @return [RunApi::Kling::Types::CompletedAiAvatarResponse] completed task with videos
|
|
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 AI avatar generation task.
|
|
30
30
|
#
|
|
31
31
|
# @param params [Hash] AI avatar parameters
|
|
32
32
|
# @return [RunApi::Kling::Types::AiAvatarResponse] 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 AI avatar task status by task ID.
|
|
40
40
|
#
|
|
41
41
|
# @param id [String] task ID
|
|
42
42
|
# @return [RunApi::Kling::Types::AiAvatarResponse] 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
|
-
|
|
51
|
-
raise Core::ValidationError, "model is required" unless model
|
|
52
|
-
unless Types::AI_AVATAR_MODELS.include?(model)
|
|
53
|
-
raise Core::ValidationError, "Invalid model: #{model}. Must be one of: #{Types::AI_AVATAR_MODELS.join(", ")}"
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
raise Core::ValidationError, "source_image_url is required" unless param(params, :source_image_url)
|
|
57
|
-
raise Core::ValidationError, "source_audio_url is required" unless param(params, :source_audio_url)
|
|
58
|
-
raise Core::ValidationError, "prompt is required" unless param(params, :prompt)
|
|
50
|
+
validate_contract!(CONTRACT["avatar"], params)
|
|
59
51
|
end
|
|
60
52
|
end
|
|
61
53
|
end
|
|
@@ -12,6 +12,14 @@ module RunApi
|
|
|
12
12
|
|
|
13
13
|
RESPONSE_CLASS = Types::ImageToVideoResponse
|
|
14
14
|
COMPLETED_RESPONSE_CLASS = Types::CompletedImageToVideoResponse
|
|
15
|
+
V26_MODEL = "kling-v2.6"
|
|
16
|
+
V3_TURBO_MODEL = "kling-v3-turbo-image-to-video"
|
|
17
|
+
V3_TURBO_UNSUPPORTED_FIELDS = %i[
|
|
18
|
+
aspect_ratio
|
|
19
|
+
negative_prompt
|
|
20
|
+
cfg_scale
|
|
21
|
+
last_frame_image_url
|
|
22
|
+
].freeze
|
|
15
23
|
|
|
16
24
|
def initialize(http)
|
|
17
25
|
@http = http
|
|
@@ -21,50 +29,66 @@ module RunApi
|
|
|
21
29
|
#
|
|
22
30
|
# @param params [Hash] image-to-video parameters
|
|
23
31
|
# @return [RunApi::Kling::Types::CompletedImageToVideoResponse] completed task with videos
|
|
24
|
-
def run(**params)
|
|
25
|
-
task = create(**params)
|
|
26
|
-
poll_until_complete { get(task.id) }
|
|
32
|
+
def run(options: nil, **params)
|
|
33
|
+
task = create(options: options, **params)
|
|
34
|
+
poll_until_complete { get(task.id, options: options) }
|
|
27
35
|
end
|
|
28
36
|
|
|
29
37
|
# Create an image-to-video task.
|
|
30
38
|
#
|
|
31
39
|
# @param params [Hash] image-to-video parameters
|
|
32
40
|
# @return [RunApi::Kling::Types::ImageToVideoResponse] task creation result with id
|
|
33
|
-
def create(**params)
|
|
41
|
+
def create(options: nil, **params)
|
|
34
42
|
params = compact_params(params)
|
|
35
43
|
validate_params!(params)
|
|
36
|
-
request(:post, ENDPOINT, body: params)
|
|
44
|
+
request(:post, ENDPOINT, body: params, options: options)
|
|
37
45
|
end
|
|
38
46
|
|
|
39
47
|
# Get image-to-video task status by task ID.
|
|
40
48
|
#
|
|
41
49
|
# @param id [String] task ID
|
|
42
50
|
# @return [RunApi::Kling::Types::ImageToVideoResponse] current task status
|
|
43
|
-
def get(id)
|
|
44
|
-
request(:get, "#{ENDPOINT}/#{id}")
|
|
51
|
+
def get(id, options: nil)
|
|
52
|
+
request(:get, "#{ENDPOINT}/#{id}", options: options)
|
|
45
53
|
end
|
|
46
54
|
|
|
47
55
|
private
|
|
48
56
|
|
|
49
57
|
def validate_params!(params)
|
|
58
|
+
reject_unsupported_v3_turbo_fields!(params)
|
|
59
|
+
validate_contract!(CONTRACT["image-to-video"], params)
|
|
60
|
+
|
|
61
|
+
# Bespoke: last_frame_image_url is only allowed for select models
|
|
62
|
+
# (model-gating, not expressible as a contract enum/required rule).
|
|
50
63
|
model = param(params, :model)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
64
|
+
last_frame_image_url = param(params, :last_frame_image_url)
|
|
65
|
+
if model == V26_MODEL
|
|
66
|
+
validate_v26_params!(params, last_frame_image_url)
|
|
67
|
+
elsif last_frame_image_url && !%w[kling-v2.5-turbo-image-to-video-pro kling-v2.1-pro].include?(model)
|
|
68
|
+
raise Core::ValidationError, "last_frame_image_url is only supported by kling-v2.5-turbo-image-to-video-pro and kling-v2.1-pro"
|
|
54
69
|
end
|
|
70
|
+
end
|
|
55
71
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if duration_seconds && !Types::FIXED_DURATIONS.include?(duration_seconds)
|
|
61
|
-
raise Core::ValidationError, "Invalid duration_seconds: #{duration_seconds}. Must be one of: #{Types::FIXED_DURATIONS.join(", ")}"
|
|
72
|
+
def validate_v26_params!(params, last_frame_image_url)
|
|
73
|
+
mode = param(params, :mode) || "std"
|
|
74
|
+
if param(params, :enable_sound) == true && mode != "pro"
|
|
75
|
+
raise Core::ValidationError, "enable_sound requires mode pro for #{V26_MODEL}"
|
|
62
76
|
end
|
|
77
|
+
return unless last_frame_image_url
|
|
63
78
|
|
|
64
|
-
last_frame_image_url
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
79
|
+
raise Core::ValidationError, "last_frame_image_url requires mode pro for #{V26_MODEL}" unless mode == "pro"
|
|
80
|
+
|
|
81
|
+
duration_seconds = param(params, :duration_seconds) || 5
|
|
82
|
+
return if duration_seconds.to_i == 5
|
|
83
|
+
|
|
84
|
+
raise Core::ValidationError, "last_frame_image_url requires duration_seconds 5 for #{V26_MODEL}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def reject_unsupported_v3_turbo_fields!(params)
|
|
88
|
+
return unless param(params, :model) == V3_TURBO_MODEL
|
|
89
|
+
|
|
90
|
+
field = V3_TURBO_UNSUPPORTED_FIELDS.find { |candidate| field_present?(params, candidate) }
|
|
91
|
+
raise Core::ValidationError, "#{field} is not supported by #{V3_TURBO_MODEL}" if field
|
|
68
92
|
end
|
|
69
93
|
end
|
|
70
94
|
end
|
|
@@ -21,46 +21,33 @@ module RunApi
|
|
|
21
21
|
#
|
|
22
22
|
# @param params [Hash] motion control parameters
|
|
23
23
|
# @return [RunApi::Kling::Types::CompletedMotionControlResponse] completed task with videos
|
|
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 motion control generation task.
|
|
30
30
|
#
|
|
31
31
|
# @param params [Hash] motion control parameters
|
|
32
32
|
# @return [RunApi::Kling::Types::MotionControlResponse] 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 motion control task status by task ID.
|
|
40
40
|
#
|
|
41
41
|
# @param id [String] task ID
|
|
42
42
|
# @return [RunApi::Kling::Types::MotionControlResponse] 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
|
-
|
|
51
|
-
raise Core::ValidationError, "model is required" unless model
|
|
52
|
-
unless Types::MOTION_CONTROL_MODELS.include?(model)
|
|
53
|
-
raise Core::ValidationError, "Invalid model: #{model}. Must be one of: #{Types::MOTION_CONTROL_MODELS.join(", ")}"
|
|
54
|
-
end
|
|
55
|
-
validate_optional!(params, :output_resolution, Types::MOTION_CONTROL_OUTPUT_RESOLUTIONS)
|
|
56
|
-
validate_optional!(params, :character_orientation, Types::MOTION_CONTROL_CHARACTER_ORIENTATIONS)
|
|
57
|
-
validate_optional!(params, :background_source, Types::MOTION_CONTROL_BACKGROUND_SOURCES)
|
|
58
|
-
|
|
59
|
-
source_image_url = param(params, :source_image_url)
|
|
60
|
-
raise Core::ValidationError, "source_image_url is required" unless source_image_url
|
|
61
|
-
|
|
62
|
-
reference_video_url = param(params, :reference_video_url)
|
|
63
|
-
raise Core::ValidationError, "reference_video_url is required" unless reference_video_url
|
|
50
|
+
validate_contract!(CONTRACT["motion-control"], params)
|
|
64
51
|
end
|
|
65
52
|
end
|
|
66
53
|
end
|
|
@@ -12,6 +12,18 @@ module RunApi
|
|
|
12
12
|
|
|
13
13
|
RESPONSE_CLASS = Types::TextToVideoResponse
|
|
14
14
|
COMPLETED_RESPONSE_CLASS = Types::CompletedTextToVideoResponse
|
|
15
|
+
V26_MODEL = "kling-v2.6"
|
|
16
|
+
V3_TURBO_MODEL = "kling-v3-turbo-text-to-video"
|
|
17
|
+
V3_TURBO_UNSUPPORTED_FIELDS = %i[
|
|
18
|
+
enable_sound
|
|
19
|
+
negative_prompt
|
|
20
|
+
cfg_scale
|
|
21
|
+
multi_shots
|
|
22
|
+
multi_prompt
|
|
23
|
+
first_frame_image_url
|
|
24
|
+
last_frame_image_url
|
|
25
|
+
kling_elements
|
|
26
|
+
].freeze
|
|
15
27
|
|
|
16
28
|
def initialize(http)
|
|
17
29
|
@http = http
|
|
@@ -21,38 +33,37 @@ module RunApi
|
|
|
21
33
|
#
|
|
22
34
|
# @param params [Hash] text-to-video parameters
|
|
23
35
|
# @return [RunApi::Kling::Types::CompletedTextToVideoResponse] completed task with videos
|
|
24
|
-
def run(**params)
|
|
25
|
-
task = create(**params)
|
|
26
|
-
poll_until_complete { get(task.id) }
|
|
36
|
+
def run(options: nil, **params)
|
|
37
|
+
task = create(options: options, **params)
|
|
38
|
+
poll_until_complete { get(task.id, options: options) }
|
|
27
39
|
end
|
|
28
40
|
|
|
29
41
|
# Create a text-to-video task.
|
|
30
42
|
#
|
|
31
43
|
# @param params [Hash] text-to-video parameters
|
|
32
44
|
# @return [RunApi::Kling::Types::TextToVideoResponse] task creation result with id
|
|
33
|
-
def create(**params)
|
|
45
|
+
def create(options: nil, **params)
|
|
34
46
|
params = compact_params(params)
|
|
35
47
|
validate_params!(params)
|
|
36
|
-
request(:post, ENDPOINT, body: params)
|
|
48
|
+
request(:post, ENDPOINT, body: params, options: options)
|
|
37
49
|
end
|
|
38
50
|
|
|
39
51
|
# Get text-to-video task status by task ID.
|
|
40
52
|
#
|
|
41
53
|
# @param id [String] task ID
|
|
42
54
|
# @return [RunApi::Kling::Types::TextToVideoResponse] current task status
|
|
43
|
-
def get(id)
|
|
44
|
-
request(:get, "#{ENDPOINT}/#{id}")
|
|
55
|
+
def get(id, options: nil)
|
|
56
|
+
request(:get, "#{ENDPOINT}/#{id}", options: options)
|
|
45
57
|
end
|
|
46
58
|
|
|
47
59
|
private
|
|
48
60
|
|
|
49
61
|
def validate_params!(params)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
raise Core::ValidationError, "Invalid model: #{model}. Must be one of: #{Types::TEXT_TO_VIDEO_MODELS.join(", ")}"
|
|
54
|
-
end
|
|
62
|
+
reject_unsupported_v3_turbo_fields!(params)
|
|
63
|
+
validate_contract!(CONTRACT["text-to-video"], params)
|
|
64
|
+
validate_v26_params!(params)
|
|
55
65
|
|
|
66
|
+
# Bespoke cross-field rules the contract cannot express.
|
|
56
67
|
multi_shots = param(params, :multi_shots) == true
|
|
57
68
|
|
|
58
69
|
if multi_shots
|
|
@@ -64,21 +75,20 @@ module RunApi
|
|
|
64
75
|
else
|
|
65
76
|
raise Core::ValidationError, "prompt is required" unless param(params, :prompt)
|
|
66
77
|
end
|
|
78
|
+
end
|
|
67
79
|
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
def validate_v26_params!(params)
|
|
81
|
+
return unless param(params, :model) == V26_MODEL
|
|
82
|
+
return unless param(params, :enable_sound) == true && param(params, :mode) != "pro"
|
|
70
83
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
raise Core::ValidationError, "Invalid duration_seconds: #{duration_seconds}. Must be an integer between #{Types::DURATION_RANGE.min} and #{Types::DURATION_RANGE.max}"
|
|
80
|
-
end
|
|
81
|
-
end
|
|
84
|
+
raise Core::ValidationError, "enable_sound requires mode pro for #{V26_MODEL}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def reject_unsupported_v3_turbo_fields!(params)
|
|
88
|
+
return unless param(params, :model) == V3_TURBO_MODEL
|
|
89
|
+
|
|
90
|
+
field = V3_TURBO_UNSUPPORTED_FIELDS.find { |candidate| field_present?(params, candidate) }
|
|
91
|
+
raise Core::ValidationError, "#{field} is not supported by #{V3_TURBO_MODEL}" if field
|
|
82
92
|
end
|
|
83
93
|
|
|
84
94
|
def validate_multi_prompt!(multi_prompt)
|
data/lib/runapi/kling/types.rb
CHANGED
|
@@ -4,54 +4,10 @@ module RunApi
|
|
|
4
4
|
module Kling
|
|
5
5
|
# Type definitions and constants for Kling video generation.
|
|
6
6
|
module Types
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
TEXT_TO_VIDEO_MODELS = %w[
|
|
10
|
-
kling-3.0
|
|
11
|
-
kling-v2.5-turbo-text-to-video-pro
|
|
12
|
-
kling-v2.1-master-text-to-video
|
|
13
|
-
].freeze
|
|
14
|
-
|
|
15
|
-
# AI avatar lip-sync quality tiers, from highest to fastest.
|
|
16
|
-
AI_AVATAR_MODELS = %w[
|
|
17
|
-
kling-ai-avatar-pro
|
|
18
|
-
kling-ai-avatar-standard
|
|
19
|
-
kling-ai-avatar-v1-pro
|
|
20
|
-
kling-v1-avatar-standard
|
|
21
|
-
].freeze
|
|
22
|
-
|
|
23
|
-
# Image-to-video model variants. V2.5 turbo and V2.1 pro support last-frame image control.
|
|
24
|
-
IMAGE_TO_VIDEO_MODELS = %w[
|
|
25
|
-
kling-v2.5-turbo-image-to-video-pro
|
|
26
|
-
kling-v2.1-pro
|
|
27
|
-
kling-v2.1-standard
|
|
28
|
-
kling-v2.1-master-image-to-video
|
|
29
|
-
].freeze
|
|
30
|
-
|
|
31
|
-
# Output resolution options. 4k is highest quality but slowest.
|
|
32
|
-
TEXT_TO_VIDEO_OUTPUT_RESOLUTIONS = %w[720p 1080p 4k].freeze
|
|
33
|
-
|
|
34
|
-
MOTION_CONTROL_MODELS = %w[kling-3.0].freeze
|
|
35
|
-
|
|
36
|
-
MOTION_CONTROL_OUTPUT_RESOLUTIONS = %w[720p 1080p].freeze
|
|
37
|
-
|
|
38
|
-
# Whether the character faces the direction from the video or the image.
|
|
39
|
-
MOTION_CONTROL_CHARACTER_ORIENTATIONS = %w[video image].freeze
|
|
40
|
-
|
|
41
|
-
# Whether the background comes from the reference video or the subject image.
|
|
42
|
-
MOTION_CONTROL_BACKGROUND_SOURCES = %w[video image].freeze
|
|
43
|
-
|
|
44
|
-
ASPECT_RATIOS = %w[16:9 9:16 1:1].freeze
|
|
45
|
-
|
|
46
|
-
# Duration range for kling-3.0 (seconds).
|
|
47
|
-
DURATION_RANGE = (3..15)
|
|
48
|
-
|
|
49
|
-
# Per-shot duration range in multi-shot mode (seconds).
|
|
7
|
+
# Per-shot duration range in multi-shot mode (seconds). Bespoke constant for
|
|
8
|
+
# the multi_prompt[] nested-array validation, which the contract cannot express.
|
|
50
9
|
MULTI_PROMPT_DURATION_RANGE = (1..12)
|
|
51
10
|
|
|
52
|
-
# Fixed duration options for V2.x models (seconds).
|
|
53
|
-
FIXED_DURATIONS = [5, 10].freeze
|
|
54
|
-
|
|
55
11
|
# Maximum character length for each multi-shot prompt segment.
|
|
56
12
|
MULTI_PROMPT_MAX_LENGTH = 500
|
|
57
13
|
|
data/lib/runapi/kling.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: runapi-kling
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.10
|
|
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.
|
|
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.
|
|
26
|
-
description: The
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
version: 0.2.14
|
|
26
|
+
description: The Kling Ruby SDK is the language-specific package for Kling 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: []
|
|
@@ -39,6 +39,7 @@ files:
|
|
|
39
39
|
- lib/runapi-kling.rb
|
|
40
40
|
- lib/runapi/kling.rb
|
|
41
41
|
- lib/runapi/kling/client.rb
|
|
42
|
+
- lib/runapi/kling/contract_gen.rb
|
|
42
43
|
- lib/runapi/kling/resources/ai_avatar.rb
|
|
43
44
|
- lib/runapi/kling/resources/image_to_video.rb
|
|
44
45
|
- lib/runapi/kling/resources/motion_control.rb
|
|
@@ -48,9 +49,11 @@ homepage: https://runapi.ai/models/kling
|
|
|
48
49
|
licenses:
|
|
49
50
|
- Apache-2.0
|
|
50
51
|
metadata:
|
|
52
|
+
runapi_slug: kling
|
|
51
53
|
homepage_uri: https://runapi.ai/models/kling
|
|
52
54
|
documentation_uri: https://github.com/runapi-ai/kling-sdk/blob/main/ruby/README.md
|
|
53
55
|
source_code_uri: https://github.com/runapi-ai/kling-sdk
|
|
56
|
+
bug_tracker_uri: https://github.com/runapi-ai/kling-sdk/issues
|
|
54
57
|
changelog_uri: https://github.com/runapi-ai/kling-sdk/blob/main/CHANGELOG.md
|
|
55
58
|
rdoc_options: []
|
|
56
59
|
require_paths:
|
|
@@ -68,5 +71,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
68
71
|
requirements: []
|
|
69
72
|
rubygems_version: 4.0.10
|
|
70
73
|
specification_version: 4
|
|
71
|
-
summary: Kling
|
|
74
|
+
summary: Kling API Ruby SDK for RunAPI
|
|
72
75
|
test_files: []
|