@pippit-dev/cli 1.0.25 → 1.0.26

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.
package/README.md CHANGED
@@ -227,7 +227,7 @@ pippit-tool-cli generate-video \
227
227
  --resolution "720p"
228
228
  ```
229
229
 
230
- 命令输出 `thread_id`、`run_id` 和 `web_thread_link`。提交生视频 HTTP 请求时,参考图、参考视频和参考音频会使用上传接口返回的 `pippit_asset_id`,并分别写入 `video_part_tool_param.images`、`video_part_tool_param.videos` 和 `video_part_tool_param.audios`。图片最多 9 张,支持 `.jpg`、`.jpeg`、`.png`、`.gif`、`.bmp`、`.webp`、`.svg`;视频最多 3 个,支持 `.mp4`、`.avi`、`.mov`、`.wmv`、`.flv`、`.webm`、`.mkv`、`.m4v`;音频最多 3 个,仅支持 `.mp3`、`.wav`。普通用户支持模型 `Seedance_2.0_mini_lite`;`seedance2.0_vision`、`seedance2.0_fast_vision`、`Seedance_2.0_mini` 和 `Seedance_2.5` 为 VIP 专属模型。CLI 会在提交前校验 prompt、素材数量和文件后缀;模型、比例、分辨率等语义校验由服务端处理。
230
+ 命令输出 `thread_id`、`run_id` 和 `web_thread_link`。提交生视频 HTTP 请求时,参考图、参考视频和参考音频会使用上传接口返回的 `pippit_asset_id`,并分别写入 `video_part_tool_param.images`、`video_part_tool_param.videos` 和 `video_part_tool_param.audios`。图片支持 `.jpg`、`.jpeg`、`.png`、`.gif`、`.bmp`、`.webp`、`.svg`;视频支持 `.mp4`、`.avi`、`.mov`、`.wmv`、`.flv`、`.webm`、`.mkv`、`.m4v`;音频仅支持 `.mp3`、`.wav`。普通用户支持模型 `Seedance_2.0_mini_lite`;`seedance2.0_vision`、`seedance2.0_fast_vision`、`Seedance_2.0_mini` 和 `Seedance_2.5` 为 VIP 专属模型。CLI 会在提交前校验 prompt 和文件后缀;模型、比例、分辨率等语义校验由服务端处理。
231
231
 
232
232
  首尾帧生视频时,按首帧、尾帧的顺序传入两次 `--image`,并设置 `--generate-type 1`:
233
233
 
package/checksums.txt CHANGED
@@ -1,6 +1,6 @@
1
- 4a4f33dcfad8ca038e4e17f30a4eb766a593189879570c42c90c67727663b3e3 pippit-tool-cli-1.0.25-darwin-amd64.tar.gz
2
- 239e645a66c08d55b053a27a736afddf6233010166a0f9646420d01eb1104073 pippit-tool-cli-1.0.25-darwin-arm64.tar.gz
3
- 1491e33040ca68be4fafa39505320ee68120742d931fc37f2f3d0774efd143de pippit-tool-cli-1.0.25-linux-amd64.tar.gz
4
- 057c80108de3e61d54be312601577ca2ec40cea32f4f4e6d4d53d3fa5d090439 pippit-tool-cli-1.0.25-linux-arm64.tar.gz
5
- 3eedc462a21392575c6f677cd7d9cceb6028c8b05a39b251e007e5ae09bb74b6 pippit-tool-cli-1.0.25-windows-amd64.zip
6
- 7641c4814e127153e0979a3e4cd69c9bb38870d81940dfa198b2cff7401f3663 pippit-tool-cli-1.0.25-windows-arm64.zip
1
+ 485d9e51092beaf675a872f890fd744460e7afe45b27ec500ab6b5c90ebb6d0c pippit-tool-cli-1.0.26-darwin-amd64.tar.gz
2
+ 978cca38261d539ea8ce2bcfd15deb24b4b317f38c084fdde92a5b9ca51f0739 pippit-tool-cli-1.0.26-darwin-arm64.tar.gz
3
+ d772c3fcef2c7b7ff0e6e52d6f10b2ee4cff1cd5fbdff9f08e0bd252ac378e79 pippit-tool-cli-1.0.26-linux-amd64.tar.gz
4
+ b16e7f2e7d9bbfe122eb0895ae6769a00d230ca250717aebb3f9b8eea0c04eae pippit-tool-cli-1.0.26-linux-arm64.tar.gz
5
+ fd05b98a6001602efad98731a4777cb035eea2bea2acbccb2c1d02af0223176e pippit-tool-cli-1.0.26-windows-amd64.zip
6
+ a0c873456cf254b0e452c6e376efec5a425ef044b3a1a671d063fa5a613242d0 pippit-tool-cli-1.0.26-windows-arm64.zip
@@ -43,9 +43,9 @@ func NewCommand(stdout, stderr io.Writer, runner *common.Runner) *cobra.Command
43
43
  cmd.SetErr(stderr)
44
44
  flags := cmd.Flags()
45
45
  flags.StringVar(&opts.Prompt, "prompt", "", "video generation prompt")
46
- flags.StringArrayVar(&opts.ImagePaths, "image", nil, "local reference image path; repeat for multiple images, up to 9")
47
- flags.StringArrayVar(&opts.VideoPaths, "video", nil, "local reference video path; repeat for multiple videos, up to 3")
48
- flags.StringArrayVar(&opts.AudioPaths, "audio", nil, "local reference audio path; repeat for multiple audios, up to 3")
46
+ flags.StringArrayVar(&opts.ImagePaths, "image", nil, "local reference image path; repeat for multiple images")
47
+ flags.StringArrayVar(&opts.VideoPaths, "video", nil, "local reference video path; repeat for multiple videos")
48
+ flags.StringArrayVar(&opts.AudioPaths, "audio", nil, "local reference audio path; repeat for multiple audios")
49
49
  flags.IntVar(&durationSec, "duration", 0, "video duration in seconds")
50
50
  flags.StringVar(&opts.Ratio, "ratio", "", "video ratio, such as 9:16, 16:9, 3:4, 4:3")
51
51
  flags.StringVar(&opts.Model, "model", "", "video model; normal users: Seedance_2.0_mini_lite; VIP-only: seedance2.0_vision, seedance2.0_fast_vision, Seedance_2.0_mini, Seedance_2.5")
@@ -189,72 +189,74 @@ func TestGenerateVideoRequiresPrompt(t *testing.T) {
189
189
  }
190
190
  }
191
191
 
192
- func TestGenerateVideoRejectsTooManyImages(t *testing.T) {
193
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
194
- t.Fatal("server should not receive request when image count is invalid")
195
- }))
196
- defer server.Close()
197
-
198
- var stdout, stderr bytes.Buffer
199
- root := newTestRootCommand(t, &stdout, &stderr, server.URL)
200
- args := []string{"generate-video", "--prompt", "x"}
201
- for _, path := range mediaPaths("image", ".jpg", 10) {
202
- args = append(args, "--image", path)
203
- }
204
- root.SetArgs(args)
205
-
206
- err := root.Execute()
207
- if err == nil {
208
- t.Fatal("Execute() error = nil, want image count validation")
209
- }
210
- if !strings.Contains(err.Error(), "参考图片最多支持 9 个,当前传入 10 个") {
211
- t.Fatalf("error = %q, want image count validation", err)
212
- }
213
- }
214
-
215
- func TestGenerateVideoRejectsTooManyVideos(t *testing.T) {
216
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
217
- t.Fatal("server should not receive request when video count is invalid")
218
- }))
219
- defer server.Close()
220
-
221
- var stdout, stderr bytes.Buffer
222
- root := newTestRootCommand(t, &stdout, &stderr, server.URL)
192
+ func TestGenerateVideoAcceptsReferencesBeyondFormerLimits(t *testing.T) {
193
+ cwd := chdirTemp(t)
223
194
  args := []string{"generate-video", "--prompt", "x"}
224
- for _, path := range mediaPaths("video", ".mp4", 4) {
225
- args = append(args, "--video", path)
226
- }
227
- root.SetArgs(args)
228
-
229
- err := root.Execute()
230
- if err == nil {
231
- t.Fatal("Execute() error = nil, want video count validation")
232
- }
233
- if !strings.Contains(err.Error(), "参考视频最多支持 3 个,当前传入 4 个") {
234
- t.Fatalf("error = %q, want video count validation", err)
195
+ var assetIDs []string
196
+ for _, media := range []struct {
197
+ flag string
198
+ ext string
199
+ count int
200
+ }{
201
+ {"image", ".jpg", 10},
202
+ {"video", ".mp4", 4},
203
+ {"audio", ".mp3", 4},
204
+ } {
205
+ for _, name := range mediaPaths(media.flag, media.ext, media.count) {
206
+ path := filepath.Join(cwd, name)
207
+ if err := os.WriteFile(path, []byte("media-data"), 0o644); err != nil {
208
+ t.Fatalf("WriteFile(%s): %v", path, err)
209
+ }
210
+ args = append(args, "--"+media.flag, path)
211
+ assetIDs = append(assetIDs, name)
212
+ }
235
213
  }
236
- }
237
214
 
238
- func TestGenerateVideoRejectsTooManyAudios(t *testing.T) {
215
+ uploadIndex := 0
216
+ submitted := false
239
217
  server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
240
- t.Fatal("server should not receive request when audio count is invalid")
218
+ switch r.URL.Path {
219
+ case "/api/biz/v1/skill/upload_file":
220
+ if uploadIndex >= len(assetIDs) {
221
+ t.Fatalf("unexpected upload %d", uploadIndex)
222
+ }
223
+ _, _ = w.Write([]byte(`{"ret":"0","data":{"pippit_asset_id":"` + assetIDs[uploadIndex] + `"}}`))
224
+ uploadIndex++
225
+ case "/api/biz/v1/skill/submit_run":
226
+ if uploadIndex != len(assetIDs) {
227
+ t.Fatalf("uploaded %d references, want %d", uploadIndex, len(assetIDs))
228
+ }
229
+ data, err := io.ReadAll(r.Body)
230
+ if err != nil {
231
+ t.Fatalf("read body: %v", err)
232
+ }
233
+ var body map[string]any
234
+ if err := sonic.Unmarshal(data, &body); err != nil {
235
+ t.Fatalf("decode body: %v", err)
236
+ }
237
+ param, ok := body["video_part_tool_param"].(map[string]any)
238
+ if !ok {
239
+ t.Fatalf("video_part_tool_param = %#v, want object", body["video_part_tool_param"])
240
+ }
241
+ assertAssetRefs(t, param["images"], assetIDs[:10])
242
+ assertAssetRefs(t, param["videos"], assetIDs[10:14])
243
+ assertAssetRefs(t, param["audios"], assetIDs[14:])
244
+ submitted = true
245
+ _, _ = w.Write([]byte(`{"ret":"0","data":{"run":{"thread_id":"thread_123","run_id":"run_456"}}}`))
246
+ default:
247
+ t.Fatalf("unexpected path %s", r.URL.Path)
248
+ }
241
249
  }))
242
250
  defer server.Close()
243
251
 
244
252
  var stdout, stderr bytes.Buffer
245
253
  root := newTestRootCommand(t, &stdout, &stderr, server.URL)
246
- args := []string{"generate-video", "--prompt", "x"}
247
- for _, path := range mediaPaths("audio", ".mp3", 4) {
248
- args = append(args, "--audio", path)
249
- }
250
254
  root.SetArgs(args)
251
-
252
- err := root.Execute()
253
- if err == nil {
254
- t.Fatal("Execute() error = nil, want audio count validation")
255
+ if err := root.Execute(); err != nil {
256
+ t.Fatalf("Execute() error = %v, stderr = %s", err, stderr.String())
255
257
  }
256
- if !strings.Contains(err.Error(), "参考音频最多支持 3 个,当前传入 4 个") {
257
- t.Fatalf("error = %q, want audio count validation", err)
258
+ if !submitted {
259
+ t.Fatal("generate-video did not submit references")
258
260
  }
259
261
  }
260
262
 
@@ -1,6 +1,6 @@
1
- 4a4f33dcfad8ca038e4e17f30a4eb766a593189879570c42c90c67727663b3e3 pippit-tool-cli-1.0.25-darwin-amd64.tar.gz
2
- 239e645a66c08d55b053a27a736afddf6233010166a0f9646420d01eb1104073 pippit-tool-cli-1.0.25-darwin-arm64.tar.gz
3
- 1491e33040ca68be4fafa39505320ee68120742d931fc37f2f3d0774efd143de pippit-tool-cli-1.0.25-linux-amd64.tar.gz
4
- 057c80108de3e61d54be312601577ca2ec40cea32f4f4e6d4d53d3fa5d090439 pippit-tool-cli-1.0.25-linux-arm64.tar.gz
5
- 3eedc462a21392575c6f677cd7d9cceb6028c8b05a39b251e007e5ae09bb74b6 pippit-tool-cli-1.0.25-windows-amd64.zip
6
- 7641c4814e127153e0979a3e4cd69c9bb38870d81940dfa198b2cff7401f3663 pippit-tool-cli-1.0.25-windows-arm64.zip
1
+ 485d9e51092beaf675a872f890fd744460e7afe45b27ec500ab6b5c90ebb6d0c pippit-tool-cli-1.0.26-darwin-amd64.tar.gz
2
+ 978cca38261d539ea8ce2bcfd15deb24b4b317f38c084fdde92a5b9ca51f0739 pippit-tool-cli-1.0.26-darwin-arm64.tar.gz
3
+ d772c3fcef2c7b7ff0e6e52d6f10b2ee4cff1cd5fbdff9f08e0bd252ac378e79 pippit-tool-cli-1.0.26-linux-amd64.tar.gz
4
+ b16e7f2e7d9bbfe122eb0895ae6769a00d230ca250717aebb3f9b8eea0c04eae pippit-tool-cli-1.0.26-linux-arm64.tar.gz
5
+ fd05b98a6001602efad98731a4777cb035eea2bea2acbccb2c1d02af0223176e pippit-tool-cli-1.0.26-windows-amd64.zip
6
+ a0c873456cf254b0e452c6e376efec5a425ef044b3a1a671d063fa5a613242d0 pippit-tool-cli-1.0.26-windows-arm64.zip
@@ -9,12 +9,6 @@ import (
9
9
  "github.com/Pippit-dev/pippit-cli/internal/common"
10
10
  )
11
11
 
12
- const (
13
- maxReferenceImages = 9
14
- maxReferenceVideos = 3
15
- maxReferenceAudios = 3
16
- )
17
-
18
12
  var (
19
13
  allowedImageExtensionList = []string{".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", ".svg"}
20
14
  allowedAudioExtensionList = []string{".mp3", ".wav"}
@@ -70,15 +64,6 @@ func ValidateOptions(opts *Options) error {
70
64
  if strings.TrimSpace(opts.Prompt) == "" {
71
65
  return fmt.Errorf("缺少必填参数 --prompt")
72
66
  }
73
- if len(opts.ImagePaths) > maxReferenceImages {
74
- return fmt.Errorf("参考图片最多支持 %d 个,当前传入 %d 个", maxReferenceImages, len(opts.ImagePaths))
75
- }
76
- if len(opts.VideoPaths) > maxReferenceVideos {
77
- return fmt.Errorf("参考视频最多支持 %d 个,当前传入 %d 个", maxReferenceVideos, len(opts.VideoPaths))
78
- }
79
- if len(opts.AudioPaths) > maxReferenceAudios {
80
- return fmt.Errorf("参考音频最多支持 %d 个,当前传入 %d 个", maxReferenceAudios, len(opts.AudioPaths))
81
- }
82
67
  if err := validateMediaExtensions("图片", opts.ImagePaths, allowedImageExtensions, allowedImageExtensionList); err != nil {
83
68
  return err
84
69
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pippit-dev/cli",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "Pippit CLI",
5
5
  "bin": {
6
6
  "pippit-tool-cli": "scripts/run.js"
@@ -8,9 +8,9 @@
8
8
  | --- | --- | --- |
9
9
  | `--prompt` | 是 | 用户原始描述,不能全为空白 |
10
10
  | `--model` | 否 | 用户指定的模型;未提供时省略,由服务端处理默认配置 |
11
- | `--image` | 否 | 本地图片路径,重复参数,最多 9 张 |
12
- | `--video` | 否 | 本地参考视频路径,重复参数,最多 3 个 |
13
- | `--audio` | 否 | 本地 `.mp3/.wav` 音频路径,重复参数,最多 3 个 |
11
+ | `--image` | 否 | 本地图片路径,重复参数 |
12
+ | `--video` | 否 | 本地参考视频路径,重复参数 |
13
+ | `--audio` | 否 | 本地 `.mp3/.wav` 音频路径,重复参数 |
14
14
  | `--duration` | 否 | 整数秒;用户只给时长范围时先确认具体秒数 |
15
15
  | `--ratio` | 否 | 比例字符串,如 `9:16`、`16:9`、`3:4`、`4:3`;不转换为生图枚举 |
16
16
  | `--resolution` | 否 | 用户指定值,如 `720p`、`1080p` |