@9000ai/cli 0.4.0 → 0.5.1
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/CHANGELOG.md +8 -0
- package/dist/client.d.ts +6 -0
- package/dist/client.js +22 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +83 -0
- package/dist/commands/monitor.js +17 -0
- package/dist/commands/search.js +30 -4
- package/dist/commands/transcribe.js +19 -2
- package/dist/index.js +3 -1
- package/dist/postinstall.d.ts +1 -1
- package/dist/postinstall.js +26 -3
- package/package.json +3 -2
- package/skills/9000AI-hub/SKILL.md +75 -190
- package/skills/9000AI-hub/references/usage-guidelines.md +75 -0
- package/skills/douyin-monitor/SKILL.md +12 -1
- package/skills/9000AI-hub/configure.py +0 -56
- package/skills/9000AI-hub/init/SKILL.md +0 -130
- package/skills/9000AI-hub/init/templates/CLAUDE.md +0 -24
- package/skills/9000AI-hub/shared/__init__.py +0 -1
- package/skills/9000AI-hub/shared/runner.py +0 -135
- package/skills/douyin-monitor/agents/openai.yaml +0 -3
- package/skills/douyin-monitor/scripts/douyin_monitor_api.py +0 -273
- package/skills/douyin-topic-discovery/agents/openai.yaml +0 -3
- package/skills/douyin-topic-discovery/scripts/douyin_topic_discovery_api.py +0 -497
- package/skills/feedback/scripts/feedback_api.py +0 -93
- package/skills/video-transcription/agents/openai.yaml +0 -3
- package/skills/video-transcription/scripts/video_transcription_api.py +0 -183
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import argparse
|
|
4
|
-
import json
|
|
5
|
-
import sys
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
from typing import Any
|
|
8
|
-
|
|
9
|
-
import requests
|
|
10
|
-
|
|
11
|
-
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
12
|
-
HUB_ROOT = REPO_ROOT / "9000AI-hub-9000AI"
|
|
13
|
-
if str(HUB_ROOT) not in sys.path:
|
|
14
|
-
sys.path.insert(0, str(HUB_ROOT))
|
|
15
|
-
|
|
16
|
-
from shared.runner import ( # noqa: E402
|
|
17
|
-
ModuleSpec,
|
|
18
|
-
configure_stdout_encoding,
|
|
19
|
-
load_json_file,
|
|
20
|
-
print_json,
|
|
21
|
-
request_json,
|
|
22
|
-
resolve_api_key,
|
|
23
|
-
resolve_base_url,
|
|
24
|
-
save_local_config,
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
SKILL_ROOT = Path(__file__).resolve().parents[1]
|
|
28
|
-
MODULE_SPEC = ModuleSpec(
|
|
29
|
-
module="video-transcription",
|
|
30
|
-
skill_root=SKILL_ROOT,
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def build_parser() -> argparse.ArgumentParser:
|
|
35
|
-
parser = argparse.ArgumentParser(description="Video transcription API client")
|
|
36
|
-
parser.add_argument("--base-url", default=None)
|
|
37
|
-
parser.add_argument("--api-key", default=None)
|
|
38
|
-
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
39
|
-
|
|
40
|
-
subparsers.add_parser("configure", help="写入本地配置文件")
|
|
41
|
-
subparsers.add_parser("whoami", help="查看当前 key 对应的调用方")
|
|
42
|
-
subparsers.add_parser("capabilities", help="查看当前 key 已开通的能力")
|
|
43
|
-
|
|
44
|
-
submit = subparsers.add_parser("submit", help="提交批量视频转文字任务")
|
|
45
|
-
submit.add_argument("--json-file", required=True)
|
|
46
|
-
|
|
47
|
-
task = subparsers.add_parser("task", help="查询任务状态")
|
|
48
|
-
task.add_argument("--task-id", required=True)
|
|
49
|
-
|
|
50
|
-
results = subparsers.add_parser("results", help="查询任务结果")
|
|
51
|
-
results.add_argument("--task-id", required=True)
|
|
52
|
-
|
|
53
|
-
text = subparsers.add_parser("text", help="只提取转写原文文案")
|
|
54
|
-
text.add_argument("--task-id", required=True)
|
|
55
|
-
|
|
56
|
-
return parser
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def _normalize_output(output: object) -> dict[str, Any]:
|
|
60
|
-
if isinstance(output, dict):
|
|
61
|
-
return output
|
|
62
|
-
if isinstance(output, str):
|
|
63
|
-
try:
|
|
64
|
-
parsed = json.loads(output)
|
|
65
|
-
if isinstance(parsed, dict):
|
|
66
|
-
return parsed
|
|
67
|
-
except json.JSONDecodeError:
|
|
68
|
-
return {}
|
|
69
|
-
return {}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def _fetch_transcription_payload(json_url: str) -> dict[str, Any]:
|
|
73
|
-
response = requests.get(json_url, timeout=60)
|
|
74
|
-
response.raise_for_status()
|
|
75
|
-
payload = response.json()
|
|
76
|
-
if not isinstance(payload, dict):
|
|
77
|
-
raise SystemExit("转写 JSON 返回格式不是 object")
|
|
78
|
-
return payload
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def main() -> None:
|
|
82
|
-
configure_stdout_encoding()
|
|
83
|
-
parser = build_parser()
|
|
84
|
-
args = parser.parse_args()
|
|
85
|
-
|
|
86
|
-
if args.command == "configure":
|
|
87
|
-
if not args.base_url or not args.api_key:
|
|
88
|
-
raise SystemExit("configure 需要同时传 --base-url 和 --api-key")
|
|
89
|
-
save_local_config(MODULE_SPEC, base_url=args.base_url, api_key=args.api_key)
|
|
90
|
-
print_json({"message": "配置已写入", "config_path": str(MODULE_SPEC.config_path)})
|
|
91
|
-
return
|
|
92
|
-
|
|
93
|
-
base_url = resolve_base_url(MODULE_SPEC, args.base_url)
|
|
94
|
-
api_key = resolve_api_key(MODULE_SPEC, args.api_key)
|
|
95
|
-
|
|
96
|
-
if args.command == "whoami":
|
|
97
|
-
print_json(
|
|
98
|
-
request_json(MODULE_SPEC, method="GET", base_url=base_url, api_key=api_key, path="/api/v1/auth/me")
|
|
99
|
-
)
|
|
100
|
-
return
|
|
101
|
-
|
|
102
|
-
if args.command == "capabilities":
|
|
103
|
-
print_json(
|
|
104
|
-
request_json(
|
|
105
|
-
MODULE_SPEC,
|
|
106
|
-
method="GET",
|
|
107
|
-
base_url=base_url,
|
|
108
|
-
api_key=api_key,
|
|
109
|
-
path="/api/v1/auth/capability-permissions",
|
|
110
|
-
)
|
|
111
|
-
)
|
|
112
|
-
return
|
|
113
|
-
|
|
114
|
-
if args.command == "submit":
|
|
115
|
-
print_json(
|
|
116
|
-
request_json(
|
|
117
|
-
MODULE_SPEC,
|
|
118
|
-
method="POST",
|
|
119
|
-
base_url=base_url,
|
|
120
|
-
api_key=api_key,
|
|
121
|
-
path="/api/v1/media/batch-video-to-text",
|
|
122
|
-
payload=load_json_file(args.json_file),
|
|
123
|
-
)
|
|
124
|
-
)
|
|
125
|
-
return
|
|
126
|
-
|
|
127
|
-
if args.command == "task":
|
|
128
|
-
print_json(
|
|
129
|
-
request_json(
|
|
130
|
-
MODULE_SPEC,
|
|
131
|
-
method="GET",
|
|
132
|
-
base_url=base_url,
|
|
133
|
-
api_key=api_key,
|
|
134
|
-
path=f"/api/v1/tasks/{args.task_id}",
|
|
135
|
-
)
|
|
136
|
-
)
|
|
137
|
-
return
|
|
138
|
-
|
|
139
|
-
if args.command == "results":
|
|
140
|
-
print_json(
|
|
141
|
-
request_json(
|
|
142
|
-
MODULE_SPEC,
|
|
143
|
-
method="GET",
|
|
144
|
-
base_url=base_url,
|
|
145
|
-
api_key=api_key,
|
|
146
|
-
path=f"/api/v1/tasks/{args.task_id}/results",
|
|
147
|
-
)
|
|
148
|
-
)
|
|
149
|
-
return
|
|
150
|
-
|
|
151
|
-
if args.command == "text":
|
|
152
|
-
task_response = request_json(
|
|
153
|
-
MODULE_SPEC,
|
|
154
|
-
method="GET",
|
|
155
|
-
base_url=base_url,
|
|
156
|
-
api_key=api_key,
|
|
157
|
-
path=f"/api/v1/tasks/{args.task_id}",
|
|
158
|
-
)
|
|
159
|
-
task_data = task_response.get("data", {}) if isinstance(task_response, dict) else {}
|
|
160
|
-
output = _normalize_output(task_data.get("output"))
|
|
161
|
-
json_url = output.get("json_url")
|
|
162
|
-
if not json_url:
|
|
163
|
-
raise SystemExit("当前 task 还没有可用的 json_url,请先确认任务已完成")
|
|
164
|
-
|
|
165
|
-
payload = _fetch_transcription_payload(str(json_url))
|
|
166
|
-
sentences = ((payload.get("timecodes") or {}).get("sentences") or [])
|
|
167
|
-
print_json(
|
|
168
|
-
{
|
|
169
|
-
"task_id": args.task_id,
|
|
170
|
-
"status": task_data.get("status"),
|
|
171
|
-
"json_url": json_url,
|
|
172
|
-
"text_field": "text",
|
|
173
|
-
"sentence_field": "timecodes.sentences[*].text",
|
|
174
|
-
"duration_ms": payload.get("duration_ms"),
|
|
175
|
-
"sentence_count": len(sentences) if isinstance(sentences, list) else None,
|
|
176
|
-
"text": payload.get("text", ""),
|
|
177
|
-
}
|
|
178
|
-
)
|
|
179
|
-
return
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if __name__ == "__main__":
|
|
183
|
-
main()
|