sophhub 0.4.12 → 0.4.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sophhub",
3
- "version": "0.4.12",
3
+ "version": "0.4.14",
4
4
  "description": "SophHub CLI - Manage and download AI Agent skills",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "bing-image-search",
3
+ "version": "1.0.0",
4
+ "types": [
5
+ "store"
6
+ ],
7
+ "displayName": "Bing 图片搜索",
8
+ "description": "通过 Bing 抓取图片原图 URL 并并行 HEAD 校验可用性,直接以 Markdown 行内图片语法嵌入预览;不下载、不上传、不经过图像生成。",
9
+ "changelog": [
10
+ {
11
+ "version": "1.0.0",
12
+ "date": "2026-05-07",
13
+ "changes": [
14
+ "初次提交"
15
+ ]
16
+ }
17
+ ],
18
+ "createdAt": "2026-05-07",
19
+ "updatedAt": "2026-05-07"
20
+ }
@@ -0,0 +1,105 @@
1
+ ---
2
+ name: bing-image-search
3
+ description: |
4
+ 通过 Bing 图片搜索快速搜图,并行 HEAD 校验 URL 可用性后以 Markdown 行内图片语法直接嵌入预览。
5
+ 当用户说"找图片"、"搜图"、"发几张XX图"、"给我看看XX照片"、"找一些XX相关的图片"时使用。
6
+ 不要用 web_search 搜图(返回文本不含图片URL),直接用本 skill 的 curl 方案。
7
+ homepage: https://cn.bing.com/images/
8
+ metadata: { "openclaw": { "emoji": "🖼️", "requires": { "bins": ["curl", "grep", "xargs", "awk"] } } }
9
+ ---
10
+
11
+ # Bing 图片搜索与预览
12
+
13
+ ## 核心流程
14
+
15
+ ```
16
+ Bing 图片搜索 → 提取 murl → 并行 HEAD 校验 → ![alt](url) 嵌入 → 发出
17
+ ```
18
+
19
+ 一步到位,不下载、不上传、不经过图像生成。
20
+
21
+ ## 一键脚本:搜图 + 并行校验
22
+
23
+ 把搜图和校验写在同一个 exec 里。**校验是并行的**(`xargs -P 10`),整轮耗时约等于单次超时(~3s),与 `N` 几乎无关:
24
+
25
+ ```bash
26
+ N=3 # 需要张数
27
+ QUERY="cute cats" # 关键词,建议英文;含中文时需 URL 编码
28
+ POOL=20 # 候选池;越大越鲁棒,并行校验不会变慢
29
+
30
+ # 1) 抓 Bing 图片搜索结果,提取去重后的原图 URL(最多 POOL 个)
31
+ URLS=$(curl -sL --max-time 10 \
32
+ "https://cn.bing.com/images/search?q=${QUERY// /+}&first=0&count=${POOL}" \
33
+ -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36' \
34
+ | grep -oP 'murl":"\K[^&"]+\.(jpg|jpeg|png|webp)[^&"]*' \
35
+ | awk '!seen[$0]++' \
36
+ | head -n "$POOL")
37
+
38
+ # 2) 并行 HEAD 校验,只输出可达 URL;取前 N 个即可
39
+ # stderr 重定向是为了消掉 head 提前关闭管道时 xargs 的 SIGPIPE 噪声
40
+ printf '%s\n' "$URLS" | xargs -P 10 -I{} bash -c '
41
+ url="$1"
42
+ code=$(curl -sI -L --max-redirs 3 --connect-timeout 2 --max-time 3 \
43
+ -H "Referer: https://cn.bing.com/" \
44
+ -H "User-Agent: Mozilla/5.0" \
45
+ -o /dev/null -w "%{http_code}" "$url" 2>/dev/null)
46
+ [ "$code" = "200" ] && printf "%s\n" "$url"
47
+ ' _ {} 2>/dev/null | head -n "$N"
48
+ ```
49
+
50
+ 输出每行一个 URL,直接拿来嵌入即可。
51
+
52
+ ## 仅搜图(不校验)
53
+
54
+ 调试或仅需原始候选列表时:
55
+
56
+ ```bash
57
+ curl -sL --max-time 10 \
58
+ "https://cn.bing.com/images/search?q=cute+cats&first=0&count=20" \
59
+ -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36' \
60
+ | grep -oP 'murl":"\K[^&"]+\.(jpg|jpeg|png|webp)[^&"]*' \
61
+ | awk '!seen[$0]++' | head -n 10
62
+ ```
63
+
64
+ ## 仅校验(已有 URL 列表)
65
+
66
+ 把 URL 一行一个传给:
67
+
68
+ ```bash
69
+ xargs -P 10 -I{} bash -c '
70
+ url="$1"
71
+ code=$(curl -sI -L --max-redirs 3 --connect-timeout 2 --max-time 3 \
72
+ -H "Referer: https://cn.bing.com/" -H "User-Agent: Mozilla/5.0" \
73
+ -o /dev/null -w "%{http_code}" "$url" 2>/dev/null)
74
+ [ "$code" = "200" ] && printf "%s\n" "$url"
75
+ ' _ {} 2>/dev/null
76
+ ```
77
+
78
+ ## 嵌入预览
79
+
80
+ 拿到校验通过的 URL 后,每行一条:
81
+
82
+ ```markdown
83
+ ![描述](URL1)
84
+ ![描述](URL2)
85
+ ![描述](URL3)
86
+ ```
87
+
88
+ ## 性能要点
89
+
90
+ - **并行校验**:从 N 张图近 `N × max-time` 的串行耗时降到 `max-time` 量级(~3s)。`POOL=20`、`-P 10` 是经验上的甜点。
91
+ - **`--connect-timeout 2`**:与 `--max-time 3` 配合,避免 DNS / 三次握手卡满整个 budget。
92
+ - **`grep -oP '...\K...'`**:用 PCRE lookbehind 直接得到捕获,省掉 `sed` 管道。
93
+ - **`awk '!seen[$0]++'`**:先去重再校验,防止候选池里重复 URL 浪费请求。
94
+ - **`Referer: cn.bing.com`**:很多图床只允许"来自搜索引擎"的请求,加了能显著降低裂图率。
95
+ - **`head -n "$N"`**:取够即停;上游 `xargs` 会因 SIGPIPE 自动收敛。
96
+
97
+ ## 注意事项
98
+
99
+ 1. **不要下载图片到本地** — 聊天直接用源站 URL 嵌入,不落盘。
100
+ 2. **不要用 web_search 搜图** — 返回文本摘要,不含图片 URL。
101
+ 3. **必须校验** — 跳过 HEAD 校验直接嵌 URL,防盗链域名会导致裂图。
102
+ 4. **关键词优先英文** — Bing 图库英文关键词结果质量和数量都更好;中文关键词请先 URL 编码(`jq -rR @uri` 或 `python3 -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1]))' "$QUERY"`)。
103
+ 5. **User-Agent 必须带** — Bing 会按 UA 节流,不带的请求量太少。
104
+ 6. **依赖 GNU grep 的 `-P`** — Linux 默认满足;macOS 需 `brew install grep` 后用 `ggrep`,或换用 `pcregrep`。
105
+ 7. **若所有候选都校验失败** — 增大 `POOL` 重试,或换关键词;少数图床会拒绝 `HEAD`,必要时改成 `curl -sL -r 0-0 -o /dev/null -w '%{http_code}'` 用 1-byte GET 兜底。
@@ -1,12 +1,29 @@
1
1
  {
2
2
  "name": "sophnet-video-generate",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "types": [
5
- "builtin"
5
+ "builtin",
6
+ "store"
6
7
  ],
7
8
  "displayName": "",
8
9
  "description": "",
9
10
  "changelog": [
11
+ {
12
+ "version": "1.0.2",
13
+ "date": "2026-05-11",
14
+ "changes": [
15
+ "补充 store 类型元数据维护,递增版本号"
16
+ ]
17
+ },
18
+ {
19
+ "version": "1.0.1",
20
+ "date": "2026-05-09",
21
+ "changes": [
22
+ "默认模型调整为 Seedance-2.0",
23
+ "修复默认 Seedance 参数兼容性(使用 resolution + duration)",
24
+ "保留用户指定模型优先策略"
25
+ ]
26
+ },
10
27
  {
11
28
  "version": "1.0.0",
12
29
  "date": "2026-04-09",
@@ -16,5 +33,5 @@
16
33
  }
17
34
  ],
18
35
  "createdAt": "2026-04-09",
19
- "updatedAt": "2026-04-09"
36
+ "updatedAt": "2026-05-11"
20
37
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: sophnet-video-generate
3
- description: "Generate videos from text prompts or images using Sophnet API. Supports text-to-video (T2V) and image-to-video (I2V) generation with models including Wan2.6-T2V, Wan2.6-I2V, ViduQ2-pro, and Seedance-1.5-Pro. Use when users request video generation, ask to create videos from descriptions, convert images to videos, or specify video generation models. "
3
+ description: "Generate videos from text prompts or images using Sophnet API. Supports text-to-video (T2V) and image-to-video (I2V) generation with models including Seedance-2.0 (default), Seedance-2.0-Fast, happyhorse-1.0-t2v/i2v, Wan2.6-T2V/I2V, ViduQ2-pro, Seedance-1.5-Pro, and any model name documented for the Sophnet video API. Use when users request video generation, ask to create videos from descriptions, convert images to videos, or specify video generation models. "
4
4
  ---
5
5
 
6
6
  # Video Generator
@@ -9,8 +9,10 @@ Generate videos using Sophnet's video generation API with support for both text-
9
9
 
10
10
  ## Supported Models
11
11
 
12
- - **Wan2.6-T2V**: Text-to-video (default for text-only prompts)
13
- - **Wan2.6-I2V**: Image-to-video (default when image is provided)
12
+ - **Seedance-2.0**: Default model (works for both text-to-video and image-to-video)
13
+ - **Seedance-2.0-Fast**: Lower latency Seedance variant
14
+ - **happyhorse-1.0-t2v / happyhorse-1.0-i2v**: Optional HappyHorse models
15
+ - **Wan2.6-T2V / Wan2.6-I2V**: Example alternatives when the user names them explicitly
14
16
  - **ViduQ2-pro**: Supports both T2V and I2V
15
17
  - **Seedance-1.5-Pro**: Supports both T2V and I2V
16
18
 
@@ -34,16 +36,15 @@ Use the absolute path for the `--first-frame` argument.
34
36
 
35
37
  ### 2. Select Model
36
38
 
37
- - If image provided + user didn't specify model → use Wan2.6-I2V
38
- - If no image + user didn't specify model use Wan2.6-T2V
39
- - If user specifies model → use their choice
39
+ - If user didn't specify model → use Seedance-2.0
40
+ - If user specifies model → pass `--model` through to the API as given (no forced switch to default model). Exception: if they use `happyhorse-1.0-t2v` with `--first-frame`, the script uses `happyhorse-1.0-i2v`; `Wan2.6-T2V` with a first frame is adjusted to `Wan2.6-I2V` when building the request (modality only).
40
41
 
41
42
  ### 3. Run Generation Script
42
43
 
43
44
  ```bash
44
45
  uv run python {baseDir}/scripts/gen_video.py \
45
46
  --prompt "Your video description" \
46
- --model "Wan2.6-T2V" \
47
+ --model "Seedance-2.0" \
47
48
  --size "1280*720" \
48
49
  --duration 5 \
49
50
  --first-frame "/absolute/path/to/image.jpg"
@@ -66,7 +67,7 @@ The script will:
66
67
  3. Poll the API until completion
67
68
  4. Display the final video URL and local save path
68
69
  5. Prompt the user to download the video
69
- 6. Other models: ViduQ2-pro, Seedance-1.5-Pro
70
+ 6. Lists other common models in console output; any documented Sophnet video model name can be passed via `--model`.
70
71
 
71
72
  Example output:
72
73
 
@@ -104,7 +105,7 @@ uv run python {baseDir}/scripts/gen_video.py \
104
105
  ```bash
105
106
  uv run python {baseDir}/scripts/gen_video.py \
106
107
  --prompt "A cat playing with yarn" \
107
- --model "ViduQ2-pro"
108
+ --model "Seedance-2.0"
108
109
  ```
109
110
 
110
111
  ## Notes
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
3
  Sophnet Video Generation Script
4
- Supports text-to-video and image-to-video generation using Wan2.6 models.
4
+ Supports text-to-video and image-to-video; default model is Seedance unless the user specifies another model.
5
5
  """
6
6
  import os
7
7
  import sys
@@ -22,7 +22,7 @@ GENERATE_URL = "https://www.sophnet.com/api/open-apis/projects/easyllms/videogen
22
22
 
23
23
  def create_request(
24
24
  prompt: Optional[str],
25
- model: str = "Wan2.6-T2V",
25
+ model: str = "Seedance-2.0",
26
26
  negative_prompt: Optional[str] = None,
27
27
  first_frame_url: Optional[str] = None,
28
28
  last_frame_url: Optional[str] = None,
@@ -48,8 +48,10 @@ def create_request(
48
48
  "image_url": {"url": first_frame_url},
49
49
  "role": "first_frame"
50
50
  })
51
- if model == "Wan2.6-T2V":
52
- # If user specified T2V but provided an image, switch to I2V
51
+ # Modality fix only: same family T2V + image → I2V (does not replace unrelated user model choices).
52
+ if model == "happyhorse-1.0-t2v":
53
+ model = "happyhorse-1.0-i2v"
54
+ elif model == "Wan2.6-T2V":
53
55
  model = "Wan2.6-I2V"
54
56
 
55
57
  # Add last frame
@@ -59,14 +61,22 @@ def create_request(
59
61
  "image_url": {"url": last_frame_url},
60
62
  "role": "last_frame"
61
63
  })
62
- else:
63
- model = "Wan2.6-T2V"
64
64
 
65
- # Build parameters
66
- parameters = {
67
- "size": size.replace("x", "*"),
68
- "duration": duration
69
- }
65
+ # Build parameters.
66
+ # Seedance uses resolution levels (e.g. 720p/1080p), while some other models accept size (e.g. 1280*720).
67
+ def infer_resolution_from_size(raw_size: str) -> str:
68
+ normalized = raw_size.lower().replace("*", "x")
69
+ if normalized in {"1920x1080", "1080x1920"}:
70
+ return "1080p"
71
+ if normalized in {"1280x720", "720x1280", "1088x832", "832x1088", "960x960"}:
72
+ return "720p"
73
+ return "720p"
74
+
75
+ parameters = {"duration": duration}
76
+ if model in {"Seedance-2.0", "Seedance-2.0-Fast", "Seedance-1.5-Pro"}:
77
+ parameters["resolution"] = infer_resolution_from_size(size)
78
+ else:
79
+ parameters["size"] = size.replace("x", "*")
70
80
 
71
81
  return {"model": model, "content": content, "parameters": parameters}
72
82
 
@@ -170,7 +180,7 @@ def get_file_with_wget(url: str, result_name: str, result_path: str) -> bool:
170
180
 
171
181
  def gen_video(
172
182
  prompt: str,
173
- model: str = "Wan2.6-T2V",
183
+ model: str = "Seedance-2.0",
174
184
  size: str = "1280*720",
175
185
  duration: int = 5,
176
186
  first_frame: Optional[str] = None,
@@ -246,38 +256,42 @@ def gen_video(
246
256
  time.sleep(5)
247
257
 
248
258
  if __name__ == "__main__":
249
- supported_models = ["Wan2.6-T2V", "Wan2.6-I2V", "ViduQ2-pro", "Seedance-1.5-Pro"]
259
+ # Listed for UX hints only; unknown models are still sent to the API as the user passed them.
260
+ supported_models = [
261
+ "happyhorse-1.0-t2v",
262
+ "happyhorse-1.0-i2v",
263
+ "Wan2.6-T2V",
264
+ "Wan2.6-I2V",
265
+ "ViduQ2-pro",
266
+ "Seedance-2.0",
267
+ "Seedance-2.0-Fast",
268
+ "Seedance-1.5-Pro",
269
+ ]
250
270
  parser = argparse.ArgumentParser(
251
271
  description="Generate videos using Sophnet Video Generation API"
252
272
  )
253
273
  parser.add_argument("--prompt", help="Text prompt (required for text-to-video)")
254
- parser.add_argument("--model", type=str, default="Wan2.6-T2V",
255
- help="Model name. Defaults to Wan2.6-I2V if image provided, otherwise Wan2.6-T2V")
274
+ parser.add_argument("--model", type=str, default="Seedance-2.0",
275
+ help="Model name. Defaults to Seedance-2.0")
256
276
  parser.add_argument("--size", type=str, default="1280*720", help="Resolution (default: 1280*720)")
257
277
  parser.add_argument("--duration", type=int, default=5, help="Video duration in seconds (default: 5)")
258
278
  parser.add_argument("--first-frame", type=str, help="First frame image URL or path")
259
279
  parser.add_argument("--generate-audio", action="store_true", help="Generate audio")
260
280
  args = parser.parse_args()
261
281
 
262
- # Auto-select model based on whether first frame is provided
263
282
  model = args.model
264
- if args.first_frame and model.find("Wan2.6") != -1:
265
- # If user specified T2V but provided an image, switch to I2V
266
- model = "Wan2.6-I2V"
267
- elif args.first_frame is None and model.find("Wan2.6") != -1:
268
- # If no image provided, ensure using T2V
269
- model = "Wan2.6-T2V"
283
+ # HappyHorse default: T2V + image → I2V (API expects I2V when a frame is supplied).
284
+ if args.first_frame and model == "happyhorse-1.0-t2v":
285
+ model = "happyhorse-1.0-i2v"
286
+ # Friendly name normalization only (canonical Vidu / Seedance names).
270
287
  elif model.find("ViduQ2") != -1:
271
288
  model = "ViduQ2-pro"
272
- elif model.find("Seedance") != -1:
273
- model = "Seedance-1.5-Pro"
289
+ elif model.strip().lower() == "seedance":
290
+ model = "Seedance-2.0"
291
+ elif model.strip().lower() == "seedance-fast":
292
+ model = "Seedance-2.0-Fast"
274
293
  elif model not in supported_models:
275
- if args.first_frame:
276
- print(f"警告: 模型 '{args.model}' 不受支持,已自动切换到 Wan2.6-I2V")
277
- model = "Wan2.6-I2V"
278
- else:
279
- print(f"警告: 模型 '{args.model}' 不受支持,已自动切换到 Wan2.6-T2V")
280
- model = "Wan2.6-T2V"
294
+ print(f"提示: 模型 '{args.model}' 不在内置常用列表中,将按您指定的名称原样调用 API。")
281
295
 
282
296
  result_url, local_video_url = gen_video(
283
297
  args.prompt,
@@ -298,7 +312,10 @@ if __name__ == "__main__":
298
312
  other_models_str = "、".join(other_models)
299
313
  print(f"当前使用的模型为 {model},还支持 {other_models_str}")
300
314
  print(f"如果想要指定模型,可以直接对我说:使用 [模型名称] 模型,生成 [视频描述]")
301
- print(f"提示: 模型名称可以是: Wan2.6-T2V、Wan2.6-I2V、ViduQ2-pro 或 Seedance-1.5-Pro")
315
+ print(
316
+ "提示: 常用模型示例: happyhorse-1.0-t2v、happyhorse-1.0-i2v、"
317
+ "Wan2.6-T2V、Wan2.6-I2V、ViduQ2-pro、Seedance-2.0、Seedance-2.0-Fast、Seedance-1.5-Pro(也可传入文档中的其他模型名)"
318
+ )
302
319
  else:
303
320
  print("\n视频生成失败")
304
321
  sys.exit(1)