@pippit-dev/cli 0.0.7 → 0.0.9
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/checksums.txt +6 -6
- package/cmd/short_drama/short_drama.go +3 -3
- package/cmd/short_drama_test.go +31 -17
- package/internal/common/download_results.go +0 -11
- package/internal/common/list_thread_file.go +6 -2
- package/package.json +2 -1
- package/scripts/run.js +3 -0
- package/scripts/version-check.js +96 -0
- package/skills/short-drama/SKILL.md +10 -10
package/checksums.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
3f9cf3a1fabbc3d178c89c3d8044c18d86110faf7d26ffa469930319d13d68e6 pippit-cli-0.0.9-darwin-amd64.tar.gz
|
|
2
|
+
5e14f8ce6034564d9646918e49f8f2d7b6178708518b528c3f95a0af67bd3cd5 pippit-cli-0.0.9-darwin-arm64.tar.gz
|
|
3
|
+
91e90ab17b577b402c7676965b701df7d317b90a2e2b717929bdadce96158a71 pippit-cli-0.0.9-linux-amd64.tar.gz
|
|
4
|
+
dad9fe0a930c91c52036290a121d721e7a100e80700b1b90807988a577a79342 pippit-cli-0.0.9-linux-arm64.tar.gz
|
|
5
|
+
62af305df2c5d5b6cfaa615f36cb0f014007ed35df8c4ffdf07b527e09993842 pippit-cli-0.0.9-windows-amd64.zip
|
|
6
|
+
c6d40c79e4bf777ad71caba29191a4fc3a25f34f9643157ce08ec270b8d6eb42 pippit-cli-0.0.9-windows-arm64.zip
|
|
@@ -164,8 +164,8 @@ func newShortDramaListThreadFileCommand(stdout, stderr io.Writer, runner *common
|
|
|
164
164
|
if opts.ThreadID == "" {
|
|
165
165
|
return fmt.Errorf("--thread-id is required")
|
|
166
166
|
}
|
|
167
|
-
if opts.PageSize <= 0 || opts.PageSize >
|
|
168
|
-
return fmt.Errorf("--page-size must be between 1 and
|
|
167
|
+
if opts.PageSize <= 0 || opts.PageSize > common.MaxListThreadFilePageSize {
|
|
168
|
+
return fmt.Errorf("--page-size must be between 1 and %d", common.MaxListThreadFilePageSize)
|
|
169
169
|
}
|
|
170
170
|
if opts.PageNum <= 0 {
|
|
171
171
|
return fmt.Errorf("--page-num must be greater than 0")
|
|
@@ -182,7 +182,7 @@ func newShortDramaListThreadFileCommand(stdout, stderr io.Writer, runner *common
|
|
|
182
182
|
cmd.SetErr(stderr)
|
|
183
183
|
cmd.Flags().StringVar(&opts.ThreadID, "thread-id", "", "thread ID to list files for")
|
|
184
184
|
cmd.Flags().IntVar(&opts.PageNum, "page-num", 1, "page number (1-based)")
|
|
185
|
-
cmd.Flags().IntVar(&opts.PageSize, "page-size",
|
|
185
|
+
cmd.Flags().IntVar(&opts.PageSize, "page-size", common.MaxListThreadFilePageSize, fmt.Sprintf("number of files per page (between 1 and %d)", common.MaxListThreadFilePageSize))
|
|
186
186
|
return cmd
|
|
187
187
|
}
|
|
188
188
|
|
package/cmd/short_drama_test.go
CHANGED
|
@@ -258,11 +258,12 @@ func TestShortDramaDownloadResultSkipsExistingFile(t *testing.T) {
|
|
|
258
258
|
assertFileContent(t, outputPath, "existing-data")
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
func
|
|
262
|
-
serverCalled := false
|
|
261
|
+
func TestShortDramaDownloadResultDownloadsMetaJSON(t *testing.T) {
|
|
263
262
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
264
|
-
|
|
265
|
-
|
|
263
|
+
if r.URL.Path != "/meta.json" {
|
|
264
|
+
t.Fatalf("path = %s, want meta.json", r.URL.Path)
|
|
265
|
+
}
|
|
266
|
+
_, _ = w.Write([]byte(`{"ok":true}`))
|
|
266
267
|
}))
|
|
267
268
|
defer server.Close()
|
|
268
269
|
|
|
@@ -280,12 +281,6 @@ func TestShortDramaDownloadResultSkipsMetaJSON(t *testing.T) {
|
|
|
280
281
|
if err := root.Execute(); err != nil {
|
|
281
282
|
t.Fatalf("Execute() error = %v, stderr = %s", err, stderr.String())
|
|
282
283
|
}
|
|
283
|
-
if serverCalled {
|
|
284
|
-
t.Fatal("server was called, want meta.json to skip download")
|
|
285
|
-
}
|
|
286
|
-
if _, err := os.Stat(outputPath); !os.IsNotExist(err) {
|
|
287
|
-
t.Fatalf("meta.json stat err = %v, want file to be absent", err)
|
|
288
|
-
}
|
|
289
284
|
|
|
290
285
|
got := decodeJSON(t, stdout.Bytes())
|
|
291
286
|
if got["output_path"] != outputPath {
|
|
@@ -294,10 +289,11 @@ func TestShortDramaDownloadResultSkipsMetaJSON(t *testing.T) {
|
|
|
294
289
|
if _, ok := got["total"]; ok {
|
|
295
290
|
t.Fatalf("total should not be returned: %#v", got)
|
|
296
291
|
}
|
|
297
|
-
|
|
298
|
-
if !ok || len(
|
|
299
|
-
t.Fatalf("
|
|
292
|
+
downloaded, ok := got["downloaded"].([]any)
|
|
293
|
+
if !ok || len(downloaded) != 1 || downloaded[0] != outputPath {
|
|
294
|
+
t.Fatalf("downloaded = %#v, want meta.json output path", got["downloaded"])
|
|
300
295
|
}
|
|
296
|
+
assertFileContent(t, outputPath, `{"ok":true}`)
|
|
301
297
|
}
|
|
302
298
|
|
|
303
299
|
func TestShortDramaDownloadResultRequiresOutputPath(t *testing.T) {
|
|
@@ -557,7 +553,7 @@ func TestShortDramaListThreadFile(t *testing.T) {
|
|
|
557
553
|
if got["total"] != float64(1) {
|
|
558
554
|
t.Fatalf("total = %v, want 1", got["total"])
|
|
559
555
|
}
|
|
560
|
-
wantMessage := "<system-remind>\n- total is below
|
|
556
|
+
wantMessage := "<system-remind>\n- total is below 200; continue querying with current --page-num 2\n</system-remind>"
|
|
561
557
|
if got["message"] != wantMessage {
|
|
562
558
|
t.Fatalf("message = %v, want current page hint", got["message"])
|
|
563
559
|
}
|
|
@@ -586,7 +582,7 @@ func TestShortDramaListThreadFileMessageWhenPageFull(t *testing.T) {
|
|
|
586
582
|
if !strings.Contains(r.URL.Path, "list_thread_file") {
|
|
587
583
|
t.Fatalf("path = %s, want list_thread_file path", r.URL.Path)
|
|
588
584
|
}
|
|
589
|
-
_, _ = w.Write([]byte(`{"ret":"0","errmsg":"","data":{"total":
|
|
585
|
+
_, _ = w.Write([]byte(`{"ret":"0","errmsg":"","data":{"total":200,"files":[]}}`))
|
|
590
586
|
}))
|
|
591
587
|
defer server.Close()
|
|
592
588
|
|
|
@@ -596,7 +592,7 @@ func TestShortDramaListThreadFileMessageWhenPageFull(t *testing.T) {
|
|
|
596
592
|
"short-drama", "+list-thread-file",
|
|
597
593
|
"--thread-id", "thread_123",
|
|
598
594
|
"--page-num", "2",
|
|
599
|
-
"--page-size", "
|
|
595
|
+
"--page-size", "200",
|
|
600
596
|
})
|
|
601
597
|
|
|
602
598
|
if err := root.Execute(); err != nil {
|
|
@@ -604,7 +600,7 @@ func TestShortDramaListThreadFileMessageWhenPageFull(t *testing.T) {
|
|
|
604
600
|
}
|
|
605
601
|
|
|
606
602
|
got := decodeJSON(t, stdout.Bytes())
|
|
607
|
-
wantMessage := "<system-remind>\n- total reached
|
|
603
|
+
wantMessage := "<system-remind>\n- total reached 200; query the next page with --page-num 3\n</system-remind>"
|
|
608
604
|
if got["message"] != wantMessage {
|
|
609
605
|
t.Fatalf("message = %v, want next page hint", got["message"])
|
|
610
606
|
}
|
|
@@ -624,6 +620,24 @@ func TestShortDramaListThreadFileRequiresThreadID(t *testing.T) {
|
|
|
624
620
|
}
|
|
625
621
|
}
|
|
626
622
|
|
|
623
|
+
func TestShortDramaListThreadFileRejectsPageSizeAboveMax(t *testing.T) {
|
|
624
|
+
var stdout, stderr bytes.Buffer
|
|
625
|
+
root := NewRootCommand(&stdout, &stderr)
|
|
626
|
+
root.SetArgs([]string{
|
|
627
|
+
"short-drama", "+list-thread-file",
|
|
628
|
+
"--thread-id", "thread_123",
|
|
629
|
+
"--page-size", "201",
|
|
630
|
+
})
|
|
631
|
+
|
|
632
|
+
err := root.Execute()
|
|
633
|
+
if err == nil {
|
|
634
|
+
t.Fatal("Execute() error = nil, want validation error")
|
|
635
|
+
}
|
|
636
|
+
if !strings.Contains(err.Error(), "--page-size must be between 1 and 200") {
|
|
637
|
+
t.Fatalf("error = %q, want page-size validation", err)
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
627
641
|
func newTestRootCommand(t *testing.T, stdout, stderr io.Writer, baseURL string) *cobra.Command {
|
|
628
642
|
t.Helper()
|
|
629
643
|
return newTestRootCommandWithAccessKey(t, stdout, stderr, baseURL, "test-token")
|
|
@@ -36,7 +36,6 @@ type DownloadResultResponse struct {
|
|
|
36
36
|
OutputPath string `json:"output_path"`
|
|
37
37
|
Downloaded []string `json:"downloaded"`
|
|
38
38
|
AlreadyExist []string `json:"already_exist,omitempty"`
|
|
39
|
-
Skipped []string `json:"skipped,omitempty"`
|
|
40
39
|
Errors []*DownloadResultError `json:"errors,omitempty"`
|
|
41
40
|
}
|
|
42
41
|
|
|
@@ -68,12 +67,6 @@ func DownloadResult(ctx context.Context, opts DownloadResultOptions, runner *Run
|
|
|
68
67
|
if outputPath == "" {
|
|
69
68
|
return nil, fmt.Errorf("output_path is required")
|
|
70
69
|
}
|
|
71
|
-
if shouldSkipDownload(outputPath) {
|
|
72
|
-
return &DownloadResultResponse{
|
|
73
|
-
OutputPath: outputPath,
|
|
74
|
-
Skipped: []string{outputPath},
|
|
75
|
-
}, nil
|
|
76
|
-
}
|
|
77
70
|
// check if the output path exists and is a file
|
|
78
71
|
if info, err := os.Stat(outputPath); err == nil {
|
|
79
72
|
if info.IsDir() {
|
|
@@ -174,10 +167,6 @@ func DownloadResult(ctx context.Context, opts DownloadResultOptions, runner *Run
|
|
|
174
167
|
return result, nil
|
|
175
168
|
}
|
|
176
169
|
|
|
177
|
-
func shouldSkipDownload(outputPath string) bool {
|
|
178
|
-
return filepath.Base(outputPath) == "meta.json"
|
|
179
|
-
}
|
|
180
|
-
|
|
181
170
|
func downloadFileWithRetry(ctx context.Context, client Client, rawURL string, targetPath string) error {
|
|
182
171
|
var lastErr error
|
|
183
172
|
for attempt := 0; attempt <= maxDownloadRetries; attempt++ {
|
|
@@ -9,6 +9,8 @@ import (
|
|
|
9
9
|
"github.com/Pippit-dev/pippit-cli/internal/config"
|
|
10
10
|
)
|
|
11
11
|
|
|
12
|
+
const MaxListThreadFilePageSize = 200
|
|
13
|
+
|
|
12
14
|
// ListThreadFileOptions is the command-facing request shape for listing thread files.
|
|
13
15
|
type ListThreadFileOptions struct {
|
|
14
16
|
ThreadID string `json:"thread_id"`
|
|
@@ -95,8 +97,10 @@ func listThreadFileMessage(total int64, pageNum int) string {
|
|
|
95
97
|
pageNum = 1
|
|
96
98
|
}
|
|
97
99
|
var message string
|
|
98
|
-
if total >=
|
|
99
|
-
message = fmt.Sprintf("total reached
|
|
100
|
+
if total >= MaxListThreadFilePageSize {
|
|
101
|
+
message = fmt.Sprintf("total reached %d; query the next page with --page-num %d", MaxListThreadFilePageSize, pageNum+1)
|
|
102
|
+
} else {
|
|
103
|
+
message = fmt.Sprintf("total is below %d; continue querying with current --page-num %d", MaxListThreadFilePageSize, pageNum)
|
|
100
104
|
}
|
|
101
105
|
return fmt.Sprintf("%s\n- %s\n%s", start, message, end)
|
|
102
106
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pippit-dev/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "Pippit CLI",
|
|
5
5
|
"bin": {
|
|
6
6
|
"pippit-cli": "scripts/run.js"
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"scripts/platform.js",
|
|
36
36
|
"scripts/run.js",
|
|
37
37
|
"scripts/skills.js",
|
|
38
|
+
"scripts/version-check.js",
|
|
38
39
|
"checksums.txt",
|
|
39
40
|
"README.md",
|
|
40
41
|
"LICENSE"
|
package/scripts/run.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const { execFileSync } = require("child_process");
|
|
4
4
|
const fs = require("fs");
|
|
5
5
|
const path = require("path");
|
|
6
|
+
const { maybeWarnNewVersion } = require("./version-check");
|
|
6
7
|
|
|
7
8
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
8
9
|
const bin = path.join(__dirname, "..", "bin", "pippit-cli" + ext);
|
|
@@ -39,6 +40,8 @@ if (process.platform === "win32" && fs.existsSync(oldBin)) {
|
|
|
39
40
|
if (args[0] === "install") {
|
|
40
41
|
require("./install-wizard.js");
|
|
41
42
|
} else {
|
|
43
|
+
maybeWarnNewVersion(args);
|
|
44
|
+
|
|
42
45
|
if (!fs.existsSync(bin)) {
|
|
43
46
|
try {
|
|
44
47
|
execFileSync(process.execPath, [path.join(__dirname, "install.js")], {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const os = require("os");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const { runSilent } = require("./platform");
|
|
5
|
+
const { DEFAULT_PKG } = require("./skills");
|
|
6
|
+
|
|
7
|
+
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
8
|
+
|
|
9
|
+
function defaultCacheFile() {
|
|
10
|
+
return path.join(os.homedir(), ".pippit-cli", "version-check.json");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function currentVersion() {
|
|
14
|
+
return require("../package.json").version.replace(/-.*$/, "");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function parseSemver(version) {
|
|
18
|
+
const match = String(version || "").trim().match(/^v?(\d+)\.(\d+)\.(\d+)/);
|
|
19
|
+
if (!match) return null;
|
|
20
|
+
return match.slice(1).map(Number);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function compareSemver(a, b) {
|
|
24
|
+
const parsedA = parseSemver(a);
|
|
25
|
+
const parsedB = parseSemver(b);
|
|
26
|
+
if (!parsedA || !parsedB) return 0;
|
|
27
|
+
for (let i = 0; i < 3; i++) {
|
|
28
|
+
const diff = parsedA[i] - parsedB[i];
|
|
29
|
+
if (diff !== 0) return diff;
|
|
30
|
+
}
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function readCache(cacheFile) {
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(fs.readFileSync(cacheFile, "utf8"));
|
|
37
|
+
} catch (_) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function writeCache(cacheFile, data) {
|
|
43
|
+
try {
|
|
44
|
+
fs.mkdirSync(path.dirname(cacheFile), { recursive: true });
|
|
45
|
+
fs.writeFileSync(cacheFile, JSON.stringify(data), "utf8");
|
|
46
|
+
} catch (_) {
|
|
47
|
+
// Version checks must never block normal CLI commands.
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function fetchLatestVersion(pkg = DEFAULT_PKG) {
|
|
52
|
+
return runSilent("npm", ["view", pkg, "version"], { timeout: 3000 }).toString().trim();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function shouldSkip(args, env) {
|
|
56
|
+
const cmd = args[0];
|
|
57
|
+
return (
|
|
58
|
+
env.PIPPIT_CLI_DISABLE_UPDATE_CHECK === "1" ||
|
|
59
|
+
env.CI ||
|
|
60
|
+
cmd === "install" ||
|
|
61
|
+
cmd === "update"
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function maybeWarnNewVersion(args = [], opts = {}) {
|
|
66
|
+
const env = opts.env || process.env;
|
|
67
|
+
if (shouldSkip(args, env)) return;
|
|
68
|
+
|
|
69
|
+
const now = opts.now || Date.now();
|
|
70
|
+
const cacheFile = opts.cacheFile || defaultCacheFile();
|
|
71
|
+
const cache = readCache(cacheFile);
|
|
72
|
+
const cacheFresh = cache && now - cache.checkedAt < CHECK_INTERVAL_MS;
|
|
73
|
+
|
|
74
|
+
let latest = cacheFresh ? cache.latest : "";
|
|
75
|
+
if (!latest) {
|
|
76
|
+
try {
|
|
77
|
+
latest = (opts.fetchLatestVersion || fetchLatestVersion)(opts.pkg || DEFAULT_PKG);
|
|
78
|
+
writeCache(cacheFile, { latest, checkedAt: now });
|
|
79
|
+
} catch (_) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const current = opts.currentVersion || currentVersion();
|
|
85
|
+
if (compareSemver(latest, current) <= 0) return;
|
|
86
|
+
|
|
87
|
+
const warn = opts.warn || console.error;
|
|
88
|
+
warn(`[pippit-cli] New version available: ${current} -> ${latest}. Run: pippit-cli update`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = {
|
|
92
|
+
CHECK_INTERVAL_MS,
|
|
93
|
+
compareSemver,
|
|
94
|
+
maybeWarnNewVersion,
|
|
95
|
+
parseSemver,
|
|
96
|
+
};
|
|
@@ -75,7 +75,7 @@ pippit-cli short-drama +upload-file --path /path/to/outline.md
|
|
|
75
75
|
|
|
76
76
|
```bash
|
|
77
77
|
# 获取会话文件列表
|
|
78
|
-
pippit-cli short-drama +list-thread-file --thread-id THREAD_ID --page-num 1 --page-size
|
|
78
|
+
pippit-cli short-drama +list-thread-file --thread-id THREAD_ID --page-num 1 --page-size 200
|
|
79
79
|
```
|
|
80
80
|
|
|
81
81
|
`+list-thread-file` 返回的每个文件对象包含:
|
|
@@ -108,7 +108,7 @@ pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-path FILE_PA
|
|
|
108
108
|
2. 立即将 web_thread_link 展示给用户
|
|
109
109
|
3. 并行发起,二者同等重要:
|
|
110
110
|
a. pippit-cli short-drama +get-thread --thread-id THREAD_ID --run-id RUN_ID --after-seq SEQUENCE
|
|
111
|
-
b. pippit-cli short-drama +list-thread-file --thread-id THREAD_ID --page-num PAGE_NUM --page-size
|
|
111
|
+
b. pippit-cli short-drama +list-thread-file --thread-id THREAD_ID --page-num PAGE_NUM --page-size 200
|
|
112
112
|
4. 检查 `get-thread` 返回的 messages:
|
|
113
113
|
- 如果任务仍在进行中:展示过程消息,继续查询
|
|
114
114
|
- 如果后端 Agent 提出问题:展示问题,等待用户回复
|
|
@@ -117,7 +117,7 @@ pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-path FILE_PA
|
|
|
117
117
|
- 将 file_path 作为本地目标文件路径,包含文件名
|
|
118
118
|
- 有 download_url 的重要资产:加入本轮下载队列
|
|
119
119
|
- 不判断 file_path 在本地是否已存在,是否跳过由 +download-result 内部处理
|
|
120
|
-
- 如果本轮 total 达到
|
|
120
|
+
- 如果本轮 total 达到 200:下一轮将 PAGE_NUM 加 1,继续查询新一页文件
|
|
121
121
|
6. 对重要资产,立即调用 +download-result 并行下载资源:
|
|
122
122
|
- 使用第 5 步获取的 download_url 作为 --url
|
|
123
123
|
- 使用第 5 步获取的完整 file_path 作为 --output-path
|
|
@@ -150,7 +150,7 @@ pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-path FILE_PA
|
|
|
150
150
|
- **间隔**:每 10 秒查询一次。
|
|
151
151
|
- **增量拉取**:首次使用 `--after-seq 0`,后续根据已读消息进度调整 `after-seq`。
|
|
152
152
|
- **并行查询**:每次 `+submit-run` 返回 `thread_id` 后,同时发起 `+get-thread` 和 `+list-thread-file`;二者同等重要,不能只查询会话进展而忽略会话文件。
|
|
153
|
-
- **文件分页**:`+list-thread-file` 使用 `--page-size
|
|
153
|
+
- **文件分页**:`+list-thread-file` 使用 `--page-size 200`。如果本轮返回的 `total` 达到 200,下一轮使用 `--page-num` 加 1 查询新一页结果;如果未达到 200,保持当前页继续轮询新增产物。
|
|
154
154
|
- **重要资产识别**:每轮都检查 `+list-thread-file` 返回的文件。剧本设计、场景设计、场景图、人物角色设计、人物图、分集草稿、故事板、最终视频产物都是重要资产。
|
|
155
155
|
- **文件下载**:解析 `+list-thread-file` 的结果后,对带 `download_url` 的重要资产立即调用 `+download-result` 下载资源;不要在 `list-thread-file` 阶段检查文件是否已存在,存在性检查由下载工具内部处理。
|
|
156
156
|
- **下载完成标准**:不要把文件元信息展示当成下载完成;必须拿到本地 `file_path`,或明确记录该文件在重试后仍下载失败。
|
|
@@ -163,7 +163,7 @@ pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-path FILE_PA
|
|
|
163
163
|
一次短剧任务不能只以 `+get-thread` 返回完成消息作为结束条件。完成前必须同时检查:
|
|
164
164
|
|
|
165
165
|
1. 已处理 `+get-thread` 返回的最新会话进展、用户确认问题和最终消息。
|
|
166
|
-
2. 已用 `--page-size
|
|
166
|
+
2. 已用 `--page-size 200` 调用 `+list-thread-file` 获取会话文件列表;如果本轮 `total` 达到 200,已在后续轮询中递增 `page-num` 查询新一页。
|
|
167
167
|
3. 对所有带 `download_url` 的重要资产,已调用 `+download-result` 下载到本地 `file_path`。
|
|
168
168
|
4. 对查询失败或下载失败的资产,已在后续轮询中主动重试,并在最终回复中列出仍失败的文件或命令。
|
|
169
169
|
|
|
@@ -224,11 +224,11 @@ pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-path FILE_PA
|
|
|
224
224
|
}
|
|
225
225
|
],
|
|
226
226
|
"total": 1,
|
|
227
|
-
"message": "<system-remind>\n- total reached
|
|
227
|
+
"message": "<system-remind>\n- total reached 200; query the next page with --page-num {page-num} + 1\n</system-remind>"
|
|
228
228
|
}
|
|
229
229
|
```
|
|
230
230
|
|
|
231
|
-
当 `total` 达到
|
|
231
|
+
当 `total` 达到 200 时,`message` 会用 `<system-remind>` 提示下一轮将 `page-num` 加 1 查询新一页。
|
|
232
232
|
|
|
233
233
|
**+download-result** 返回:
|
|
234
234
|
|
|
@@ -251,9 +251,9 @@ pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-path FILE_PA
|
|
|
251
251
|
1. 有download_url的重要资产
|
|
252
252
|
→ 记录该file_path和URL
|
|
253
253
|
→ 使用 +download-result 将URL资源下载到该file_path
|
|
254
|
-
2. 本轮total达到
|
|
254
|
+
2. 本轮total达到200
|
|
255
255
|
→ 下一轮page-num加1,继续查询新一页结果
|
|
256
|
-
3. 本轮total未达到
|
|
256
|
+
3. 本轮total未达到200
|
|
257
257
|
→ 后续轮询保持当前页,继续发现新增产物
|
|
258
258
|
4. list-thread-file或download-result失败
|
|
259
259
|
→ 记录失败参数和错误
|
|
@@ -302,6 +302,6 @@ pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-path FILE_PA
|
|
|
302
302
|
- 查询进展时优先使用 `+submit-run` 返回的 `thread_id` 和 `run_id`。
|
|
303
303
|
- `--after-seq` 用于增量拉取消息,首次查询可设置为 `0`。
|
|
304
304
|
- `+upload-file` 当前用于短剧场景文件上传链路,上传后将返回可传给 `+submit-run` 的文件 ID。
|
|
305
|
-
- `+list-thread-file` 只需要 `thread_id`;分页参数使用 `--page-num 1 --page-size
|
|
305
|
+
- `+list-thread-file` 只需要 `thread_id`;分页参数使用 `--page-num 1 --page-size 200` 起步,`total` 达到 200 时下一轮递增 `page-num`。
|
|
306
306
|
- `+list-thread-file` 和 `+download-result` 是两个不同的 CLI 指令:前者获取会话文件元信息,后者下载 URL 资源并写入到本地目标文件路径。
|
|
307
307
|
- `+download-result` 接收 `--url`、`--output-path`、`--workers`;`--output-path` 必须是包含文件名的目标文件路径。
|