Module: SmartPrompt::SiliconFlow::Video
- Included in:
- SmartPrompt::SiliconFlowAdapter
- Defined in:
- lib/smart_prompt/adapters/siliconflow/video.rb
Overview
Text-to-video / image-to-video (Wan2.2, async submit -> poll -> download).
Constant Summary collapse
- VALID_VIDEO_SIZES =
Text-to-video image_size enum (SiliconFlow rejects anything else).
%w[1280x720 720x1280 960x960].freeze
- DEFAULT_VIDEO_SIZE =
"1280x720".freeze
Instance Method Summary collapse
-
#check_video_status(request_id) ⇒ Object
Poll an async task.
- #download_video(video_url, output_path) ⇒ Object
-
#generate_video(prompt, params = {}) ⇒ Object
Submit a text-to-video (or image-to-video) job.
-
#wait_for_video_completion(request_id, check_interval: 10, timeout: 600) ⇒ Object
Block until the task finishes (or times out), then return the video URL.
Instance Method Details
#check_video_status(request_id) ⇒ Object
Poll an async task. SiliconFlow’s status endpoint is a POST (NOT GET) that takes requestId in the body. Returns the raw status hash.
40 41 42 43 44 45 46 47 |
# File 'lib/smart_prompt/adapters/siliconflow/video.rb', line 40 def check_video_status(request_id) SmartPrompt.logger.info "SiliconFlowAdapter: polling video request #{request_id}" http_post_json(@video_status_url, { "requestId" => request_id }) rescue LLMAPIError, Error raise rescue => e raise LLMAPIError, "Failed to query SiliconFlow video status: #{e.}" end |
#download_video(video_url, output_path) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/smart_prompt/adapters/siliconflow/video.rb', line 73 def download_video(video_url, output_path) uri = URI.parse(video_url) http = Net::HTTP.new(uri.host, uri.port); http.use_ssl = (uri.scheme == "https") response = http.request(Net::HTTP::Get.new(uri.request_uri)) raise Error, "Failed to download video: #{response.code}" unless response.is_a?(Net::HTTPSuccess) FileUtils.mkdir_p(File.dirname(output_path)) File.binwrite(output_path, response.body) SmartPrompt.logger.info "SiliconFlow video saved to #{output_path}" output_path rescue => e raise e.is_a?(SmartPrompt::Error) ? e : Error, "Error downloading SiliconFlow video: #{e.}" end |
#generate_video(prompt, params = {}) ⇒ Object
Submit a text-to-video (or image-to-video) job. Returns the requestId. SiliconFlow’s submit endpoint returns “…” (camelCase).
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/smart_prompt/adapters/siliconflow/video.rb', line 11 def generate_video(prompt, params = {}) SmartPrompt.logger.info "SiliconFlowAdapter: submitting video job" model_name = params[:model] || @config["video_model"] || @config["model"] raise Error, "No model configured for video generation" if model_name.nil? || model_name.to_s.strip.empty? body = { "model" => model_name, "prompt" => prompt.to_s } body["image_size"] = resolve_video_size(params[:image_size] || params[:size]) body["negative_prompt"] = params[:negative_prompt] if params[:negative_prompt] body["seed"] = params[:seed] if params[:seed] body["image"] = normalize_input_image(params[:image]) if params[:image] SmartPrompt.logger.info "SiliconFlow video params: #{body.except('prompt').inspect}" response = begin http_post_json(@video_submit_url, body) rescue LLMAPIError, Error raise rescue => e raise Error, "Failed to submit SiliconFlow video job: #{e.}" end request_id = response["requestId"] || response["request_id"] raise LLMAPIError, "No requestId in SiliconFlow video response: #{response.inspect}" unless request_id SmartPrompt.logger.info "SiliconFlowAdapter: video request #{request_id} submitted" { request_id: request_id, model: model_name, raw: response } end |
#wait_for_video_completion(request_id, check_interval: 10, timeout: 600) ⇒ Object
Block until the task finishes (or times out), then return the video URL. SiliconFlow status values are exactly: Succeeded / InQueue / InProgress / Failed.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/smart_prompt/adapters/siliconflow/video.rb', line 51 def wait_for_video_completion(request_id, check_interval: 10, timeout: 600) start = Time.now loop do status = check_video_status(request_id) case video_status_of(status) when "Succeed" url = video_url_of(status) raise LLMAPIError, "Video succeeded but no url in: #{status.inspect}" unless url SmartPrompt.logger.info "SiliconFlowAdapter: video ready #{url}" return { request_id: request_id, status: "Succeeded", video_url: url, raw: status } when "Failed" raise LLMAPIError, "SiliconFlow video generation failed: #{status["reason"] || status.inspect}" else if Time.now - start > timeout raise LLMAPIError, "SiliconFlow video generation timeout after #{timeout}s" end SmartPrompt.logger.info "SiliconFlow video request #{request_id} #{video_status_of(status)}..." sleep(check_interval) end end end |