@pippit-dev/cli 0.0.15 → 0.0.17

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
@@ -13,7 +13,7 @@ export XYQ_ACCESS_KEY="<access-key>"
13
13
  pippit-tool-cli --version
14
14
  pippit-tool-cli short-drama +submit-run --message "写一个赛博朋克短剧开头"
15
15
  pippit-tool-cli short-drama +upload-file --path ./reference.doc
16
- pippit-tool-cli short-drama +get-thread --thread-id thread_123 --run-id run_456 --after-seq 0
16
+ pippit-tool-cli short-drama +get-thread --thread-id thread_123 --run-id run_456
17
17
  pippit-tool-cli short-drama +download-result --output-path ./thread_123/results/result.mp4 --url URL
18
18
  ```
19
19
 
@@ -27,17 +27,17 @@ export XYQ_ACCESS_KEY="<access-key>"
27
27
  go run . --version
28
28
  go run . short-drama +submit-run --message "写一个赛博朋克短剧开头"
29
29
  go run . short-drama +upload-file --path ./reference.doc
30
- go run . short-drama +get-thread --thread-id thread_123 --run-id run_456 --after-seq 0
30
+ go run . short-drama +get-thread --thread-id thread_123 --run-id run_456
31
31
  go run . short-drama +download-result --output-path ./thread_123/results/result.mp4 --url URL
32
32
  ```
33
33
 
34
34
  `+submit-run` calls `/api/biz/v1/skill/submit_run` and prints `thread_id`,
35
35
  `run_id`, and `web_thread_link`; `--message` is required.
36
36
  `+get-thread` calls
37
- `/api/biz/v1/skill/get_thread` and prints extracted `messages`.
37
+ `/api/biz/v1/skill/get_thread` with `version=v2` and prints `readable_text`.
38
38
  `+upload-file` calls `/api/biz/v1/skill/upload_file` with
39
39
  `multipart/form-data` and prints the returned `asset_id`.
40
- Only `.doc` and `.txt` file extensions are supported.
40
+ Only `.doc`, `.docx`, and `.txt` file extensions are supported.
41
41
  `+download-result` downloads the result URL to
42
42
  the `--output-path` file path.
43
43
 
package/checksums.txt CHANGED
@@ -1,6 +1,6 @@
1
- fa8c1c2792f7d35d5cc3d404d54f3739b27d293f752109a12b1eb472a42cb137 pippit-tool-cli-0.0.15-darwin-amd64.tar.gz
2
- b7fea091af69a21d3817af90781c89c45c2c3a7eebfbcaf9c7d1cc4ed5817661 pippit-tool-cli-0.0.15-darwin-arm64.tar.gz
3
- 8efb9fbdf2bcb67444ace90f376b82f81b6e7d28c17f8a63cf3f659796ec4a9f pippit-tool-cli-0.0.15-linux-amd64.tar.gz
4
- 6e9b689ca808704d551967abdf9e3bf7bbb462e8f87978b9f5f8d09c49ae8e31 pippit-tool-cli-0.0.15-linux-arm64.tar.gz
5
- 1dcb53bd959026ddcae51c2cf50174ab90c900875992c28b3d568cf88fcb5408 pippit-tool-cli-0.0.15-windows-amd64.zip
6
- 4c1cdaea7521d9600ad33a2091e078104a5891d7950c527bc05176bd0cf2ffba pippit-tool-cli-0.0.15-windows-arm64.zip
1
+ dc08d1d25fe9fb2d2ed4dc5c2dec42b999ffe9f42f7dfac723d50f85d9107099 pippit-tool-cli-0.0.17-darwin-amd64.tar.gz
2
+ f696c2aec0901638716b5037231fd47916c557b6157c1dcff559c894d7992c5a pippit-tool-cli-0.0.17-darwin-arm64.tar.gz
3
+ ee4386da9ba02e5dfd93786b319e42af2a41c1fa01c20151232b87ebc81ef343 pippit-tool-cli-0.0.17-linux-amd64.tar.gz
4
+ 795c624e273acb9edb0f4851d767d4f58b947e8dc056a7246a64bbb30b085bc1 pippit-tool-cli-0.0.17-linux-arm64.tar.gz
5
+ 0e3eb11d38fd04686317df1185195e12180265b9bd7bbb1de2b68a145d72f339 pippit-tool-cli-0.0.17-windows-amd64.zip
6
+ acccf51f98a58f3d887a6e2c9131b8acbbc246b6c518ebe8c26b28ad20ed0a54 pippit-tool-cli-0.0.17-windows-arm64.zip
@@ -138,14 +138,14 @@ func newShortDramaGetThreadCommand(stdout, stderr io.Writer, runner *common.Runn
138
138
  if err != nil {
139
139
  return err
140
140
  }
141
- return writeJSON(stdout, result)
141
+ _, err = fmt.Fprintln(stdout, result.ReadableText)
142
+ return err
142
143
  },
143
144
  }
144
145
  cmd.SetOut(stdout)
145
146
  cmd.SetErr(stderr)
146
147
  cmd.Flags().StringVar(&opts.ThreadID, "thread-id", "", "thread ID to fetch")
147
148
  cmd.Flags().StringVar(&opts.RunID, "run-id", "", "run ID to fetch")
148
- cmd.Flags().IntVar(&opts.AfterSeq, "after-seq", 0, "return messages whose sequence is greater than or equal to this value")
149
149
  return cmd
150
150
  }
151
151
 
@@ -196,11 +196,11 @@ func TestShortDramaUploadFile(t *testing.T) {
196
196
  if len(files) != 1 {
197
197
  t.Fatalf("file parts = %d, want 1", len(files))
198
198
  }
199
- if files[0].Filename != "story.txt" {
200
- t.Fatalf("filename = %q, want story.txt", files[0].Filename)
199
+ if files[0].Filename != "story.docx" {
200
+ t.Fatalf("filename = %q, want story.docx", files[0].Filename)
201
201
  }
202
- if got := files[0].Header.Get("Content-Type"); got != "text/plain; charset=utf-8" {
203
- t.Fatalf("Content-Type = %q, want text/plain; charset=utf-8", got)
202
+ if got := files[0].Header.Get("Content-Type"); got != "application/vnd.openxmlformats-officedocument.wordprocessingml.document" {
203
+ t.Fatalf("Content-Type = %q, want docx content type", got)
204
204
  }
205
205
  file, err := files[0].Open()
206
206
  if err != nil {
@@ -211,16 +211,16 @@ func TestShortDramaUploadFile(t *testing.T) {
211
211
  if err != nil {
212
212
  t.Fatalf("ReadAll multipart file: %v", err)
213
213
  }
214
- if string(data) != "txt-data" {
215
- t.Fatalf("file content = %q, want txt-data", string(data))
214
+ if string(data) != "docx-data" {
215
+ t.Fatalf("file content = %q, want docx-data", string(data))
216
216
  }
217
217
  _, _ = w.Write([]byte(`{"ret":"0","errmsg":"","data":{"pippit_asset_id":"asset_123"}}`))
218
218
  }))
219
219
  defer server.Close()
220
220
 
221
221
  cwd := chdirTemp(t)
222
- path := filepath.Join(cwd, "story.txt")
223
- if err := os.WriteFile(path, []byte("txt-data"), 0o644); err != nil {
222
+ path := filepath.Join(cwd, "story.docx")
223
+ if err := os.WriteFile(path, []byte("docx-data"), 0o644); err != nil {
224
224
  t.Fatalf("WriteFile(): %v", err)
225
225
  }
226
226
 
@@ -292,7 +292,7 @@ func TestShortDramaUploadFileRejectsUnsupportedFileType(t *testing.T) {
292
292
  if err == nil {
293
293
  t.Fatal("Execute() error = nil, want file type validation error")
294
294
  }
295
- if !strings.Contains(err.Error(), "only .doc and .txt uploads are supported") {
295
+ if !strings.Contains(err.Error(), "only .doc, .docx, and .txt uploads are supported") {
296
296
  t.Fatalf("error = %q, want unsupported type validation", err)
297
297
  }
298
298
  }
@@ -569,10 +569,13 @@ func TestShortDramaGetThread(t *testing.T) {
569
569
  if body["run_id"] != "run_456" {
570
570
  t.Fatalf("run_id = %v, want run_456", body["run_id"])
571
571
  }
572
- if body["after_seq"] != float64(7) {
573
- t.Fatalf("after_seq = %v, want 7", body["after_seq"])
572
+ if _, ok := body["after_seq"]; ok {
573
+ t.Fatalf("after_seq = %v, want omitted", body["after_seq"])
574
574
  }
575
- _, _ = w.Write([]byte(`{"ret":"0","errmsg":"","data":{"thread":{"run_list":[{"state":3,"entry_list":[{"message":{"message_id":"msg_1","role":"assistant","content":[{"text":"hello"}],"client_tool_calls":[{"name":"tool_call"}]}},{"artifact":{"artifact_id":"artifact_1","role":"assistant","content":[{"type":"image"}]}}]}]}}}`))
575
+ if body["version"] != "v2" {
576
+ t.Fatalf("version = %v, want v2", body["version"])
577
+ }
578
+ _, _ = w.Write([]byte(`{"ret":"0","errmsg":"","data":{"readable_text":"Thread: thread_123\n [assistant] hello"}}`))
576
579
  }))
577
580
  defer server.Close()
578
581
 
@@ -582,28 +585,14 @@ func TestShortDramaGetThread(t *testing.T) {
582
585
  "short-drama", "+get-thread",
583
586
  "--thread-id", "thread_123",
584
587
  "--run-id", "run_456",
585
- "--after-seq", "7",
586
588
  })
587
589
 
588
590
  if err := root.Execute(); err != nil {
589
591
  t.Fatalf("Execute() error = %v, stderr = %s", err, stderr.String())
590
592
  }
591
593
 
592
- got := decodeJSON(t, stdout.Bytes())
593
- messages, ok := got["messages"].([]any)
594
- if !ok || len(messages) != 2 {
595
- t.Fatalf("messages = %#v, want two entries", got["messages"])
596
- }
597
- first, ok := messages[0].(map[string]any)
598
- if !ok {
599
- t.Fatalf("first message = %#v, want object", messages[0])
600
- }
601
- if first["id"] != "msg_1" {
602
- t.Fatalf("first id = %v, want msg_1", first["id"])
603
- }
604
- content, ok := first["content"].([]any)
605
- if !ok || len(content) != 2 {
606
- t.Fatalf("first content = %#v, want message content plus tool call", first["content"])
594
+ if got := stdout.String(); got != "Thread: thread_123\n [assistant] hello\n" {
595
+ t.Fatalf("stdout = %#v, want API readable text", got)
607
596
  }
608
597
  }
609
598
 
@@ -36,8 +36,9 @@ type uploadFileResponse struct {
36
36
  const uploadFileFieldName = "file"
37
37
 
38
38
  var allowedUploadExtensions = map[string]bool{
39
- ".doc": true,
40
- ".txt": true,
39
+ ".doc": true,
40
+ ".docx": true,
41
+ ".txt": true,
41
42
  }
42
43
 
43
44
  func UploadFile(ctx context.Context, opts UploadFileOptions, runner *Runner) (*UploadFileResult, error) {
@@ -62,7 +63,7 @@ func UploadFile(ctx context.Context, opts UploadFileOptions, runner *Runner) (*U
62
63
 
63
64
  ext := strings.ToLower(filepath.Ext(path))
64
65
  if !allowedUploadExtensions[ext] {
65
- return nil, fmt.Errorf("unsupported file extension %q; only .doc and .txt uploads are supported", ext)
66
+ return nil, fmt.Errorf("unsupported file extension %q; only .doc, .docx, and .txt uploads are supported", ext)
66
67
  }
67
68
  fileName := filepath.Base(path)
68
69
  contentType := mime.TypeByExtension(ext)
@@ -8,59 +8,27 @@ import (
8
8
  "github.com/Pippit-dev/pippit-cli/internal/config"
9
9
  )
10
10
 
11
+ const getThreadVersionV2 = "v2"
12
+
11
13
  // GetThreadOptions is the stable command-facing request shape for thread lookup.
12
14
  type GetThreadOptions struct {
13
15
  ThreadID string `json:"thread_id"`
14
16
  RunID string `json:"run_id,omitempty"`
15
- AfterSeq int `json:"after_seq"`
16
- }
17
-
18
- // ThreadEntry is a compact message or artifact entry inside a thread run.
19
- type ThreadEntry struct {
20
- ID string `json:"id"`
21
- Role string `json:"role"`
22
- Content []any `json:"content"`
23
17
  }
24
18
 
25
- // GetThreadResult is the JSON envelope printed by `pippit-tool-cli short-drama +get-thread`.
19
+ // GetThreadResult is the parsed get_thread response used by `pippit-tool-cli short-drama +get-thread`.
26
20
  type GetThreadResult struct {
27
- Messages []*ThreadEntry `json:"messages"`
21
+ ReadableText string `json:"readable_text"`
28
22
  }
29
23
 
30
24
  type getThreadResponse struct {
31
25
  Ret string `json:"ret"`
32
26
  Errmsg string `json:"errmsg"`
33
27
  Data struct {
34
- Thread struct {
35
- RunList []getThreadRun `json:"run_list"`
36
- } `json:"thread"`
28
+ ReadableText string `json:"readable_text"`
37
29
  } `json:"data"`
38
30
  }
39
31
 
40
- type getThreadRun struct {
41
- State int `json:"state"`
42
- FailReason string `json:"fail_reason"`
43
- EntryList []getThreadEntry `json:"entry_list"`
44
- }
45
-
46
- type getThreadEntry struct {
47
- Message *getThreadMessage `json:"message"`
48
- Artifact *getThreadArtifact `json:"artifact"`
49
- }
50
-
51
- type getThreadMessage struct {
52
- MessageID string `json:"message_id"`
53
- Role string `json:"role"`
54
- Content []any `json:"content"`
55
- ClientToolCalls []any `json:"client_tool_calls"`
56
- }
57
-
58
- type getThreadArtifact struct {
59
- ArtifactID string `json:"artifact_id"`
60
- Role string `json:"role"`
61
- Content []any `json:"content"`
62
- }
63
-
64
32
  func GetThread(ctx context.Context, opts *GetThreadOptions, runner *common.Runner) (*GetThreadResult, error) {
65
33
  if runner == nil || runner.Client == nil {
66
34
  return nil, fmt.Errorf("get_thread runner client is required")
@@ -68,7 +36,7 @@ func GetThread(ctx context.Context, opts *GetThreadOptions, runner *common.Runne
68
36
 
69
37
  body := map[string]any{
70
38
  "thread_id": opts.ThreadID,
71
- "after_seq": opts.AfterSeq,
39
+ "version": getThreadVersionV2,
72
40
  }
73
41
  if opts.RunID != "" {
74
42
  body["run_id"] = opts.RunID
@@ -84,51 +52,15 @@ func GetThread(ctx context.Context, opts *GetThreadOptions, runner *common.Runne
84
52
  }
85
53
  return nil, fmt.Errorf("get_thread failed: ret=%s errmsg=%s", resp.Ret, resp.Errmsg)
86
54
  }
87
- if len(resp.Data.Thread.RunList) == 0 {
88
- return nil, fmt.Errorf("get_thread response missing data.thread.run_list")
89
- }
90
-
91
- run := resp.Data.Thread.RunList[0]
92
- // 4: failed
93
- // 5: canceled
94
- if run.State == 4 {
95
- if run.FailReason == "" {
96
- run.FailReason = "unknown failure"
97
- }
98
- return nil, fmt.Errorf("get_thread run failed: %s", run.FailReason)
99
- }
100
- if run.State == 5 {
101
- return nil, fmt.Errorf("get_thread run canceled")
55
+ if resp.Data.ReadableText == "" {
56
+ return nil, fmt.Errorf("get_thread response missing data.readable_text")
102
57
  }
103
58
 
104
59
  return &GetThreadResult{
105
- Messages: extractThreadEntries(run),
60
+ ReadableText: resp.Data.ReadableText,
106
61
  }, nil
107
62
  }
108
63
 
109
- func extractThreadEntries(run getThreadRun) []*ThreadEntry {
110
- entries := make([]*ThreadEntry, 0, len(run.EntryList))
111
- for _, entry := range run.EntryList {
112
- if entry.Message != nil {
113
- content := append([]any(nil), entry.Message.Content...)
114
- content = append(content, entry.Message.ClientToolCalls...)
115
- entries = append(entries, &ThreadEntry{
116
- ID: entry.Message.MessageID,
117
- Role: entry.Message.Role,
118
- Content: content,
119
- })
120
- }
121
- if entry.Artifact != nil {
122
- entries = append(entries, &ThreadEntry{
123
- ID: entry.Artifact.ArtifactID,
124
- Role: entry.Artifact.Role,
125
- Content: entry.Artifact.Content,
126
- })
127
- }
128
- }
129
- return entries
130
- }
131
-
132
64
  func getThreadPath(runner *common.Runner) string {
133
65
  if runner != nil && runner.Config != nil && runner.Config.Paths != nil && runner.Config.Paths.GetThread != "" {
134
66
  return runner.Config.Paths.GetThread
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pippit-dev/cli",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "Pippit CLI",
5
5
  "bin": {
6
6
  "pippit-tool-cli": "scripts/run.js"
@@ -24,8 +24,8 @@ metadata:
24
24
  ## 功能
25
25
 
26
26
  1. **提交短剧 Run 任务** - 创建新会话或向已有会话发送短剧创作需求。
27
- 2. **查询会话进展** - 根据 `thread_id`、`run_id`、`after_seq` 拉取短剧任务消息列表。
28
- 3. **上传文件** - 上传本地 `.doc` / `.txt` 参考文件,得到 `asset_id`,供后续任务引用。
27
+ 2. **查询会话进展** - 根据 `thread_id` 和可选 `run_id` 拉取服务端 v2 `readable_text`,用于展示短剧任务进展、问题和结果。
28
+ 3. **上传文件** - 上传本地 `.doc` / `.docx` / `.txt` 参考文件,得到 `asset_id`,供后续任务引用。
29
29
  4. **获取会话文件** - 根据 `thread_id` 拉取会话文件列表,得到 `file_path`、`download_url`。这和查询会话进展同等重要。
30
30
  5. **下载重要资产** - 使用文件列表中的 `download_url` 下载资源,并按 `file_path` 写入用户本地目标文件路径。
31
31
 
@@ -57,15 +57,15 @@ pippit-tool-cli short-drama +submit-run --message "参考这个大纲写第一
57
57
  ### 2. 查询短剧任务进展
58
58
 
59
59
  ```bash
60
- # 查询会话消息列表
61
- pippit-tool-cli short-drama +get-thread --thread-id THREAD_ID --run-id RUN_ID --after-seq 0
60
+ # 查询会话可读进展
61
+ pippit-tool-cli short-drama +get-thread --thread-id THREAD_ID --run-id RUN_ID
62
62
  ```
63
63
 
64
- > `thread_id` 和 `run_id` 由 `+submit-run` 返回。`after-seq` 用于增量拉取消息,首次查询可使用 `0`。
64
+ > `thread_id` 和 `run_id` 由 `+submit-run` 返回。`run_id` 可省略,省略时返回当前 `thread_id` 下的所有 Run;传入时只看指定 Run。
65
65
 
66
66
  ### 3. 上传文件
67
67
 
68
- 当用户提供短剧大纲、人物设定、世界观设定、已有分集或剧本等本地参考文件时,可先上传文件。`+upload-file` 当前只接收本地文件路径,并且只支持 `.doc` 和 `.txt` 后缀;不要把 `.md`、`.pdf`、图片、视频或 URL 传给该命令。
68
+ 当用户提供短剧大纲、人物设定、世界观设定、已有分集或剧本等本地参考文件时,可先上传文件。`+upload-file` 当前只接收本地文件路径,并且只支持 `.doc`、`.docx` 和 `.txt` 后缀;不要把 `.md`、`.pdf`、图片、视频或 URL 传给该命令。
69
69
 
70
70
  ```bash
71
71
  pippit-tool-cli short-drama +upload-file --path /path/to/outline.txt
@@ -117,11 +117,11 @@ pippit-tool-cli short-drama +download-result --url DOWNLOAD_URL --output-path FI
117
117
  → 拿到 thread_id、run_id 和 web_thread_link
118
118
  2. 立即将 web_thread_link 展示给用户
119
119
  3. 并行发起,二者同等重要:
120
- a. pippit-tool-cli short-drama +get-thread --thread-id THREAD_ID --run-id RUN_ID --after-seq SEQUENCE
120
+ a. pippit-tool-cli short-drama +get-thread --thread-id THREAD_ID --run-id RUN_ID
121
121
  b. pippit-tool-cli short-drama +list-thread-file --thread-id THREAD_ID --page-num PAGE_NUM --page-size 200
122
- 4. 检查 `get-thread` 返回的 messages
123
- - 如果任务仍在进行中:展示过程消息,继续查询
124
- - 如果后端 Agent 提出问题:展示问题,等待用户回复
122
+ 4. 检查 `get-thread` 返回的 readable_text
123
+ - 如果任务仍在进行中:展示可读进展,继续查询
124
+ - 如果后端 Agent 提出问题:从 readable_text 中提取问题并展示,等待用户回复
125
125
  5. 检查 `list-thread-file` 返回的 files:
126
126
  - 对每个文件取 file_path、download_url
127
127
  - 将 file_path 作为本地目标文件路径,包含文件名
@@ -140,7 +140,7 @@ pippit-tool-cli short-drama +download-result --url DOWNLOAD_URL --output-path FI
140
140
  ### 场景 2:用户提供参考文件要求创作
141
141
 
142
142
  ```
143
- 1. 检查用户提供的是一个本地 `.doc` 或 `.txt` 剧本文件路径;如果不是,告知当前上传命令只支持这两类文件,不要擅自转换或改写文件。
143
+ 1. 检查用户提供的是一个本地 `.doc`、`.docx` 或 `.txt` 剧本文件路径;如果不是,告知当前上传命令只支持这三类文件,不要擅自转换或改写文件。
144
144
  2. pippit-tool-cli short-drama +upload-file --path /path/to/file.txt
145
145
  → 拿到 asset_id
146
146
  3. pippit-tool-cli short-drama +submit-run --message "用户的原始短剧需求" --asset-ids asset_id
@@ -161,7 +161,7 @@ pippit-tool-cli short-drama +download-result --url DOWNLOAD_URL --output-path FI
161
161
  ## 轮询策略
162
162
 
163
163
  - **间隔**:每 10 秒查询一次。
164
- - **增量拉取**:首次使用 `--after-seq 0`,后续根据已读消息进度调整 `after-seq`。
164
+ - **进展查询**:每轮调用 `+get-thread` 查看 `readable_text`。优先带上本轮 `run_id` 聚焦当前任务;需要查看整个会话时可省略 `--run-id`。
165
165
  - **并行查询**:每次 `+submit-run` 返回 `thread_id` 后,同时发起 `+get-thread` 和 `+list-thread-file`;二者同等重要,不能只查询会话进展而忽略会话文件。
166
166
  - **文件分页**:`+list-thread-file` 使用 `--page-size 200`。如果本轮返回的 `total` 达到 200,下一轮使用 `--page-num` 加 1 查询新一页结果;如果未达到 200,保持当前页继续轮询新增产物。
167
167
  - **重要资产识别**:每轮都检查 `+list-thread-file` 返回的文件。剧本设计、场景设计、场景图、人物角色设计、人物图、分集草稿、故事板、最终视频产物都是重要资产。
@@ -173,9 +173,9 @@ pippit-tool-cli short-drama +download-result --url DOWNLOAD_URL --output-path FI
173
173
 
174
174
  ## 完成标准
175
175
 
176
- 一次短剧任务不能只以 `+get-thread` 返回完成消息作为结束条件。完成前必须同时检查:
176
+ 一次短剧任务不能只以 `+get-thread` 返回的 `readable_text` 作为结束条件。完成前必须同时检查:
177
177
 
178
- 1. 已处理 `+get-thread` 返回的最新会话进展、用户确认问题和最终消息。
178
+ 1. 已处理 `+get-thread` 返回的最新 `readable_text`、用户确认问题和最终消息。
179
179
  2. 已用 `--page-size 200` 调用 `+list-thread-file` 获取会话文件列表;如果本轮 `total` 达到 200,已在后续轮询中递增 `page-num` 查询新一页。
180
180
  3. 对所有带 `download_url` 的重要资产,已调用 `+download-result` 下载到本地 `file_path`。
181
181
  4. 对查询失败或下载失败的资产,已在后续轮询中主动重试,并在最终回复中列出仍失败的文件或命令。
@@ -194,21 +194,13 @@ pippit-tool-cli short-drama +download-result --url DOWNLOAD_URL --output-path FI
194
194
 
195
195
  **+get-thread** 返回:
196
196
 
197
- ```json
198
- {
199
- "messages": [
200
- {
201
- "id": "message_...",
202
- "role": "assistant",
203
- "content": [
204
- {
205
- "type": "text",
206
- "data": {}
207
- }
208
- ]
209
- }
210
- ]
211
- }
197
+ ```text
198
+ Thread: thread_...
199
+ 标题: ...
200
+ 状态: ...
201
+
202
+ -- Run #1 --
203
+ [assistant] ...
212
204
  ```
213
205
 
214
206
  **+upload-file** 返回:
@@ -219,7 +211,7 @@ pippit-tool-cli short-drama +download-result --url DOWNLOAD_URL --output-path FI
219
211
  }
220
212
  ```
221
213
 
222
- `+upload-file` 通过 `multipart/form-data` 上传文件,表单文件字段名为 `file`。本地文件必须存在、不能是目录,后缀必须是 `.doc` 或 `.txt`;不支持的后缀会直接报错。返回的 `asset_id` 来自服务端 `pippit_asset_id`,如果没有该字段才回退到 `asset_id`。
214
+ `+upload-file` 通过 `multipart/form-data` 上传文件,表单文件字段名为 `file`。本地文件必须存在、不能是目录,后缀必须是 `.doc`、`.docx` 或 `.txt`;不支持的后缀会直接报错。返回的 `asset_id` 来自服务端 `pippit_asset_id`,如果没有该字段才回退到 `asset_id`。
223
215
 
224
216
  **+list-thread-file** 返回:
225
217
 
@@ -253,7 +245,7 @@ pippit-tool-cli short-drama +download-result --url DOWNLOAD_URL --output-path FI
253
245
 
254
246
  ### 获取会话文件
255
247
 
256
- 从 `+list-thread-file` 的 `files` 中逐个读取文件元信息:`file_path`、`download_url`。重点识别剧本大纲、故事线设计、场景设计说明、场景图、人物角色设计说明、人物图、分集草稿、分镜片段视频、故事板、最终视频产物等重要资产。
248
+ 从 `+list-thread-file` 的 `files` 中逐个读取文件元信息:`file_path`、`file_name`、`download_url`。重点识别剧本设计、场景设计、场景图、人物角色设计、人物图、分集草稿、故事板、最终视频产物等重要资产。
257
249
 
258
250
  ```
259
251
  1. 有download_url的重要资产
@@ -291,9 +283,9 @@ pippit-tool-cli short-drama +download-result --url DOWNLOAD_URL --output-path FI
291
283
 
292
284
  你要做的只有三件事:
293
285
 
294
- 1. **上传**:如果用户给了本地 `.doc` / `.txt` 参考文件,先调用 `+upload-file`。
286
+ 1. **上传**:如果用户给了本地 `.doc` / `.docx` / `.txt` 参考文件,先调用 `+upload-file`。
295
287
  2. **提交任务**:首次创作时把用户原始短剧需求和唯一剧本 `asset_id` 通过 `+submit-run --asset-ids` 发给后端;同一 `thread_id` 后续续写或修改不再追加新的剧本文件。
296
- 3. **传话、取文件、下载资源**:根据 `+get-thread` 返回的消息展示进展、问题和结果;根据 `+list-thread-file` 获取文件列表;再根据 `download_url` 调用 `+download-result` 把缺失资源下载到用户本地。
288
+ 3. **传话、取文件、下载资源**:根据 `+get-thread` 返回的 `readable_text` 展示进展、问题和结果;根据 `+list-thread-file` 获取文件列表;再根据 `download_url` 调用 `+download-result` 把缺失资源下载到用户本地。
297
289
 
298
290
  **不要做的事:**
299
291
 
@@ -307,9 +299,9 @@ pippit-tool-cli short-drama +download-result --url DOWNLOAD_URL --output-path FI
307
299
  ## 注意事项
308
300
 
309
301
  - `--message` 是用户的原始短剧需求,不能为空。
310
- - 查询进展时优先使用 `+submit-run` 返回的 `thread_id` 和 `run_id`。
311
- - `--after-seq` 用于增量拉取消息,首次查询可设置为 `0`。
312
- - `+upload-file` 当前用于短剧场景文件上传链路,只支持本地 `.doc` / `.txt` 文件;`--path` 不能为空,路径必须指向真实文件,不能是目录。
302
+ - 查询进展时优先使用 `+submit-run` 返回的 `thread_id` 和 `run_id`;如果需要查看整个会话,可以省略 `--run-id`。
303
+ - `+get-thread` 当前固定走服务端 v2 响应,输出字段是 `readable_text`;不要解析旧版 `messages` 数组。
304
+ - `+upload-file` 当前用于短剧场景文件上传链路,只支持本地 `.doc` / `.docx` / `.txt` 文件;`--path` 不能为空,路径必须指向真实文件,不能是目录。
313
305
  - `+upload-file` 上传成功后只返回 `asset_id`;把该值原样作为 `+submit-run --asset-ids` 的参数。
314
306
  - 单次创作会话中(相同 `thread_id`),`+submit-run` 只支持绑定一个剧本文件。不要在同一 `thread_id` 下重复上传并追加第二个剧本 `asset_id`;用户给多个剧本时,先让用户选择一个,或分别开启新的创作会话。
315
307
  - `+list-thread-file` 只需要 `thread_id`;分页参数使用 `--page-num 1 --page-size 200` 起步,`total` 达到 200 时下一轮递增 `page-num`。
@@ -1,47 +0,0 @@
1
- package short_drama
2
-
3
- import (
4
- "context"
5
- "crypto/sha1"
6
- "encoding/hex"
7
- )
8
-
9
- // MockClient returns deterministic IDs so the demo chain is easy to test.
10
- type MockClient struct{}
11
-
12
- func (MockClient) SubmitRun(ctx context.Context, opts SubmitRunOptions) (*SubmitRunResult, error) {
13
- if err := ctx.Err(); err != nil {
14
- return nil, err
15
- }
16
- key := opts.ThreadID + "\x00" + opts.Message
17
- id := stableIDMock(key, 12)
18
- return &SubmitRunResult{
19
- ThreadID: "thread_mock_" + id[:6],
20
- RunID: "run_mock_" + id[6:],
21
- WebThreadLink: "https://xyq.jianying.com/mock/thread_mock_" + id[:6],
22
- }, nil
23
- }
24
-
25
- func (MockClient) GetThread(ctx context.Context, opts GetThreadOptions) (*GetThreadResult, error) {
26
- if err := ctx.Err(); err != nil {
27
- return nil, err
28
- }
29
- return &GetThreadResult{
30
- Messages: []*ThreadEntry{
31
- {
32
- ID: "message_mock_" + stableIDMock(opts.ThreadID, 8),
33
- Role: "assistant",
34
- Content: []any{"mock thread message"},
35
- },
36
- },
37
- }, nil
38
- }
39
-
40
- func stableIDMock(key string, n int) string {
41
- sum := sha1.Sum([]byte(key))
42
- id := hex.EncodeToString(sum[:])
43
- if n > len(id) {
44
- return id
45
- }
46
- return id[:n]
47
- }