coze-coding-dev-sdk 0.5.16__tar.gz → 0.5.17__tar.gz

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.

Potentially problematic release.


This version of coze-coding-dev-sdk might be problematic. Click here for more details.

Files changed (92) hide show
  1. {coze_coding_dev_sdk-0.5.16/coze_coding_dev_sdk.egg-info → coze_coding_dev_sdk-0.5.17}/PKG-INFO +1 -1
  2. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/core/url_utils.py +84 -11
  3. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/video/__init__.py +10 -2
  4. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/video/client.py +104 -7
  5. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/video/models.py +21 -1
  6. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17/coze_coding_dev_sdk.egg-info}/PKG-INFO +1 -1
  7. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/pyproject.toml +1 -1
  8. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/CHANGELOG.md +0 -0
  9. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/LICENSE +0 -0
  10. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/MANIFEST.in +0 -0
  11. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/README.md +0 -0
  12. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/__init__.py +0 -0
  13. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/__init__.py +0 -0
  14. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/chat.py +0 -0
  15. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/cli.py +0 -0
  16. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/constants.py +0 -0
  17. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/db.py +0 -0
  18. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/document.py +0 -0
  19. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/embedding.py +0 -0
  20. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/image.py +0 -0
  21. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/knowledge.py +0 -0
  22. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/search.py +0 -0
  23. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/storage.py +0 -0
  24. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/supabase.py +0 -0
  25. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/utils.py +0 -0
  26. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/video.py +0 -0
  27. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/video_edit.py +0 -0
  28. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/cli/voice.py +0 -0
  29. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/core/__init__.py +0 -0
  30. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/core/client.py +0 -0
  31. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/core/config.py +0 -0
  32. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/core/exceptions.py +0 -0
  33. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/database/__init__.py +0 -0
  34. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/database/client.py +0 -0
  35. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/database/migration.py +0 -0
  36. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/document/__init__.py +0 -0
  37. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/document/client.py +0 -0
  38. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/document/docx_generator.py +0 -0
  39. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/document/models.py +0 -0
  40. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/document/pdf_generator.py +0 -0
  41. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/document/pptx_generator.py +0 -0
  42. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/document/xlsx_generator.py +0 -0
  43. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/embedding/__init__.py +0 -0
  44. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/embedding/client.py +0 -0
  45. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/embedding/models.py +0 -0
  46. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/fetch/__init__.py +0 -0
  47. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/fetch/client.py +0 -0
  48. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/fetch/models.py +0 -0
  49. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/image/__init__.py +0 -0
  50. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/image/client.py +0 -0
  51. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/image/models.py +0 -0
  52. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/knowledge/__init__.py +0 -0
  53. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/knowledge/client.py +0 -0
  54. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/knowledge/models.py +0 -0
  55. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/llm/__init__.py +0 -0
  56. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/llm/client.py +0 -0
  57. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/llm/models.py +0 -0
  58. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/memory/__init__.py +0 -0
  59. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/memory/client.py +0 -0
  60. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/report/__init__.py +0 -0
  61. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/report/buffer.py +0 -0
  62. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/report/client.py +0 -0
  63. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/report/interceptors/__init__.py +0 -0
  64. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/report/interceptors/boto3_hook.py +0 -0
  65. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/report/interceptors/httpx_transport.py +0 -0
  66. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/report/models.py +0 -0
  67. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/report/singleton.py +0 -0
  68. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/report/utils.py +0 -0
  69. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/s3/__init__.py +0 -0
  70. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/s3/client.py +0 -0
  71. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/s3/models.py +0 -0
  72. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/search/__init__.py +0 -0
  73. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/search/client.py +0 -0
  74. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/search/models.py +0 -0
  75. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/supabase/__init__.py +0 -0
  76. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/supabase/client.py +0 -0
  77. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/supabase/models.py +0 -0
  78. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/video_edit/__init__.py +0 -0
  79. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/video_edit/examples.py +0 -0
  80. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/video_edit/frame_extractor.py +0 -0
  81. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/video_edit/models.py +0 -0
  82. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/video_edit/video_edit.py +0 -0
  83. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/voice/__init__.py +0 -0
  84. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/voice/asr.py +0 -0
  85. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/voice/models.py +0 -0
  86. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk/voice/tts.py +0 -0
  87. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk.egg-info/SOURCES.txt +0 -0
  88. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk.egg-info/dependency_links.txt +0 -0
  89. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk.egg-info/entry_points.txt +0 -0
  90. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk.egg-info/requires.txt +0 -0
  91. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/coze_coding_dev_sdk.egg-info/top_level.txt +0 -0
  92. {coze_coding_dev_sdk-0.5.16 → coze_coding_dev_sdk-0.5.17}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coze-coding-dev-sdk
3
- Version: 0.5.16
3
+ Version: 0.5.17
4
4
  Summary: Coze Coding Dev SDK - 优雅的多功能 AI SDK,支持图片生成、视频生成、语音合成、语音识别、大语言模型、联网搜索和文本/多模态 Embedding。包含命令行工具 coze-coding-ai,支持 Context 上下文追踪
5
5
  Author-email: Coze Coding Integration Team <support@coze.com>
6
6
  Maintainer-email: Coze Coding Integration Team <support@coze.com>
@@ -1,8 +1,9 @@
1
1
  """
2
2
  URL 校验工具模块
3
- 提供 URL 格式校验、协议校验、本地地址拦截、临时URL检测和可达性预检功能
3
+ 提供 URL 格式校验、协议校验、本地地址拦截、临时URL检测、base64 data URI 检测和可达性预检功能
4
4
  """
5
5
 
6
+ import re
6
7
  from urllib.parse import urlparse
7
8
  from typing import Optional
8
9
 
@@ -23,6 +24,34 @@ _EPHEMERAL_URL_PATTERNS = [
23
24
  ("code.coze.cn", _SANDBOX_PROXY_PATH),
24
25
  ]
25
26
 
27
+ # base64 data URI 格式:data:<mediatype>;base64,<data>
28
+ # 例如 data:image/png;base64,iVBORw0KGgo...
29
+ # 捕获 mediatype(如 image/png),用于进一步的格式校验
30
+ _BASE64_DATA_URI_RE = re.compile(
31
+ r"^data:([\w.+-]+/[\w.+-]+)(?:;[\w.+-]+=[\w.+-]+)*;base64,[A-Za-z0-9+/]+={0,2}$",
32
+ re.IGNORECASE,
33
+ )
34
+
35
+ # 老旧 / 大模型普遍不支持的图片格式(mediatype 全小写匹配)
36
+ # 这些格式(如 WMF/EMF/TIFF/BMP 等)很多多模态模型无法解析,建议改用 PNG/JPEG/WEBP 等。
37
+ _UNSUPPORTED_IMAGE_MEDIATYPES = frozenset({
38
+ "image/x-wmf",
39
+ "image/wmf",
40
+ "image/x-emf",
41
+ "image/emf",
42
+ "image/x-ms-bmp",
43
+ "image/tiff",
44
+ "image/x-tiff",
45
+ "image/x-icon",
46
+ "image/vnd.microsoft.icon",
47
+ "image/x-portable-pixmap",
48
+ "image/x-portable-bitmap",
49
+ "image/x-portable-graymap",
50
+ })
51
+
52
+ # 推荐的图片格式(用于错误提示)
53
+ _RECOMMENDED_IMAGE_FORMATS = "PNG, JPEG, WEBP or GIF"
54
+
26
55
 
27
56
  class URLValidationError(ValidationError):
28
57
  """URL 校验失败异常"""
@@ -51,6 +80,37 @@ def _is_local_path(value: str) -> bool:
51
80
  return False
52
81
 
53
82
 
83
+ def is_base64_data_uri(value: str) -> bool:
84
+ """
85
+ 检测字符串是否为合法的 base64 编码 data URI。
86
+
87
+ 仅匹配带 ;base64 标记且数据部分为合法 base64 字符集的 data URI,
88
+ 例如 data:image/png;base64,iVBORw0KGgo...
89
+ 非 base64 的 data URI(如 data:text/html,<h1>hi</h1>)不视为合法。
90
+
91
+ 注意:本函数只校验「格式」,不判断 mediatype 是否为受支持的图片格式。
92
+
93
+ Args:
94
+ value: 待检测的字符串
95
+
96
+ Returns:
97
+ bool: True 表示是合法的 base64 data URI
98
+ """
99
+ if not value or not isinstance(value, str):
100
+ return False
101
+ return bool(_BASE64_DATA_URI_RE.match(value.strip()))
102
+
103
+
104
+ def _get_data_uri_mediatype(value: str) -> Optional[str]:
105
+ """从合法的 base64 data URI 中提取 mediatype(小写),非法格式返回 None。"""
106
+ if not value or not isinstance(value, str):
107
+ return None
108
+ m = _BASE64_DATA_URI_RE.match(value.strip())
109
+ if not m:
110
+ return None
111
+ return m.group(1).lower()
112
+
113
+
54
114
  def validate_url(
55
115
  url: str,
56
116
  *,
@@ -62,10 +122,11 @@ def validate_url(
62
122
 
63
123
  检查项:
64
124
  1. 非空、字符串类型校验
65
- 2. URL 格式校验(scheme + netloc)
66
- 3. 协议校验:仅允许 http/https
67
- 4. 本地地址拦截:禁止 localhost/127.0.0.1/0.0.0.0/::1
68
- 5. 可选 HEAD 预检:确认 URL 可达(不下载内容)
125
+ 2. base64 data URI 直接放行(如 data:image/png;base64,...),但拦截老旧/不受支持的图片格式(如 image/x-wmf)
126
+ 3. URL 格式校验(scheme + netloc)
127
+ 4. 协议校验:仅允许 http/https
128
+ 5. 本地地址拦截:禁止 localhost/127.0.0.1/0.0.0.0/::1
129
+ 6. 可选 HEAD 预检:确认 URL 可达(不下载内容)
69
130
 
70
131
  注意:不做 DNS 解析到 IP 再判断私有网段的检查,避免误杀(如内部 CDN 域名解析到内网 IP 的合法场景)。
71
132
 
@@ -75,7 +136,7 @@ def validate_url(
75
136
  timeout: HEAD 预检超时秒数,默认 5
76
137
 
77
138
  Returns:
78
- str: 经过 strip 的合法 URL
139
+ str: 经过 strip 的合法 URL(base64 data URI 原样返回)
79
140
 
80
141
  Raises:
81
142
  URLValidationError: URL 校验失败
@@ -89,7 +150,19 @@ def validate_url(
89
150
  if not url:
90
151
  raise URLValidationError("URL cannot be empty", url=url)
91
152
 
92
- # 2. 格式校验
153
+ # 2. base64 data URI 直接放行(无需格式/协议/可达性校验)
154
+ # 但拦截老旧 / 大模型普遍不支持的图片格式(如 WMF/EMF/TIFF 等),提示改用主流格式
155
+ if is_base64_data_uri(url):
156
+ mediatype = _get_data_uri_mediatype(url)
157
+ if mediatype in _UNSUPPORTED_IMAGE_MEDIATYPES:
158
+ raise URLValidationError(
159
+ f"The image format '{mediatype}' is outdated and not supported by many models. "
160
+ f"Please convert the image to a widely-supported format ({_RECOMMENDED_IMAGE_FORMATS}) and try again.",
161
+ url=url,
162
+ )
163
+ return url
164
+
165
+ # 3. 格式校验
93
166
  try:
94
167
  parsed = urlparse(url)
95
168
  except Exception:
@@ -112,14 +185,14 @@ def validate_url(
112
185
  f"Invalid URL format (missing scheme or host): {url}", url=url
113
186
  )
114
187
 
115
- # 3. 协议校验
188
+ # 4. 协议校验
116
189
  if parsed.scheme.lower() not in _ALLOWED_SCHEMES:
117
190
  raise URLValidationError(
118
191
  f"Unsupported scheme '{parsed.scheme}', only http/https allowed",
119
192
  url=url,
120
193
  )
121
194
 
122
- # 4. 本地地址拦截(字符串匹配,不做 DNS 解析)
195
+ # 5. 本地地址拦截(字符串匹配,不做 DNS 解析)
123
196
  hostname = parsed.hostname
124
197
  if not hostname:
125
198
  raise URLValidationError(f"Cannot extract hostname from URL: {url}", url=url)
@@ -129,7 +202,7 @@ def validate_url(
129
202
  f"Access to local address is not allowed: {hostname}", url=url
130
203
  )
131
204
 
132
- # 5. 临时 URL 检测(沙箱代理等)
205
+ # 6. 临时 URL 检测(沙箱代理等)
133
206
  if is_ephemeral_url(url):
134
207
  raise URLValidationError(
135
208
  f"This URL appears to be a temporary sandbox proxy URL that may expire. "
@@ -137,7 +210,7 @@ def validate_url(
137
210
  url=url,
138
211
  )
139
212
 
140
- # 6. 可选 HEAD 预检
213
+ # 7. 可选 HEAD 预检
141
214
  if allow_head_check:
142
215
  _head_check(url, timeout=timeout)
143
216
 
@@ -4,7 +4,11 @@ from .models import (
4
4
  VideoGenerationTask,
5
5
  TextContent,
6
6
  ImageURLContent,
7
- ImageURL
7
+ ImageURL,
8
+ VideoURLContent,
9
+ VideoURL,
10
+ AudioURLContent,
11
+ AudioURL,
8
12
  )
9
13
 
10
14
  __all__ = [
@@ -13,5 +17,9 @@ __all__ = [
13
17
  "VideoGenerationTask",
14
18
  "TextContent",
15
19
  "ImageURLContent",
16
- "ImageURL"
20
+ "ImageURL",
21
+ "VideoURLContent",
22
+ "VideoURL",
23
+ "AudioURLContent",
24
+ "AudioURL",
17
25
  ]
@@ -11,10 +11,12 @@ from ..core.config import Config
11
11
  from ..core.exceptions import APIError
12
12
  from ..core.url_utils import validate_url
13
13
  from .models import (
14
+ AudioURLContent,
14
15
  ImageURLContent,
15
16
  TextContent,
16
17
  VideoGenerationRequest,
17
18
  VideoGenerationTask,
19
+ VideoURLContent,
18
20
  )
19
21
 
20
22
  logger = logging.getLogger(__name__)
@@ -31,10 +33,99 @@ class VideoGenerationClient(BaseClient):
31
33
  super().__init__(config, ctx, custom_headers, verbose)
32
34
  self.base_url = self.config.base_url
33
35
 
36
+ @staticmethod
37
+ def _validate_content_items(
38
+ content_items: List[Union[TextContent, ImageURLContent, VideoURLContent, AudioURLContent]],
39
+ model: str,
40
+ ) -> None:
41
+ """校验 content_items 是否符合三个互斥场景及数量/模型约束。
42
+
43
+ 三个互斥场景:
44
+ 1. 图生视频-首帧 / 首尾帧 (role=first_frame / last_frame)
45
+ 2. 多模态参考生视频 (role=reference_image / 任意 video_url / audio_url)
46
+ 3. 文生视频(无图片/视频/音频)
47
+ 多模态参考:
48
+ - 必须包含至少 1 个 reference_image 或 reference_video(不可单独输入音频)
49
+ - reference_image 0~9,reference_video 0~3,reference_audio 0~3
50
+ - 仅 doubao-seedance-2-0-260128 支持
51
+ 首/尾帧:
52
+ - first_frame 至多 1 个,last_frame 至多 1 个
53
+ - 提供 last_frame 时必须同时提供 first_frame
54
+ """
55
+ first_frame_count = 0
56
+ last_frame_count = 0
57
+ reference_image_count = 0
58
+ reference_video_count = 0
59
+ reference_audio_count = 0
60
+
61
+ for item in content_items:
62
+ if isinstance(item, ImageURLContent):
63
+ if item.role == "first_frame":
64
+ first_frame_count += 1
65
+ elif item.role == "last_frame":
66
+ last_frame_count += 1
67
+ elif item.role == "reference_image":
68
+ reference_image_count += 1
69
+ elif isinstance(item, VideoURLContent):
70
+ reference_video_count += 1
71
+ elif isinstance(item, AudioURLContent):
72
+ reference_audio_count += 1
73
+
74
+ is_first_last_frame = first_frame_count > 0 or last_frame_count > 0
75
+ is_multimodal = (
76
+ reference_image_count > 0
77
+ or reference_video_count > 0
78
+ or reference_audio_count > 0
79
+ )
80
+
81
+ if is_first_last_frame and is_multimodal:
82
+ raise ValueError(
83
+ "图生视频-首尾帧 与 多模态参考生视频 为互斥场景,不可混用。"
84
+ "请只使用 first_frame/last_frame 角色,或只使用 reference_image/"
85
+ "reference_video/reference_audio。如需『首尾帧 + 多模态参考』效果,"
86
+ "可在多模态场景中通过提示词指定参考图作为首帧/尾帧。"
87
+ )
88
+
89
+ if is_multimodal:
90
+ if model != "doubao-seedance-2-0-260128":
91
+ raise ValueError(
92
+ f"多模态参考生视频(reference_image/reference_video/reference_audio)"
93
+ f"仅支持 doubao-seedance-2-0-260128 模型,当前模型为 {model}"
94
+ )
95
+ if reference_image_count == 0 and reference_video_count == 0:
96
+ raise ValueError(
97
+ "多模态参考生视频至少需要包含 1 个 reference_image 或 reference_video,"
98
+ "不可单独输入 reference_audio。"
99
+ )
100
+ if reference_image_count > 9:
101
+ raise ValueError(
102
+ f"reference_image 数量超出限制:最多 9 个,当前 {reference_image_count} 个"
103
+ )
104
+ if reference_video_count > 3:
105
+ raise ValueError(
106
+ f"reference_video 数量超出限制:最多 3 个,当前 {reference_video_count} 个"
107
+ )
108
+ if reference_audio_count > 3:
109
+ raise ValueError(
110
+ f"reference_audio 数量超出限制:最多 3 个,当前 {reference_audio_count} 个"
111
+ )
112
+
113
+ if is_first_last_frame:
114
+ if first_frame_count > 1:
115
+ raise ValueError(
116
+ f"first_frame 角色至多 1 个,当前 {first_frame_count} 个"
117
+ )
118
+ if last_frame_count > 1:
119
+ raise ValueError(
120
+ f"last_frame 角色至多 1 个,当前 {last_frame_count} 个"
121
+ )
122
+ if last_frame_count > 0 and first_frame_count == 0:
123
+ raise ValueError("提供 last_frame 时必须同时提供 first_frame")
124
+
34
125
  def _create_task(
35
126
  self,
36
127
  model: str,
37
- content: List[Union[TextContent, ImageURLContent]],
128
+ content: List[Union[TextContent, ImageURLContent, VideoURLContent, AudioURLContent]],
38
129
  resolution: Optional[str] = "720p",
39
130
  ratio: Optional[str] = "16:9",
40
131
  duration: Optional[int] = 5,
@@ -74,10 +165,10 @@ class VideoGenerationClient(BaseClient):
74
165
  @observe(name="video_generation")
75
166
  def video_generation(
76
167
  self,
77
- content_items: List[Union[TextContent, ImageURLContent]],
168
+ content_items: List[Union[TextContent, ImageURLContent, VideoURLContent, AudioURLContent]],
78
169
  callback_url: Optional[str] = None,
79
170
  return_last_frame: Optional[bool] = False,
80
- model: str = "doubao-seedance-1-5-pro-251215",
171
+ model: str = "doubao-seedance-2-0-260128",
81
172
  max_wait_time: int = 900,
82
173
  resolution: Optional[str] = "720p",
83
174
  ratio: Optional[str] = "16:9",
@@ -94,7 +185,7 @@ class VideoGenerationClient(BaseClient):
94
185
  content_items: 输入给模型,生成视频的信息,支持文本信息和图片信息。
95
186
  callback_url: 可选,填写本次生成任务结果的回调通知地址。当视频生成任务有状态变化时,方舟将向此地址推送 POST 请求。
96
187
  return_last_frame: 可选,返回生成视频的尾帧图像。设置为 true 后,可获取视频的尾帧图像。
97
- model: 模型名称,默认使用 doubao-seedance-1-5-pro-251215
188
+ model: 模型名称,默认使用 doubao-seedance-2-0-260128
98
189
  max_wait_time: 最大等待时间(秒),默认 900 秒
99
190
  resolution: 视频分辨率,可选 "480p" 或 "720p",默认 "720p"
100
191
  ratio: 视频比例,可选 "16:9", "9:16", "1:1", "4:3", "3:4", "21:9", "adaptive",默认 "16:9"
@@ -132,9 +223,15 @@ class VideoGenerationClient(BaseClient):
132
223
  """
133
224
  poll_interval = 5
134
225
 
226
+ self._validate_content_items(content_items, model)
227
+
135
228
  for item in content_items:
136
229
  if isinstance(item, ImageURLContent):
137
230
  item.image_url.url = validate_url(item.image_url.url)
231
+ elif isinstance(item, VideoURLContent):
232
+ item.video_url.url = validate_url(item.video_url.url)
233
+ elif isinstance(item, AudioURLContent):
234
+ item.audio_url.url = validate_url(item.audio_url.url)
138
235
 
139
236
  request_data = {
140
237
  "model": model,
@@ -275,10 +372,10 @@ class VideoGenerationClient(BaseClient):
275
372
 
276
373
  async def video_generation_async(
277
374
  self,
278
- content_items: List[Union[TextContent, ImageURLContent]],
375
+ content_items: List[Union[TextContent, ImageURLContent, VideoURLContent, AudioURLContent]],
279
376
  callback_url: Optional[str] = None,
280
377
  return_last_frame: Optional[bool] = False,
281
- model: str = "doubao-seedance-1-5-pro-251215",
378
+ model: str = "doubao-seedance-2-0-260128",
282
379
  max_wait_time: int = 900,
283
380
  resolution: Optional[str] = "720p",
284
381
  ratio: Optional[str] = "16:9",
@@ -315,7 +412,7 @@ class VideoGenerationClient(BaseClient):
315
412
  content_items: 输入给模型,生成视频的信息,支持文本信息和图片信息。
316
413
  callback_url: 可选,填写本次生成任务结果的回调通知地址。
317
414
  return_last_frame: 可选,返回生成视频的尾帧图像。
318
- model: 模型名称,默认使用 doubao-seedance-1-5-pro-251215
415
+ model: 模型名称,默认使用 doubao-seedance-2-0-260128
319
416
  max_wait_time: 最大等待时间(秒),默认 900 秒
320
417
  resolution: 视频分辨率,可选 "480p" 或 "720p",默认 "720p"
321
418
  ratio: 视频比例,可选 "16:9", "9:16", "1:1", "4:3", "3:4", "21:9", "adaptive",默认 "16:9"
@@ -13,6 +13,26 @@ class ImageURLContent(BaseModel):
13
13
  role: Optional[Literal["first_frame", "last_frame", "reference_image"]] = None
14
14
 
15
15
 
16
+ class VideoURL(BaseModel):
17
+ url: str
18
+
19
+
20
+ class VideoURLContent(BaseModel):
21
+ type: Literal["video_url"] = "video_url"
22
+ video_url: VideoURL
23
+ role: Optional[Literal["reference_video"]] = "reference_video"
24
+
25
+
26
+ class AudioURL(BaseModel):
27
+ url: str
28
+
29
+
30
+ class AudioURLContent(BaseModel):
31
+ type: Literal["audio_url"] = "audio_url"
32
+ audio_url: AudioURL
33
+ role: Optional[Literal["reference_audio"]] = "reference_audio"
34
+
35
+
16
36
  class TextContent(BaseModel):
17
37
  type: Literal["text"] = "text"
18
38
  text: str
@@ -20,7 +40,7 @@ class TextContent(BaseModel):
20
40
 
21
41
  class VideoGenerationRequest(BaseModel):
22
42
  model: str
23
- content: List[Union[TextContent, ImageURLContent]]
43
+ content: List[Union[TextContent, ImageURLContent, VideoURLContent, AudioURLContent]]
24
44
  resolution: Optional[Literal["480p", "720p", "1080p"]] = "720p"
25
45
  ratio: Optional[
26
46
  Literal["16:9", "9:16", "1:1", "4:3", "3:4", "21:9", "adaptive"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coze-coding-dev-sdk
3
- Version: 0.5.16
3
+ Version: 0.5.17
4
4
  Summary: Coze Coding Dev SDK - 优雅的多功能 AI SDK,支持图片生成、视频生成、语音合成、语音识别、大语言模型、联网搜索和文本/多模态 Embedding。包含命令行工具 coze-coding-ai,支持 Context 上下文追踪
5
5
  Author-email: Coze Coding Integration Team <support@coze.com>
6
6
  Maintainer-email: Coze Coding Integration Team <support@coze.com>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "coze-coding-dev-sdk"
7
- version = "0.5.16"
7
+ version = "0.5.17"
8
8
  description = "Coze Coding Dev SDK - 优雅的多功能 AI SDK,支持图片生成、视频生成、语音合成、语音识别、大语言模型、联网搜索和文本/多模态 Embedding。包含命令行工具 coze-coding-ai,支持 Context 上下文追踪"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"