@9000ai/cli 0.6.1 → 0.6.3
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/dist/commands/task.js
CHANGED
|
@@ -3,11 +3,21 @@ export function registerTaskCommands(parent) {
|
|
|
3
3
|
const cmd = parent.command("task").description("Query task status and results");
|
|
4
4
|
cmd
|
|
5
5
|
.command("status")
|
|
6
|
-
.description("Check task status")
|
|
7
|
-
.
|
|
6
|
+
.description("Check task or batch status")
|
|
7
|
+
.option("--task-id <id>", "Task ID")
|
|
8
|
+
.option("--batch-id <id>", "Batch ID (shows batch progress + task list)")
|
|
8
9
|
.option("--fields <list>", "Comma-separated fields to extract (e.g. desc,video_url,likes)")
|
|
9
10
|
.option("--compact", "One JSON object per line, no indentation")
|
|
10
11
|
.action(async (opts) => {
|
|
12
|
+
if (!opts.taskId && !opts.batchId) {
|
|
13
|
+
console.error("Error: must provide --task-id or --batch-id");
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
if (opts.batchId) {
|
|
17
|
+
const data = await request({ method: "GET", path: `/api/v1/tasks/batch/${opts.batchId}` });
|
|
18
|
+
printJson(data, { fields: opts.fields, compact: opts.compact });
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
11
21
|
const data = await request({ method: "GET", path: `/api/v1/tasks/${opts.taskId}` });
|
|
12
22
|
printJson(data, { fields: opts.fields, compact: opts.compact });
|
|
13
23
|
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { request, printJson, pollUntilDone } from "../client.js";
|
|
2
2
|
import { loadJsonFile } from "../utils/format.js";
|
|
3
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
3
5
|
/** Extract unique video_ids from monitor task output */
|
|
4
6
|
function extractVideoIdsFromMonitorOutput(output) {
|
|
5
7
|
const data = (output.data ?? output);
|
|
@@ -72,39 +74,52 @@ export function registerTranscribeCommands(parent) {
|
|
|
72
74
|
});
|
|
73
75
|
cmd
|
|
74
76
|
.command("text")
|
|
75
|
-
.description("Extract transcription text
|
|
77
|
+
.description("Extract transcription text and save to local file")
|
|
76
78
|
.requiredOption("--task-id <id>", "Task ID")
|
|
79
|
+
.option("--no-save", "Print text to stdout instead of saving to file")
|
|
77
80
|
.action(async (opts) => {
|
|
78
81
|
const taskData = await request({ method: "GET", path: `/api/v1/tasks/${opts.taskId}` });
|
|
79
82
|
const inner = taskData.data;
|
|
80
|
-
if (!inner || inner.status !== "SUCCESS") {
|
|
81
|
-
console.
|
|
82
|
-
|
|
83
|
-
printJson(inner);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
83
|
+
if (!inner || String(inner.status).toUpperCase() !== "SUCCESS") {
|
|
84
|
+
console.error(`Task status: ${inner?.status ?? "unknown"}`);
|
|
85
|
+
process.exit(1);
|
|
86
86
|
}
|
|
87
87
|
const output = (typeof inner.output === "string" ? JSON.parse(inner.output) : inner.output);
|
|
88
88
|
const jsonUrl = output?.json_url;
|
|
89
89
|
if (!jsonUrl) {
|
|
90
90
|
console.error("No json_url in task output");
|
|
91
|
-
|
|
92
|
-
return;
|
|
91
|
+
process.exit(1);
|
|
93
92
|
}
|
|
94
93
|
const controller = new AbortController();
|
|
95
94
|
const timer = setTimeout(() => controller.abort(), 60_000);
|
|
96
95
|
try {
|
|
97
96
|
const res = await fetch(jsonUrl, { signal: controller.signal });
|
|
98
97
|
const transcript = await res.json();
|
|
99
|
-
const text = transcript.text ?? "";
|
|
100
|
-
|
|
98
|
+
const text = String(transcript.text ?? "");
|
|
99
|
+
if (!text) {
|
|
100
|
+
console.error("Transcript text is empty");
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
// 用 third_party_task_id (video_id) 或 task_id 做文件名
|
|
104
|
+
const videoId = (inner.third_party_task_id ?? opts.taskId);
|
|
105
|
+
if (!opts.save) {
|
|
106
|
+
// --no-save: 直接输出
|
|
107
|
+
console.log(text);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// 落盘到 output/transcripts/{video_id}.txt
|
|
111
|
+
const dir = resolve("output", "transcripts");
|
|
112
|
+
mkdirSync(dir, { recursive: true });
|
|
113
|
+
const filepath = join(dir, `${videoId}.txt`);
|
|
114
|
+
writeFileSync(filepath, text, "utf-8");
|
|
115
|
+
// 只返回摘要给 AI
|
|
116
|
+
const preview = text.length > 100 ? text.slice(0, 100) + "..." : text;
|
|
101
117
|
printJson({
|
|
102
118
|
task_id: opts.taskId,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
text,
|
|
106
|
-
|
|
107
|
-
duration_ms: transcript.duration_ms,
|
|
119
|
+
video_id: videoId,
|
|
120
|
+
file: filepath,
|
|
121
|
+
char_count: text.length,
|
|
122
|
+
preview,
|
|
108
123
|
});
|
|
109
124
|
}
|
|
110
125
|
finally {
|
|
@@ -133,7 +148,7 @@ export function registerTranscribeCommands(parent) {
|
|
|
133
148
|
if (opts.taskId) {
|
|
134
149
|
const taskResp = await request({ method: "GET", path: `/api/v1/tasks/${opts.taskId}` });
|
|
135
150
|
const taskData = (taskResp.data ?? taskResp);
|
|
136
|
-
if (taskData.status !== "SUCCESS") {
|
|
151
|
+
if (String(taskData.status).toUpperCase() !== "SUCCESS") {
|
|
137
152
|
console.error(`Task status: ${taskData.status ?? "unknown"} (need SUCCESS)`);
|
|
138
153
|
process.exit(1);
|
|
139
154
|
}
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ const program = new Command();
|
|
|
14
14
|
program
|
|
15
15
|
.name("9000ai")
|
|
16
16
|
.description("9000AI Toolbox CLI — unified interface for 9000AI platform")
|
|
17
|
-
.version("0.6.
|
|
17
|
+
.version("0.6.3");
|
|
18
18
|
registerConfigCommands(program);
|
|
19
19
|
registerAuthCommands(program);
|
|
20
20
|
registerSearchCommands(program);
|
package/package.json
CHANGED
package/skills/feedback/SKILL.md
CHANGED
|
@@ -46,6 +46,8 @@ agent 在对话中确认标题和内容后,直接组装参数调 CLI 就行。
|
|
|
46
46
|
| `--type` | 否 | 可选分类:workflow / bug / feature / other |
|
|
47
47
|
| `--context-json` | 否 | 附加上下文,比如涉及的 skill 名、task_id 等,JSON 格式 |
|
|
48
48
|
|
|
49
|
+
**必须带版本号**:提交反馈前先执行 `9000ai --version` 获取当前版本,在 content 末尾附上 `[CLI v0.x.x]`,方便定位问题。
|
|
50
|
+
|
|
49
51
|
## 命令
|
|
50
52
|
|
|
51
53
|
查看帮助:
|
|
@@ -67,13 +67,18 @@ output-format: task-oriented
|
|
|
67
67
|
|
|
68
68
|
不要把整份转写 JSON 原样塞进上下文。
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
提取原文文案:
|
|
71
71
|
|
|
72
72
|
```bash
|
|
73
73
|
9000ai transcribe text --task-id <task_id>
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
这个命令会:
|
|
77
|
+
1. 下载转写结果,提取纯文本
|
|
78
|
+
2. 保存到 `output/transcripts/{video_id}.txt`
|
|
79
|
+
3. 返回文件路径 + 前 100 字预览
|
|
80
|
+
|
|
81
|
+
AI 拿到路径后按需读取,不要一次性把所有文案塞进上下文。如果只需要输出到终端不落盘,加 `--no-save`。
|
|
77
82
|
|
|
78
83
|
## 命令
|
|
79
84
|
|
|
@@ -117,7 +122,7 @@ output-format: task-oriented
|
|
|
117
122
|
# 正确 — 只取需要的字段
|
|
118
123
|
9000ai task results --task-id <id> --fields status,output,video_url
|
|
119
124
|
|
|
120
|
-
# 只要原文 —
|
|
125
|
+
# 只要原文 — 落盘后按需读取
|
|
121
126
|
9000ai transcribe text --task-id <task_id>
|
|
122
127
|
```
|
|
123
128
|
|