@optima-chat/optima-agent 0.9.5 → 0.9.7

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.
@@ -14,32 +14,69 @@ description: "剪辑用户【已有的】口播视频——去除卡顿停顿让
14
14
 
15
15
  ## 用户怎么说,你交付什么
16
16
 
17
+ **默认所有剪辑都带字幕**——中文短视频(TikTok / 小红书 / 视频号)99% 需要字幕,"剪一下"的潜台词就是"给我能直接发的成片"。
18
+
17
19
  | 用户说 | 你交付 |
18
20
  |---|---|
19
- | "剪一下" / "去卡顿" / "变流畅" | `<video>_edited.mp4` |
20
- | "剪成 X 秒短视频" / "30 秒" | `<video>_edited.mp4`(压到目标时长) |
21
- | "加字幕" | `<video>_subbed.mp4` |
22
- | "剪完加字幕" | `<video>_edited_subbed.mp4` |
21
+ | "剪一下" / "去卡顿" / "变流畅" | `<video>_subbed.mp4`(剪 + 字幕) |
22
+ | "剪成 X 秒短视频" / "30 秒" | `<video>_subbed.mp4`(压到目标时长 + 字幕) |
23
+ | "加字幕"(不需要剪) | `<video>_subbed.mp4`(仅字幕) |
24
+ | "剪一下不要字幕" / "无字幕版" | `<video>_edited.mp4` |
23
25
 
24
26
  只有当用户提到平台但**没说目标时长**时(如"剪成 TikTok"无时长),才追问"目标多长?"。
25
27
  其他情况**直接动手**,不要废话。
26
28
 
27
29
  ## 你的内部流程(用户不需要知道)
28
30
 
29
- ### 默认剪辑
31
+ ### 默认剪辑(剪 + 字幕,最常见)
30
32
 
31
33
  ```bash
32
34
  video-edit both <video>
33
35
  video-edit review <video>
36
+ # review 通过后烧字幕:
37
+ video-edit subtitle <video>
38
+ ```
39
+
40
+ **3 关审片**全过才烧字幕交付:
41
+
42
+ **第 1 关:声学审片(review 报告给)**
43
+ - 全 OK → 进入第 2 关
44
+ - 有 HARD issue(dead air / 切到字中间 / 重复内容)→ **你自己**编辑 `<video>.work/cut_proposal.md`,把问题段行首加 `#`,重跑 `cut` → `review`
45
+ - **修复尝试上限**:≤ 2 次重剪还有同样的 HARD → 停止循环,按现状继续,**不主动**告诉用户残留小问题(黑盒交付原则;用户问起再答)
46
+ - **小残留静音容忍**:唯一 HARD 是 `residual-silence-at-cut < 0.15s`(切点淡化固有产物,再剪也修不掉)→ 直接接受
47
+
48
+ **第 2 关:语义审片(你自己做,必做)**
49
+
50
+ 成片"实际说出来的话" ≠ 你保留的 phrase 拼接(有转写误差 + 切点丢字)。**你自己跑**:
51
+
52
+ ```bash
53
+ # 重转写成片(输出到 work 目录避免并发冲突)
54
+ python3 -c "
55
+ from faster_whisper import WhisperModel
56
+ import json
57
+ m = WhisperModel('small', device='cpu', compute_type='int8')
58
+ segs, info = m.transcribe('<video>_edited.mp4', language='zh', word_timestamps=True, vad_filter=True)
59
+ words = [{'s':round(w.start,2),'e':round(w.end,2),'t':w.word} for s in segs for w in (s.words or [])]
60
+ print(json.dumps({'duration':round(info.duration,2),'words':words,'text':''.join(w['t'] for w in words)}, ensure_ascii=False, indent=2))
61
+ " > <video>.work/edited_audit.json
62
+
63
+ cat <video>.work/edited_audit.json
64
+ cat <video>.work/cut_proposal.md # 看未被 # 注释的行
34
65
  ```
35
66
 
36
- review 报告:
37
- - OK → 交付
38
- - HARD issue(dead air / 切到字中间 / 重复内容)→ **你自己**编辑 `<video>.work/cut_proposal.md`,把问题段行首加 `#`,重跑 `cut` → `review`,直到通过
39
- - 顺便扫一遍 `<video>.work/cut_proposal.md` 里**未被 `#` 注释的行**(保留下来的 phrase 序列),发现"承诺没兑现('我说三个'但只剩两个)/ 指代物丢失('这个'指什么没了)/ 逻辑跳段"也按 HARD 处理,自己改 proposal 重剪
40
- - 全部通过才交付
67
+ **对比检查**(任一发现 HARD,回去改 proposal 重剪,同样 ≤ 2 次上限):
68
+ - 句子被切半("我们..."没下文 / "因为..."没结果)
69
+ - 指代物丢失("这个" / "那种" / "上面那个" 但前文没了)
70
+ - 承诺没兑现("我说三个"但成片只剩两个)
71
+ - 词义跳段(前一句说苹果,下一句说香蕉,承接句被剪)
72
+ - 转写误差导致字错(whisper 把 "义乌" 转成 "亿物")
73
+ - **切点接合不顺**:成片转写的 words 里相邻 word gap > 0.4s 的位置(不是天然停顿)说明拼接生硬
74
+
75
+ **两关全过 → 跑 subtitle 烧字幕 → 交付**
76
+
77
+ `subtitle` 命令传**原片路径**即可(脚本会自动用 `_edited.mp4` 做输入),输出固定是 `<原片>_subbed.mp4`。
41
78
 
42
- 如果 review 显示语音占比 > 90%(说明几乎没卡顿要删,但用户原片可能有 NG 重录或跑题),改走"限时长精剪"路径让你自己决定删哪些短语——`both` 只删停顿,删不掉 NG / 废话。
79
+ 如果第 1 关 review 显示语音占比 > 90%(说明几乎没卡顿要删,但用户原片可能有 NG 重录或跑题),改走"限时长精剪"路径让你自己决定删哪些短语——`both` 只删停顿,删不掉 NG / 废话。
43
80
 
44
81
  ### 限时长精剪(用户给了目标时长)
45
82
 
@@ -59,22 +96,28 @@ video-edit cut <video>
59
96
  video-edit review <video>
60
97
  ```
61
98
 
62
- review 通过交付。
99
+ **剪完同样走"默认剪辑"里的 2 关审片**(声学 + 语义),全过再跑 `video-edit subtitle` 交付 `<原片>_subbed.mp4`。
63
100
 
64
- ### 加字幕
101
+ 限时长场景为了压时长更激进地删,**比默认剪辑更需要**这两关 — 不要跳过。
102
+
103
+ ### 仅字幕(用户明确说不剪)
65
104
 
66
105
  ```bash
67
106
  video-edit subtitle <video>
68
107
  ```
69
108
 
70
- 如果是剪过的成片,传 `_edited.mp4`。命令会自动处理。
109
+ 没有 `_edited.mp4` 时,命令直接对原片烧字幕,输出 `<原片>_subbed.mp4`。
110
+
111
+ ### 无字幕版(用户明确说不要字幕)
112
+
113
+ 只跑 `both` + `review`,**不跑 subtitle**,交付 `<原片>_edited.mp4`。
71
114
 
72
115
  ## 交付怎么说
73
116
 
74
117
  简洁,**只说结果**:
75
118
 
76
- - ✅ "剪好了,xxx_edited.mp4,时长 23 秒"
77
- - ✅ "字幕烧好了,xxx_subbed.mp4"
119
+ - ✅ "剪好了,xxx_subbed.mp4,时长 23 秒"(默认带字幕的情况)
120
+ - ✅ "无字幕版剪好了,xxx_edited.mp4,时长 23 秒"(用户要无字幕时)
78
121
  - ❌ "我用了 video-edit analyze,然后编辑了 cut_proposal.md..."
79
122
  - ❌ "review 显示 3 个 WARN,但都不影响..."
80
123
 
@@ -83,6 +126,7 @@ review 自动修过的问题不用提;改了几次也不用提。
83
126
  ## 不要做的事
84
127
 
85
128
  - ❌ 用户说"剪一下"就追问平台/钩子/时长——直接动手
129
+ - ❌ 用户说"剪一下"只交付 `_edited.mp4` 不烧字幕——**默认带字幕**,除非用户明说不要
86
130
  - ❌ 让用户编辑 cut_proposal.md——**你来编辑**
87
131
  - ❌ 把命令名暴露给用户——简单交付即可
88
132
  - ❌ 编造命令(仅 5 个:both / analyze / cut / review / subtitle)
@@ -96,4 +140,4 @@ review 自动修过的问题不用提;改了几次也不用提。
96
140
  | `video-edit analyze <video>` | 生成 `<video>.work/cut_proposal.md` |
97
141
  | `video-edit cut <video>` | 按 proposal 剪辑 |
98
142
  | `video-edit review <video>` | 检查 `<video>_edited.mp4`,输出 review_report.md |
99
- | `video-edit subtitle <video>` | 烧字幕到 `<video>_subbed.mp4` |
143
+ | `video-edit subtitle <video>` | 烧字幕。传**原片路径**即可,自动找 `_edited.mp4` 做输入;输出固定是 `<原片>_subbed.mp4`(不会带 `_edited`) |
@@ -0,0 +1,174 @@
1
+ ---
2
+ name: wechat
3
+ description: "微信视频号视频下载与 metadata 查询。使用场景:下载视频号/微信视频/weixin.qq.com/sph/ 链接,或查看视频号信息/作者/话题/点赞。使用 scout wechat 命令。"
4
+ ---
5
+
6
+ # 微信 - 视频号视频下载与 metadata
7
+
8
+ 所有命令使用 `scout wechat` 前缀。当前覆盖**视频号(Channels)**,未来可扩展到公众号、小程序等其他微信 surface。
9
+
10
+ > **依赖**:`@optima-chat/scout-cli >= 0.14.0`(`scout wechat` 命令在 0.14.0 引入)。如果 CLI 报 `unknown command 'wechat'`,说明环境里 scout-cli 版本太低,**不要重试**,直接告诉用户"请升级 scout-cli 到 0.14.0 或以上"。
11
+
12
+ ---
13
+
14
+ ## 快速选择
15
+
16
+ | 你的目标 | 命令 |
17
+ |---------|------|
18
+ | **下载视频号视频**(拿可播放 mp4) | `scout wechat fetch <url或exportId>` |
19
+ | **只看 metadata**(作者/话题/点赞,不下载) | `scout wechat metadata <url或exportId>` |
20
+
21
+ ---
22
+
23
+ ## 典型场景
24
+
25
+ 当用户说:
26
+ - "下载这个视频号" + 链接 → `scout wechat fetch <url>`
27
+ - "下载微信视频" + 链接 → `scout wechat fetch <url>`
28
+ - "看看这个视频号的信息" / "这个视频号谁发的" → `scout wechat metadata <url>`
29
+ - 用户直接贴 `weixin.qq.com/sph/xxx` 或 `channels.weixin.qq.com/.../sph?id=xxx`,无其他说明 → 默认走 `metadata`(避免误烧 TikHub 额度;用户明确说"下载"/"保存"才走 `fetch`)
30
+
31
+ ---
32
+
33
+ ## URL 解析 - 视频号链接处理
34
+
35
+ 视频号视频有三种形态,**都直接传给命令即可,不需要自己解析**(命令内置正则):
36
+
37
+ | URL 形态 | 示例 |
38
+ |---------|------|
39
+ | 短链 | `https://weixin.qq.com/sph/Azn5HYOeb0` |
40
+ | 完整链 | `https://channels.weixin.qq.com/finder-preview/pages/sph?id=Azn5HYOeb0` |
41
+ | 裸 exportId(10 位短码) | `Azn5HYOeb0` |
42
+
43
+ ```bash
44
+ # 三种都行(以下示例用 fetch 演示 URL 形态;实际用哪个命令看场景,默认 metadata)
45
+ scout wechat fetch https://weixin.qq.com/sph/Azn5HYOeb0
46
+ scout wechat fetch "https://channels.weixin.qq.com/finder-preview/pages/sph?id=Azn5HYOeb0"
47
+ scout wechat fetch Azn5HYOeb0
48
+ ```
49
+
50
+ **不要用 WebFetch** 去抓视频号页面 — 视频是加密的,WebFetch 拿不到。
51
+
52
+ ---
53
+
54
+ ## 核心命令
55
+
56
+ ### 1. fetch - 下载视频 + metadata
57
+
58
+ 完整 pipeline:解析 URL → TikHub 拿 metadata + 加密 CDN → 下载 + 解密 → 上传 S3 → 返回可播放 mp4 URL。
59
+
60
+ ```bash
61
+ scout wechat fetch https://weixin.qq.com/sph/Azn5HYOeb0
62
+ ```
63
+
64
+ **返回数据**(JSON):
65
+ - `data.videoUrl` — 可直接播放/下载的 mp4 URL(S3,公开读)
66
+ - `data.videoSize` — 文件字节数
67
+ - `data.metadata.title` — 标题
68
+ - `data.metadata.author.nickname` — 作者昵称
69
+ - `data.metadata.author.auth` — 认证身份(若有)
70
+ - `data.metadata.topics` — 话题列表(从 `#xxx` 解析)
71
+ - `data.metadata.video.durationSec` — 视频时长(秒)
72
+ - `data.metadata.video.width / height` — 分辨率
73
+ - `data.metadata.stats` — `like / comment / forward / fav`
74
+ - `data.metadata.coverUrl` — 封面图
75
+
76
+ **下载视频文件**:拿到 `videoUrl` 后用任意 HTTP 工具:
77
+ ```bash
78
+ # Linux/macOS 通常有 wget
79
+ wget -O video.mp4 "<videoUrl>"
80
+
81
+ # Windows / 没有 wget — 用 curl (curl 在 macOS / Win10+ 都自带)
82
+ curl -L -o video.mp4 "<videoUrl>"
83
+ ```
84
+
85
+ ### 2. metadata - 只看信息
86
+
87
+ 不下载视频文件,只拿 metadata 字段(省 S3 流量,但仍消耗 1 次 TikHub 额度)。
88
+
89
+ ```bash
90
+ scout wechat metadata https://weixin.qq.com/sph/Azn5HYOeb0
91
+ ```
92
+
93
+ 返回字段跟 `fetch` 的 `data.metadata` 一致,但没有 `videoUrl / videoSize`。
94
+
95
+ **何时用 metadata 而不是 fetch**:
96
+ - 用户问"这视频谁发的""讲什么的""多少赞" → 用 metadata
97
+ - 用户要"下载""视频文件""保存下来" → 用 fetch
98
+ - 用户只贴链接、没说要做什么 → 默认 metadata(见典型场景第 4 条)
99
+
100
+ ---
101
+
102
+ ## 限制与注意事项
103
+
104
+ 1. **画质**:目前只能拿低清版本(约 576×1024,1-3 MB),TikHub 公开 API 不返回高清 30 MB 版
105
+ 2. **每次消费 TikHub 额度**:`fetch_video_detail` 大约 \$0.01/次,频繁调用会烧钱,先 `metadata` 看看有没有必要再 `fetch`
106
+ 3. **依赖 decrypt server**:`fetch` 的解密步骤依赖外部部署的 decrypt 服务,如果返回 **503 Service Unavailable**,说明 backend 配置缺失(`WECHAT_DECRYPT_API_URL` 没设),应该告知用户"视频号下载服务暂未配置,请联系 SRE"
107
+ 4. **错误码语义**:
108
+ - `400` — URL 解析不出 exportId(用户给的链接不对)
109
+ - `502` — TikHub / CDN / decrypt server 上游失败(短期重试可能恢复)
110
+ - `503` — backend 没配解密服务(SRE 还没部署)
111
+ - `500` — 其它内部异常
112
+ 5. **videoUrl 是一次性签名链接**:`fetch` pipeline 必须一气呵成拿到后立刻返回,不要中间缓存;只直接返回给当前用户,不要存储或转发给第三方系统(链接很快失效)
113
+ 6. **scope 限定**:这个 skill 只管视频号(Channels),不要用它处理公众号文章 / 小程序 / 朋友圈
114
+
115
+ ---
116
+
117
+ ## 工作流示例
118
+
119
+ ### 用户给链接要下载
120
+
121
+ ```
122
+ 用户:帮我下载这个视频号 https://weixin.qq.com/sph/Azn5HYOeb0
123
+ ```
124
+
125
+ ```bash
126
+ scout wechat fetch https://weixin.qq.com/sph/Azn5HYOeb0
127
+ ```
128
+
129
+ 返回 JSON 后,以 Markdown 链接格式展示 `videoUrl`(如 `[点击播放/下载](<实际 videoUrl>)`),并列出标题、作者昵称、时长。
130
+
131
+ ### 用户问"这视频啥情况"
132
+
133
+ ```
134
+ 用户:这条视频号链接讲啥的 https://weixin.qq.com/sph/Azn5HYOeb0
135
+ ```
136
+
137
+ ```bash
138
+ scout wechat metadata https://weixin.qq.com/sph/Azn5HYOeb0
139
+ ```
140
+
141
+ 列出标题、作者昵称、时长、话题、点赞数给用户,不消耗 S3 / 解密资源。
142
+
143
+ ### 用户给的是 exportId 且只想看信息
144
+
145
+ ```
146
+ 用户:看下 Azn5HYOeb0 这个视频号
147
+ ```
148
+
149
+ ```bash
150
+ scout wechat metadata Azn5HYOeb0
151
+ ```
152
+
153
+ 直接传短码,命令内部识别。
154
+
155
+ ### 用户给的是 exportId 且要下载
156
+
157
+ ```
158
+ 用户:下载 Azn5HYOeb0
159
+ ```
160
+
161
+ ```bash
162
+ scout wechat fetch Azn5HYOeb0
163
+ ```
164
+
165
+ 直接传短码,命令内部识别。
166
+
167
+ ### 出错怎么办
168
+
169
+ | 状态 | 处理 |
170
+ |------|------|
171
+ | 400 (URL 解析失败) | 跟用户说"这个链接不是视频号链接,请贴 `weixin.qq.com/sph/...` 或 `channels.weixin.qq.com/...` 的链接" |
172
+ | 502 (上游失败) | 重试 1 次;仍失败告诉用户"上游服务波动,稍后再试" |
173
+ | 503 (服务未配置) | 告诉用户"视频号下载服务暂未上线,请联系运维"(不要重试) |
174
+ | 500 (内部异常) | 让用户提供链接给运维排查 |
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/system-prompt.ts"],"names":[],"mappings":"AASA,wBAAgB,eAAe,IAAI,MAAM,CA0KxC"}
1
+ {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/system-prompt.ts"],"names":[],"mappings":"AASA,wBAAgB,eAAe,IAAI,MAAM,CA2KxC"}
@@ -34,7 +34,8 @@ export function getSystemPrompt() {
34
34
  - **product-page** - 商品详情页配置
35
35
  - **gen** - 图像/视频/语音生成
36
36
  - **markdown-pdf** - Markdown 转 PDF(文档导出、报告生成)
37
- - **ffmpeg** - 音视频处理(格式转换、压缩、提取音频)
37
+ - **ffmpeg** - 音视频**精确操作**(截取指定时间段、压缩、格式转换、提取音频、生成缩略图、拼接)—— 仅当用户明确说具体操作时用
38
+ - **video-edit** - 🎬 **口播/talking-head 视频智能剪辑**(自动转写 → 删卡顿停顿/NG/废话 → 烧字幕)。**用户给已有视频说"剪一下/帮我剪辑/去卡顿/变流畅/剪短点/加字幕"等模糊指令时首选**,优先级高于 ffmpeg
38
39
  - **ads** - Google Ads 广告投放
39
40
  - **scout** - Amazon 选品调研
40
41
  - **reddit** - Reddit 趋势发现与商机预判
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/system-prompt.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,qEAAqE;AACrE,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE;IACzD,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,MAAM;IACb,GAAG,EAAE,SAAS;IACd,OAAO,EAAE,MAAM;CAChB,CAAC,CAAC;AAEH,MAAM,UAAU,eAAe;IAC7B,OAAO;;;;;;;;;aASI,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+JvB,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/system-prompt.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,qEAAqE;AACrE,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE;IACzD,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,MAAM;IACb,GAAG,EAAE,SAAS;IACd,OAAO,EAAE,MAAM;CAChB,CAAC,CAAC;AAEH,MAAM,UAAU,eAAe;IAC7B,OAAO;;;;;;;;;aASI,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgKvB,CAAC;AACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optima-chat/optima-agent",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "description": "基于 Claude Agent SDK 的电商运营 AI 助手",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",