@pippit-dev/cli 1.0.48 → 1.0.50

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
@@ -265,16 +265,11 @@ pippit-tool-cli canvas command run create_biz_node \
265
265
 
266
266
  `guide [topic]` 提供无需登录的离线帮助。无主题时仅返回索引,可选 `storyboard`、`prompt-references`、`time`、`timeline`、`scene3d`;正文包含单位、ID 来源、前置条件和最小示例。指南不启用新能力,先用 `list` 确认本机运行时支持哪些命令。故事板指南说明原生 `<duration-ms>` 标签累加与引用格式;目前没有公开的故事板脚本编辑、镜头排序或指定镜头生成领域命令,通用视频生成与资产补丁不能替代其业务流程。
267
267
 
268
- 3D 导演台和多轨道都通过外层画布节点定位,其编辑内容保存在节点引用的独立文档或草稿资产中。先查询取得内部对象、轨道、片段 ID 和版本,再执行编辑:
268
+ 当前 SDK 主干的 3D 导演文档已迁移到 V2,旧 CLI 的 `xyq.scene3d.apply/query` 入口已移除。本版本沿用主干能力;3D 节点仍可通过业务工厂创建,内部对象编辑使用 Web 3D 导演台,不通过通用资产补丁改写文档。
269
269
 
270
- ```bash
271
- pippit-tool-cli canvas command describe xyq.scene3d.apply
272
- pippit-tool-cli canvas command run xyq.scene3d.query \
273
- --canvas-id CANVAS_ID --input '{"nodeId":"DIRECTOR_NODE_ID"}'
274
- pippit-tool-cli canvas command run xyq.scene3d.apply \
275
- --canvas-id CANVAS_ID \
276
- --input '{"nodeId":"DIRECTOR_NODE_ID","operations":[{"command":"create_node","args":{"kind":"camera","id":"camera-2","name":"Close-up"}}]}'
270
+ 多轨道通过外层画布节点定位,先查询轨道、片段 ID 和版本,再执行编辑:
277
271
 
272
+ ```bash
278
273
  pippit-tool-cli canvas command describe xyq.timeline.apply
279
274
  pippit-tool-cli canvas command run xyq.timeline.query \
280
275
  --canvas-id CANVAS_ID --input '{"nodeId":"TIMELINE_NODE_ID"}'
@@ -455,7 +450,7 @@ pippit-tool-cli query-result \
455
450
  --download-dir "./output"
456
451
  ```
457
452
 
458
- `query-result` 会查询指定 Run 并输出 JSON。Run 成功完成后下载视频和图片产物,`completed=true`,`videos` 和 `images` 中各包含 `download_url` 和 `output_path`;图片扩展名取自产物 `metadata.format`,缺省时兜底 `.png`。Run 失败也视为终态,`completed=true` 且填充 `error_message`;Run 未到终态时 `completed=false`。
453
+ `query-result` 会查询指定 Run 并输出 JSON。Run 成功完成后下载视频和图片产物,`completed=true`、`status="succeeded"`,`videos` 和 `images` 中各包含 `download_url` 和 `output_path`;图片扩展名取自产物 `metadata.format`,缺省时兜底 `.png`。`status` 是机读状态,共 5 种取值:`running`(运行中,对应服务端已提交、处理中、生成中、程序中断等继续轮询的状态)、`succeeded`(成功)、`failed`(失败并填充 `error_message`)、`canceled`(已取消)、`unknown`(未指定、等待补充输入、人工交互中断等无法自动判定的状态)。`completed` 只表示是否到终态(成功、失败、已取消时为 true),判断成功失败请使用 `status`;查询或下载本身失败时 `status="unknown"`、`completed=false`,具体原因见 `error_message`。
459
454
 
460
455
  ## Adapter 接入边界
461
456
 
package/checksums.txt CHANGED
@@ -1,6 +1,6 @@
1
- 718067da81039c982cdcb9579f50a06a83bbc7c7dd599ab447b50e8b8e2b13ac pippit-tool-cli-1.0.48-darwin-amd64.tar.gz
2
- d0aa4e2272c8369fb615b82bbb390a3e575e3b3df39dffbb5d38c6fc8e7d67c3 pippit-tool-cli-1.0.48-darwin-arm64.tar.gz
3
- 838f221cef34481f042a2fec32da0f015d5c61151f43eeb3460ceb94c05601fd pippit-tool-cli-1.0.48-linux-amd64.tar.gz
4
- 1ff3d84ffe6a04bc6c5ed92d9e784308d8dc16fffc88037faa21665d9a74106c pippit-tool-cli-1.0.48-linux-arm64.tar.gz
5
- 04400b90e115ba0d9d8e0d6917e8b69cfe980fa5601bd5c9bdb2625135036d5e pippit-tool-cli-1.0.48-windows-amd64.zip
6
- e6a2f024b93abcc546007fe1c5e2fcaebed11ab64123943c30dda9f47f8c4b63 pippit-tool-cli-1.0.48-windows-arm64.zip
1
+ a458435d1197a30b707df6a462f8226a7e0712a68321e80122f94c2adc1de6b5 pippit-tool-cli-1.0.50-darwin-amd64.tar.gz
2
+ f2d521422ef4e4ac1f4a8ce1111f8bffd2b29a70e83cbaf5b931354085894152 pippit-tool-cli-1.0.50-darwin-arm64.tar.gz
3
+ 5655d75170e4e6616e12ba2f6c05849381b5eca14b70b4e5273357c457c90d85 pippit-tool-cli-1.0.50-linux-amd64.tar.gz
4
+ c38ae24da3a18c9ce295a67523a3608da4c8fa10a1e125c03b07d635372f1894 pippit-tool-cli-1.0.50-linux-arm64.tar.gz
5
+ a02ee4dfd051201fbbf84188d7969ec3be3ffa8a0ef70e0ac7fd94a307fce6af pippit-tool-cli-1.0.50-windows-amd64.zip
6
+ 72f17b0945d8619ff5a80da26d474e8d4e30f56b4c70d0c01f838ae3fd8080b9 pippit-tool-cli-1.0.50-windows-arm64.zip
@@ -26,7 +26,7 @@ func NewQueryResultCommand(stdout, stderr io.Writer, runner *common.Runner) *cob
26
26
  "run_id": strings.TrimSpace(opts.RunID),
27
27
  "download_dir": strings.TrimSpace(opts.DownloadDir),
28
28
  })
29
- result = queryResultFromError(err, opts)
29
+ result = internalgen.NewQueryResultError(err, opts)
30
30
  }
31
31
  encoder := json.NewEncoder(stdout)
32
32
  encoder.SetIndent("", " ")
@@ -40,16 +40,3 @@ func NewQueryResultCommand(stdout, stderr io.Writer, runner *common.Runner) *cob
40
40
  cmd.Flags().StringVar(&opts.DownloadDir, "download-dir", "", "directory to download completed videos or images into")
41
41
  return cmd
42
42
  }
43
-
44
- func queryResultFromError(err error, opts *internalgen.QueryResultOptions) *internalgen.QueryResultResult {
45
- result := &internalgen.QueryResultResult{
46
- ErrorMessage: err.Error(),
47
- Videos: []internalgen.QueryResultVideo{},
48
- Images: []internalgen.QueryResultImage{},
49
- }
50
- if opts != nil {
51
- result.ThreadID = strings.TrimSpace(opts.ThreadID)
52
- result.RunID = strings.TrimSpace(opts.RunID)
53
- }
54
- return result
55
- }
@@ -2,6 +2,7 @@ package cmd
2
2
 
3
3
  import (
4
4
  "bytes"
5
+ "fmt"
5
6
  "io"
6
7
  "net/http"
7
8
  "net/http/httptest"
@@ -496,6 +497,9 @@ func TestQueryResultDownloadsCompletedVideo(t *testing.T) {
496
497
  if got["completed"] != true {
497
498
  t.Fatalf("completed = %v, want true", got["completed"])
498
499
  }
500
+ if got["status"] != "succeeded" {
501
+ t.Fatalf("status = %v, want succeeded", got["status"])
502
+ }
499
503
  if got["thread_id"] != "thread_123" || got["run_id"] != "run_456" {
500
504
  t.Fatalf("ids = (%v, %v), want thread/run ids", got["thread_id"], got["run_id"])
501
505
  }
@@ -600,6 +604,9 @@ func TestQueryResultIgnoresVideoDataWithoutVideoSubType(t *testing.T) {
600
604
  if got["completed"] != false {
601
605
  t.Fatalf("completed = %v, want false", got["completed"])
602
606
  }
607
+ if got["status"] != "unknown" {
608
+ t.Fatalf("status = %v, want unknown", got["status"])
609
+ }
603
610
  if got["thread_id"] != "thread_123" || got["run_id"] != "run_456" {
604
611
  t.Fatalf("ids = (%v, %v), want thread/run ids", got["thread_id"], got["run_id"])
605
612
  }
@@ -628,6 +635,9 @@ func TestQueryResultValidationErrorReturnsJSON(t *testing.T) {
628
635
  if got["completed"] != false {
629
636
  t.Fatalf("completed = %v, want false", got["completed"])
630
637
  }
638
+ if got["status"] != "unknown" {
639
+ t.Fatalf("status = %v, want unknown", got["status"])
640
+ }
631
641
  if got["thread_id"] != "" || got["run_id"] != "run_456" {
632
642
  t.Fatalf("ids = (%v, %v), want empty thread_id and run_id", got["thread_id"], got["run_id"])
633
643
  }
@@ -664,12 +674,15 @@ func TestQueryResultGetThreadBusinessErrorReturnsErrorMessage(t *testing.T) {
664
674
  t.Fatalf("Execute() error = %v, stderr = %s", err, stderr.String())
665
675
  }
666
676
  got := decodeJSON(t, stdout.Bytes())
667
- if got["completed"] != true {
668
- t.Fatalf("completed = %v, want true", got["completed"])
677
+ if got["completed"] != false {
678
+ t.Fatalf("completed = %v, want false", got["completed"])
669
679
  }
670
680
  if got["thread_id"] != "thread_123" || got["run_id"] != "run_456" {
671
681
  t.Fatalf("ids = (%v, %v), want thread/run ids", got["thread_id"], got["run_id"])
672
682
  }
683
+ if got["status"] != "unknown" {
684
+ t.Fatalf("status = %v, want unknown", got["status"])
685
+ }
673
686
  if got["error_message"] != "创作失败:暂时无法生成 log_id=log_456" {
674
687
  t.Fatalf("error_message = %v, want get_thread business error", got["error_message"])
675
688
  }
@@ -706,6 +719,9 @@ func TestQueryResultFailedReturnsErrorMessage(t *testing.T) {
706
719
  if got["completed"] != true {
707
720
  t.Fatalf("completed = %v, want true", got["completed"])
708
721
  }
722
+ if got["status"] != "failed" {
723
+ t.Fatalf("status = %v, want failed", got["status"])
724
+ }
709
725
  if _, ok := got["state"]; ok {
710
726
  t.Fatalf("state should not be returned: %#v", got)
711
727
  }
@@ -745,6 +761,9 @@ func TestQueryResultPendingDoesNotDownload(t *testing.T) {
745
761
  if got["completed"] != false {
746
762
  t.Fatalf("completed = %v, want false", got["completed"])
747
763
  }
764
+ if got["status"] != "running" {
765
+ t.Fatalf("status = %v, want running", got["status"])
766
+ }
748
767
  if _, ok := got["state"]; ok {
749
768
  t.Fatalf("state should not be returned: %#v", got)
750
769
  }
@@ -757,6 +776,58 @@ func TestQueryResultPendingDoesNotDownload(t *testing.T) {
757
776
  }
758
777
  }
759
778
 
779
+ func TestQueryResultRunStateMapping(t *testing.T) {
780
+ // state=3 needs artifacts and is covered by the dedicated success tests;
781
+ // every other state must map deterministically, including unknown values.
782
+ tests := []struct {
783
+ state int
784
+ wantStatus string
785
+ wantCompleted bool
786
+ }{
787
+ {0, "unknown", false},
788
+ {1, "running", false},
789
+ {2, "running", false},
790
+ {4, "failed", true},
791
+ {5, "canceled", true},
792
+ {6, "unknown", false},
793
+ {7, "running", false},
794
+ {8, "running", false},
795
+ {9, "unknown", false},
796
+ {99, "unknown", false},
797
+ }
798
+ for _, tt := range tests {
799
+ t.Run(fmt.Sprintf("state=%d", tt.state), func(t *testing.T) {
800
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
801
+ if r.URL.Path != "/api/biz/v1/skill/get_thread" {
802
+ t.Fatalf("unexpected path %s", r.URL.Path)
803
+ }
804
+ payload := fmt.Sprintf(`{"ret":"0","data":{"thread":{"thread_id":"thread_123","run_list":[{"run_id":"run_456","state":%d}]}}}`, tt.state)
805
+ _, _ = w.Write([]byte(payload))
806
+ }))
807
+ defer server.Close()
808
+
809
+ var stdout, stderr bytes.Buffer
810
+ root := newTestRootCommand(t, &stdout, &stderr, server.URL)
811
+ root.SetArgs([]string{
812
+ "query-result",
813
+ "--thread-id", "thread_123",
814
+ "--run-id", "run_456",
815
+ "--download-dir", t.TempDir(),
816
+ })
817
+ if err := root.Execute(); err != nil {
818
+ t.Fatalf("Execute() error = %v, stderr = %s", err, stderr.String())
819
+ }
820
+ got := decodeJSON(t, stdout.Bytes())
821
+ if got["status"] != tt.wantStatus {
822
+ t.Fatalf("status = %v, want %s", got["status"], tt.wantStatus)
823
+ }
824
+ if got["completed"] != tt.wantCompleted {
825
+ t.Fatalf("completed = %v, want %v", got["completed"], tt.wantCompleted)
826
+ }
827
+ })
828
+ }
829
+ }
830
+
760
831
  func serverURL(r *http.Request) string {
761
832
  return "http://" + r.Host
762
833
  }
@@ -1,6 +1,6 @@
1
- 718067da81039c982cdcb9579f50a06a83bbc7c7dd599ab447b50e8b8e2b13ac pippit-tool-cli-1.0.48-darwin-amd64.tar.gz
2
- d0aa4e2272c8369fb615b82bbb390a3e575e3b3df39dffbb5d38c6fc8e7d67c3 pippit-tool-cli-1.0.48-darwin-arm64.tar.gz
3
- 838f221cef34481f042a2fec32da0f015d5c61151f43eeb3460ceb94c05601fd pippit-tool-cli-1.0.48-linux-amd64.tar.gz
4
- 1ff3d84ffe6a04bc6c5ed92d9e784308d8dc16fffc88037faa21665d9a74106c pippit-tool-cli-1.0.48-linux-arm64.tar.gz
5
- 04400b90e115ba0d9d8e0d6917e8b69cfe980fa5601bd5c9bdb2625135036d5e pippit-tool-cli-1.0.48-windows-amd64.zip
6
- e6a2f024b93abcc546007fe1c5e2fcaebed11ab64123943c30dda9f47f8c4b63 pippit-tool-cli-1.0.48-windows-arm64.zip
1
+ a458435d1197a30b707df6a462f8226a7e0712a68321e80122f94c2adc1de6b5 pippit-tool-cli-1.0.50-darwin-amd64.tar.gz
2
+ f2d521422ef4e4ac1f4a8ce1111f8bffd2b29a70e83cbaf5b931354085894152 pippit-tool-cli-1.0.50-darwin-arm64.tar.gz
3
+ 5655d75170e4e6616e12ba2f6c05849381b5eca14b70b4e5273357c457c90d85 pippit-tool-cli-1.0.50-linux-amd64.tar.gz
4
+ c38ae24da3a18c9ce295a67523a3608da4c8fa10a1e125c03b07d635372f1894 pippit-tool-cli-1.0.50-linux-arm64.tar.gz
5
+ a02ee4dfd051201fbbf84188d7969ec3be3ffa8a0ef70e0ac7fd94a307fce6af pippit-tool-cli-1.0.50-windows-amd64.zip
6
+ 72f17b0945d8619ff5a80da26d474e8d4e30f56b4c70d0c01f838ae3fd8080b9 pippit-tool-cli-1.0.50-windows-arm64.zip