@remixmate/cli 0.9.72 → 0.9.73
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/LICENSE +45 -21
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/argv.js +1 -51
- package/dist/auth/auth-lock.js +1 -100
- package/dist/auth/auto-login.js +7 -75
- package/dist/auth/commands.js +40 -290
- package/dist/auth/credential-store.js +1 -143
- package/dist/auth/device-flow-runner.js +13 -110
- package/dist/auth/device-flow.js +1 -132
- package/dist/auth/ensure.js +1 -62
- package/dist/auth/environment.js +1 -69
- package/dist/auth/pending-store.js +1 -45
- package/dist/auth/resolve.js +1 -44
- package/dist/billing.js +3 -76
- package/dist/capabilities.js +1 -75
- package/dist/cli.js +39 -211
- package/dist/diagnostics.js +2 -70
- package/dist/doctor.js +9 -188
- package/dist/errors.js +1 -33
- package/dist/exec.js +4 -47
- package/dist/handlers/gen-digital-human.js +33 -264
- package/dist/handlers/gen-image.js +9 -113
- package/dist/handlers/gen-post.js +15 -192
- package/dist/handlers/gen-video.js +7 -185
- package/dist/handlers/gen-voice.js +19 -133
- package/dist/handlers/index.js +1 -20
- package/dist/handlers/shared.js +1 -66
- package/dist/handlers/template-init.js +1 -21
- package/dist/http.js +3 -155
- package/dist/index.js +1 -8
- package/dist/install.js +40 -448
- package/dist/manifest.json +44 -3
- package/dist/progress.js +2 -15
- package/dist/project/commands.js +34 -156
- package/dist/project/host.js +1 -151
- package/dist/project/resolve.js +1 -65
- package/dist/project/store.js +2 -97
- package/dist/project/take.js +1 -106
- package/dist/project/trace.js +5 -278
- package/dist/registry.js +3 -70
- package/dist/runner.js +7 -225
- package/dist/skill-schema.js +1 -194
- package/dist/template/args.js +1 -69
- package/dist/template/check.js +2 -30
- package/dist/template/commands.js +34 -163
- package/dist/template/constants.js +1 -46
- package/dist/template/init.js +5 -133
- package/dist/template/list.js +1 -46
- package/dist/template/preview.js +7 -318
- package/dist/template/proc.js +1 -43
- package/dist/template/project.js +6 -161
- package/dist/template/publish.js +5 -185
- package/dist/template/render-client.js +2 -79
- package/dist/template/upgrade.js +4 -123
- package/dist/text.js +1 -15
- package/package.json +2 -35
- package/skills/doc-parse/scripts/extract_via_render.py +32 -32
- package/skills/export-jianying/scripts/gen_jianying_draft.py +188 -188
- package/skills/gen-script/SKILL.md +23 -1
- package/skills/gen-script/scripts/gen_script.py +644 -551
- package/skills/gen-script/skill.json +12 -0
- package/skills/gen-script/version.json +1 -1
- package/skills/prepare-video-assets/scripts/prepare_video_assets.py +21 -21
- package/skills/render-video/scripts/_chrome_vendor.py +17 -17
- package/skills/render-video/scripts/_digital_human_segments.py +34 -34
- package/skills/render-video/scripts/_video_probe.py +33 -33
- package/skills/render-video/scripts/_vod_polling.py +13 -13
- package/skills/render-video/scripts/remote_renderer_client.py +42 -42
- package/skills/render-video/scripts/render_video.py +639 -639
- package/skills/render-video/scripts/required_props.py +37 -37
- package/skills/render-video/scripts/upload_video.py +35 -35
- package/skills/render-video/version.json +1 -1
- package/skills/template-registry/SKILL.md +16 -0
- package/skills/template-registry/scripts/countdown_spec.py +92 -92
- package/skills/template-registry/scripts/doc_extract.py +40 -40
- package/skills/template-registry/scripts/list_templates.py +303 -191
- package/skills/template-registry/scripts/log_diagnostics.py +1 -1
- package/skills/template-registry/scripts/match_template.py +87 -87
- package/skills/template-registry/scripts/payload_hydrator.py +89 -89
- package/skills/template-registry/scripts/registry_loader.py +159 -159
- package/skills/template-registry/scripts/render_job_client.py +75 -75
- package/skills/template-registry/scripts/showcase_loader.py +44 -44
- package/skills/template-registry/skill.json +4 -1
- package/skills/template-registry/version.json +1 -1
- package/skills/template-registry/video_dsl/runtime/__init__.py +8 -8
- package/skills/template-registry/video_dsl/runtime/dsl_validator.py +329 -329
- package/skills/template-registry/video_dsl/runtime/narration_budget.py +36 -36
- package/skills/template-registry/video_dsl/runtime/payload_contract.py +7 -7
- package/skills/template-registry/video_dsl/runtime/prompt_enhancer.py +98 -98
- package/skills/template-registry/video_dsl/runtime/timeline_compiler.py +127 -127
- package/skills/template-registry/video_dsl/schema/video-dsl-v1alpha1.json +14 -1
- package/skills/video-parser/scripts/analyze_video.py +173 -173
- package/skills/video-parser/scripts/deconstruct_video.py +91 -91
- package/skills/video-parser/scripts/parse_via_render.py +21 -21
- package/skills/web-screenshot/scripts/_media_screenshot/__init__.py +4 -4
- package/skills/web-screenshot/scripts/_media_screenshot/bootstrap.py +7 -7
- package/skills/web-screenshot/scripts/_media_screenshot/browser.py +4 -4
- package/skills/web-screenshot/scripts/_media_screenshot/cli_args.py +4 -4
- package/skills/web-screenshot/scripts/_media_screenshot/js_loader.py +2 -2
- package/skills/web-screenshot/scripts/_media_screenshot/overlay.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/reader.py +40 -40
- package/skills/web-screenshot/scripts/_media_screenshot/recording.py +11 -11
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/__init__.py +8 -8
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/arrow.py +2 -2
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/caption.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/click.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/code_lines.py +5 -5
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/focus.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/highlight.py +3 -3
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/hover.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/redact.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/scroll.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/sequence.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/title_card.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/type.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/wait.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/zoom.py +2 -2
- package/skills/web-screenshot/scripts/_media_screenshot/screenshot.py +15 -15
- package/skills/web-screenshot/scripts/_media_screenshot/storyboard.py +2 -2
- package/skills/web-screenshot/scripts/_media_screenshot/template.py +11 -11
- package/skills/web-screenshot/scripts/_media_screenshot/trim.py +10 -10
- package/skills/web-screenshot/scripts/_media_screenshot/urlguard.py +22 -22
- package/skills/web-screenshot/scripts/_media_upload.py +33 -33
- package/skills/web-screenshot/scripts/read_page.py +15 -15
- package/skills/web-screenshot/scripts/record.py +26 -26
- package/skills/web-screenshot/scripts/screenshot.py +5 -5
- package/dist/argv.d.ts +0 -15
- package/dist/auth/auth-lock.d.ts +0 -26
- package/dist/auth/auto-login.d.ts +0 -20
- package/dist/auth/commands.d.ts +0 -8
- package/dist/auth/credential-store.d.ts +0 -60
- package/dist/auth/device-flow-runner.d.ts +0 -58
- package/dist/auth/device-flow.d.ts +0 -52
- package/dist/auth/ensure.d.ts +0 -55
- package/dist/auth/environment.d.ts +0 -38
- package/dist/auth/pending-store.d.ts +0 -33
- package/dist/auth/resolve.d.ts +0 -30
- package/dist/billing.d.ts +0 -44
- package/dist/capabilities.d.ts +0 -63
- package/dist/cli.d.ts +0 -13
- package/dist/diagnostics.d.ts +0 -24
- package/dist/doctor.d.ts +0 -22
- package/dist/errors.d.ts +0 -29
- package/dist/exec.d.ts +0 -18
- package/dist/handlers/gen-digital-human.d.ts +0 -17
- package/dist/handlers/gen-image.d.ts +0 -20
- package/dist/handlers/gen-post.d.ts +0 -22
- package/dist/handlers/gen-video.d.ts +0 -19
- package/dist/handlers/gen-voice.d.ts +0 -26
- package/dist/handlers/index.d.ts +0 -20
- package/dist/handlers/shared.d.ts +0 -26
- package/dist/handlers/template-init.d.ts +0 -10
- package/dist/http.d.ts +0 -72
- package/dist/index.d.ts +0 -9
- package/dist/install.d.ts +0 -71
- package/dist/progress.d.ts +0 -23
- package/dist/project/commands.d.ts +0 -19
- package/dist/project/host.d.ts +0 -91
- package/dist/project/resolve.d.ts +0 -43
- package/dist/project/store.d.ts +0 -31
- package/dist/project/take.d.ts +0 -50
- package/dist/project/trace.d.ts +0 -98
- package/dist/registry.d.ts +0 -30
- package/dist/runner.d.ts +0 -39
- package/dist/skill-schema.d.ts +0 -138
- package/dist/template/args.d.ts +0 -25
- package/dist/template/check.d.ts +0 -23
- package/dist/template/commands.d.ts +0 -25
- package/dist/template/constants.d.ts +0 -39
- package/dist/template/init.d.ts +0 -28
- package/dist/template/list.d.ts +0 -23
- package/dist/template/preview.d.ts +0 -60
- package/dist/template/proc.d.ts +0 -26
- package/dist/template/project.d.ts +0 -47
- package/dist/template/publish.d.ts +0 -43
- package/dist/template/render-client.d.ts +0 -39
- package/dist/template/upgrade.d.ts +0 -44
- package/dist/text.d.ts +0 -8
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
render_job_client.py — ab-api renderJob 接口 Python 客户端
|
|
4
2
|
|
|
5
|
-
封装对 ab-api /api/renderJob/* 的调用,供 render_video.py 和
|
|
6
|
-
gen_jianying_draft.py 使用。
|
|
7
3
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
13
|
|
|
14
14
|
from log_diagnostics import trace_headers
|
|
15
15
|
import json
|
|
@@ -39,10 +39,10 @@ def _make_headers(priv_token: str) -> dict:
|
|
|
39
39
|
return headers
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
46
|
_BILLING: dict = {"credits": 0, "balance": None}
|
|
47
47
|
|
|
48
48
|
|
|
@@ -60,12 +60,12 @@ def _record_billing(result: dict) -> None:
|
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
def billing_summary() -> dict:
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
return dict(_BILLING)
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
def _post(path: str, payload: dict, priv_token: str, timeout: int = 30) -> dict:
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
url = f"{_api_base()}{path}"
|
|
70
70
|
body = json.dumps(payload).encode("utf-8")
|
|
71
71
|
req = urllib.request.Request(url, data=body, headers=_make_headers(priv_token), method="POST")
|
|
@@ -86,33 +86,33 @@ def _post(path: str, payload: dict, priv_token: str, timeout: int = 30) -> dict:
|
|
|
86
86
|
return result.get("data") or {}
|
|
87
87
|
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
def create_job(priv_token: str, dsl: str = "", dsl_meta: dict = None) -> int:
|
|
93
|
-
"""
|
|
94
|
-
创建渲染任务。
|
|
95
93
|
|
|
96
|
-
会话归属:本函数会自动带上环境变量 CONVERSATION_ID(若已设置),让服务端在
|
|
97
|
-
创建时就把 job 挂到该会话的 take 上。
|
|
98
94
|
|
|
99
|
-
为什么要在这里传:渲染任务过去出生就是孤儿——归属全靠事后一次独立的补绑调用,
|
|
100
|
-
而那条路上有四个静默盲区(CLI 的 take 绑定在 job 出生前就跑完了;云端因为
|
|
101
|
-
CONVERSATION_ID 已被注入而整段跳过它;兜底补绑的 jobId 末位来源是从 stdout
|
|
102
|
-
正则抠的)。归属断了,成片在旁白面板里就查不到已生成的音频。
|
|
103
|
-
而 CONVERSATION_ID 在这一刻本来就已经在环境里了——信息在场,以前只是没传。
|
|
104
|
-
见 ab-platform/docs/engineering/render-job-binding-fix.md。
|
|
105
95
|
|
|
106
|
-
服务端对该字段是软失败:绑不上只记日志,不影响任务创建。
|
|
107
96
|
|
|
108
|
-
Args:
|
|
109
|
-
priv_token: PrivToken
|
|
110
|
-
dsl: 完整 DSL JSON 字符串(可选)
|
|
111
|
-
dsl_meta: DSL 摘要字典(可选,将被序列化为 JSON)
|
|
112
97
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
116
|
payload: dict = {}
|
|
117
117
|
if dsl:
|
|
118
118
|
payload["dsl"] = dsl
|
|
@@ -131,28 +131,28 @@ def create_job(priv_token: str, dsl: str = "", dsl_meta: dict = None) -> int:
|
|
|
131
131
|
|
|
132
132
|
|
|
133
133
|
def save_plan(job_id: int, render_plan: str, priv_token: str) -> None:
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
142
|
_post("/renderJob/savePlan", {"jobId": job_id, "renderPlan": render_plan}, priv_token)
|
|
143
143
|
|
|
144
144
|
|
|
145
145
|
def get_plan(job_id: int, priv_token: str) -> str:
|
|
146
|
-
"""
|
|
147
|
-
从数据库加载 RenderPlan(Phase 2 开始前调用)。
|
|
148
146
|
|
|
149
|
-
Args:
|
|
150
|
-
job_id: 渲染任务 ID
|
|
151
|
-
priv_token: PrivToken
|
|
152
147
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
156
|
data = _post("/renderJob/getPlan", {"jobId": job_id}, priv_token)
|
|
157
157
|
render_plan = data.get("renderPlan")
|
|
158
158
|
if not render_plan:
|
|
@@ -161,28 +161,28 @@ def get_plan(job_id: int, priv_token: str) -> str:
|
|
|
161
161
|
|
|
162
162
|
|
|
163
163
|
def save_manifest(job_id: int, manifest: dict, priv_token: str) -> None:
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
172
|
_post("/renderJob/saveManifest", {"jobId": job_id, "manifest": manifest}, priv_token)
|
|
173
173
|
|
|
174
174
|
|
|
175
175
|
def latest_job(conversation_id: str, priv_token: str) -> dict:
|
|
176
|
-
"""
|
|
177
|
-
按会话取最近一次**已存 RenderPlan** 的渲染任务摘要(POST /renderJob/latest)。
|
|
178
176
|
|
|
179
|
-
多轮对话里模型看不到之前的工具结果,拿不到 jobId;消费上一轮成果的 skill
|
|
180
|
-
(如 export-jianying)用注入的 CONVERSATION_ID 反查最新一版,而不是让模型从
|
|
181
|
-
聊天记录里拼素材 URL —— 那样会拿到过期的旧版素材。
|
|
182
177
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
186
|
data = _post("/renderJob/latest", {"conversationId": conversation_id}, priv_token)
|
|
187
187
|
if not data.get("jobId"):
|
|
188
188
|
raise RuntimeError("no render job with a saved RenderPlan in this conversation")
|
|
@@ -190,20 +190,20 @@ def latest_job(conversation_id: str, priv_token: str) -> dict:
|
|
|
190
190
|
|
|
191
191
|
|
|
192
192
|
def get_job(job_id: int, priv_token: str) -> dict:
|
|
193
|
-
"""
|
|
194
|
-
获取渲染任务完整详情。
|
|
195
193
|
|
|
196
|
-
Args:
|
|
197
|
-
job_id: 渲染任务 ID
|
|
198
|
-
priv_token: PrivToken
|
|
199
194
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
203
|
return _post("/renderJob/get", {"jobId": job_id}, priv_token)
|
|
204
204
|
|
|
205
205
|
|
|
206
|
-
|
|
206
|
+
|
|
207
207
|
|
|
208
208
|
if __name__ == "__main__":
|
|
209
209
|
import argparse
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
"""Showcase (sample video) loader — per-template samples + web detail-page links.
|
|
2
1
|
|
|
3
|
-
Used by ``list_templates.py`` so an agent host (Codex CLI / Codex Desktop /
|
|
4
|
-
Claude Code) can show the user how many samples a template has and a link to
|
|
5
|
-
the web detail page where the samples play.
|
|
6
2
|
|
|
7
|
-
Contract (ab-api ``POST /templateShowcase/listByTemplate``, X-Priv-Token):
|
|
8
3
|
|
|
9
|
-
request {"templateKeys": [...], "limitPerTemplate": N}
|
|
10
|
-
response {code, msg, data: {"templates": [
|
|
11
|
-
{"templateKey", "pageUrl"?, "showcaseCount",
|
|
12
|
-
"showcases": [{"showcaseId", "name", "coverImage", "videoUrl",
|
|
13
|
-
"aspectRatio", "duration", "hasDemo", "pageUrl"?, ...}]}
|
|
14
|
-
]}}
|
|
15
4
|
|
|
16
|
-
Links are built server-side; the CLI never knows the web origin or routes.
|
|
17
5
|
|
|
18
|
-
Unlike the registry, samples are *enhancement* data: every failure (network,
|
|
19
|
-
older ab-api without the endpoint, business error, bad JSON) returns ``None``
|
|
20
|
-
with one stderr warning, and the caller keeps printing the template list.
|
|
21
|
-
Auth failures are also degraded here — the registry call that precedes this
|
|
22
|
-
one already surfaces them with the proper exit code.
|
|
23
6
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
30
|
|
|
31
31
|
from __future__ import annotations
|
|
32
32
|
|
|
@@ -41,14 +41,14 @@ from typing import Optional
|
|
|
41
41
|
|
|
42
42
|
from registry_loader import api_base_url
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
|
|
45
|
+
|
|
46
46
|
_TTL_SECONDS = 300
|
|
47
47
|
_HTTP_TIMEOUT = 5
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
52
|
SUMMARY_ITEM_FIELDS = (
|
|
53
53
|
"showcaseId", "name", "coverImage", "videoUrl",
|
|
54
54
|
"aspectRatio", "duration", "hasDemo", "pageUrl",
|
|
@@ -56,12 +56,12 @@ SUMMARY_ITEM_FIELDS = (
|
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
def _endpoint() -> str:
|
|
59
|
-
"""Endpoint URL, or "" when samples should not be fetched at all.
|
|
60
59
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
65
|
explicit = os.environ.get("VIDEO_TEMPLATE_SHOWCASE_URL", "").strip()
|
|
66
66
|
if explicit:
|
|
67
67
|
return explicit
|
|
@@ -78,8 +78,8 @@ def _cache_dir() -> str:
|
|
|
78
78
|
|
|
79
79
|
|
|
80
80
|
def _cache_file(url: str, body: bytes, token: str) -> str:
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
|
|
82
|
+
|
|
83
83
|
token_id = hashlib.sha256(token.encode("utf-8")).hexdigest()[:8]
|
|
84
84
|
digest = hashlib.sha256(url.encode("utf-8") + b"\0" + body + b"\0" + token_id.encode()).hexdigest()[:16]
|
|
85
85
|
return os.path.join(_cache_dir(), f"showcases-{digest}.json")
|
|
@@ -104,7 +104,7 @@ def _write_cache(path: str, data: dict) -> None:
|
|
|
104
104
|
json.dump({"fetchedAt": time.time(), "data": data}, fh, ensure_ascii=False)
|
|
105
105
|
os.replace(tmp, path)
|
|
106
106
|
except OSError:
|
|
107
|
-
pass
|
|
107
|
+
pass
|
|
108
108
|
|
|
109
109
|
|
|
110
110
|
def _warn(reason: str) -> None:
|
|
@@ -112,18 +112,18 @@ def _warn(reason: str) -> None:
|
|
|
112
112
|
|
|
113
113
|
|
|
114
114
|
def load_showcases(template_keys: list[str], limit_per_template: int) -> Optional[dict[str, dict]]:
|
|
115
|
-
"""Return ``{templateKey: group}`` for the visible templates, or ``None`` on any failure.
|
|
116
115
|
|
|
117
|
-
|
|
118
|
-
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
119
|
keys = [k for k in dict.fromkeys(template_keys) if isinstance(k, str) and k]
|
|
120
120
|
if not keys:
|
|
121
121
|
return {}
|
|
122
122
|
|
|
123
123
|
url = _endpoint()
|
|
124
124
|
token = os.environ.get("PRIV_TOKEN", "").strip()
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
|
|
126
|
+
|
|
127
127
|
if not url or (not token and not url.startswith("file://")):
|
|
128
128
|
return None
|
|
129
129
|
body = json.dumps(
|
|
@@ -141,8 +141,8 @@ def load_showcases(template_keys: list[str], limit_per_template: int) -> Optiona
|
|
|
141
141
|
try:
|
|
142
142
|
with urllib.request.urlopen(req, timeout=_HTTP_TIMEOUT) as resp:
|
|
143
143
|
parsed = json.loads(resp.read().decode("utf-8"))
|
|
144
|
-
except Exception as exc:
|
|
145
|
-
|
|
144
|
+
except Exception as exc:
|
|
145
|
+
|
|
146
146
|
_warn(type(exc).__name__ + (f" {exc.code}" if hasattr(exc, "code") else ""))
|
|
147
147
|
return None
|
|
148
148
|
if not isinstance(parsed, dict) or parsed.get("code") not in (0, "0"):
|
|
@@ -164,7 +164,7 @@ def load_showcases(template_keys: list[str], limit_per_template: int) -> Optiona
|
|
|
164
164
|
|
|
165
165
|
|
|
166
166
|
def summarize_group(group: dict, max_items: int) -> dict:
|
|
167
|
-
|
|
167
|
+
|
|
168
168
|
items = []
|
|
169
169
|
for sc in (group.get("showcases") or [])[:max_items]:
|
|
170
170
|
if isinstance(sc, dict):
|
|
@@ -18,8 +18,11 @@
|
|
|
18
18
|
"filter_tag": { "type": "string", "description": "Show only templates whose styleTags contain (or are contained in) this string. Case-insensitive. E.g. 'tech' / '科普' / 'walkthrough'." },
|
|
19
19
|
"filter_aspect": { "type": "string", "description": "Show only templates that declare this aspect ratio. E.g. '9:16' / '16:9' / '1:1'." },
|
|
20
20
|
"filter_language": { "type": "string", "description": "Show only templates whose contentLanguage includes this code ('zh' or 'en'). Templates with no declared language are always shown (treated as language-agnostic)." },
|
|
21
|
+
"user_media": { "type": "string", "enum": ["yes", "no"], "description": "Shortlisting when the user named no template. 'yes' = the user handed over their own images/videos: drops templates with nowhere to put them. 'no' = they did not: drops templates that cannot run without them. Leave unset when it does not matter." },
|
|
22
|
+
"source_doc": { "type": "string", "description": "Shortlisting: the user gave a source document of this kind (e.g. 'pptx') — keeps only templates that build their scenes from one. 'none' drops those templates. Leave unset otherwise." },
|
|
23
|
+
"narration": { "type": "string", "enum": ["yes", "no"], "description": "Shortlisting: 'yes' = the video needs voice-over (drops narration-free templates); 'no' = the user wants none (keeps only narration-free templates). Leave unset unless the user said so." },
|
|
21
24
|
"include_beta": { "type": "boolean", "description": "Also list templates with status='beta'. Default off (only 'stable' shows). The ENABLE_BETA_TEMPLATES env var has the same effect process-wide." },
|
|
22
|
-
"json_output": { "type": "boolean", "description": "Emit a JSON result instead of the human-readable table: { templates: [...] } — summaries, or full definitions when template_id / full is set — or { examples: [...] }. List summaries carry pageUrl (the template's web detail page — show it to the user as a link) and, when the backend serves samples, showcases { count, pageUrl, items }; the template_id view carries top-level pageUrls / showcases maps." },
|
|
25
|
+
"json_output": { "type": "boolean", "description": "Emit a JSON result instead of the human-readable table: { templates: [...] } — summaries (each with notFor when the template declares which requests it is the wrong pick for), or full definitions when template_id / full is set — or { examples: [...] }. List summaries carry pageUrl (the template's web detail page — show it to the user as a link) and, when the backend serves samples, showcases { count, pageUrl, items }; the template_id view carries top-level pageUrls / showcases maps." },
|
|
23
26
|
"open": { "type": "string", "description": "Print the web detail page URL of <templateId> (playable samples, layouts, copy-ready prompt) and open it in the browser when run from an interactive terminal. Relay the printed URL to the user." }
|
|
24
27
|
},
|
|
25
28
|
"required": []
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"skillName": "template-registry",
|
|
3
3
|
"repoName": "agent-skill-media-maker",
|
|
4
4
|
"skillId": "475",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "V28",
|
|
6
6
|
"skillDescription": "Video-template registry skill. Stores every video-template definition and lists the available templates (templateId / name / aspect ratio / style tags).\n\nUse this skill as soon as the user mentions any of these intents:\n- View available templates / list every template\n\nNote: DSL→TemplateBinding is no longer a separate exposed step — once prepare_video_assets receives a template_id it builds the binding internally."
|
|
7
7
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"""Package marker for ``video_dsl.runtime`` — kept intentionally empty.
|
|
2
1
|
|
|
3
|
-
This file exists so ``from video_dsl.runtime.<mod> import …`` resolves when
|
|
4
|
-
``skills/template-registry/`` is on sys.path (the pattern used by render-video
|
|
5
|
-
and gen-script). Public modules:
|
|
6
2
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|