Skip to content

Commit 8be26af

Browse files
committed
feat-mul
1 parent 2b454aa commit 8be26af

4 files changed

Lines changed: 19 additions & 24 deletions

File tree

cozeloop/entities/prompt.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,10 @@ class ContentType(str, Enum):
5050
MULTI_PART_VARIABLE = "multi_part_variable"
5151

5252

53-
class ImageURL(BaseModel):
54-
url: str
55-
56-
5753
class ContentPart(BaseModel):
5854
type: ContentType
5955
text: Optional[str] = None
60-
image_url: Optional[ImageURL] = None
56+
image_url: Optional[str] = None
6157

6258

6359
class Message(BaseModel):

cozeloop/internal/prompt/converter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ def _to_span_content_part(entity_part: EntityContentPart) -> ModelMessagePart:
244244
image_url = None
245245
if entity_part.image_url is not None:
246246
image_url = ModelImageURL(
247-
url=entity_part.image_url.url
247+
url=entity_part.image_url
248248
)
249249
return ModelMessagePart(
250250
type=_to_span_content_type(entity_part.type),

examples/prompt/multipart/prompt_hub_with_multipart.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import cozeloop
99
from cozeloop import Message
10-
from cozeloop.entities.prompt import Role, ContentPart, ContentType, ImageURL
10+
from cozeloop.entities.prompt import Role, ContentPart, ContentType
1111
from cozeloop.spec.tracespec import CALL_OPTIONS, ModelCallOption, ModelMessage, ModelInput, ModelMessagePartType, ModelMessagePart, ModelImageURL
1212

1313

@@ -24,7 +24,7 @@ def _to_span_content_part(entity_part: ContentPart) -> ModelMessagePart:
2424
image_url = None
2525
if entity_part.image_url is not None:
2626
image_url = ModelImageURL(
27-
url=entity_part.image_url.url
27+
url=entity_part.image_url
2828
)
2929
return ModelMessagePart(
3030
type=_to_span_content_type(entity_part.type),
@@ -144,8 +144,7 @@ def llm_call(self, input_data):
144144
# im1 is a multi-part variable, and the value is a list of ContentPart
145145
"im1": [
146146
ContentPart(type=ContentType.TEXT, text="图片示例"),
147-
ContentPart(type=ContentType.IMAGE_URL,
148-
image_url=ImageURL(url="https://example.com"))
147+
ContentPart(type=ContentType.IMAGE_URL, image_url="https://dummyimage.com/600x400/4CAF50/fff&text="),
149148
],
150149
# Other variables in the prompt template that are not provided with corresponding values will be
151150
# considered as empty values.

tests/internal/prompt/test_prompt.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from cozeloop.entities.prompt import (
99
Prompt, Message, VariableDef, VariableType, TemplateType, Role, PromptVariable,
10-
ContentType, ContentPart, ImageURL
10+
ContentType, ContentPart
1111
)
1212
from cozeloop.internal import consts
1313
from cozeloop.internal.consts.error import RemoteServiceError
@@ -1134,7 +1134,7 @@ def test_validate_variable_values_type_multi_part_valid(prompt_provider):
11341134
# 创建有效的 ContentPart 列表
11351135
content_parts = [
11361136
ContentPart(type=ContentType.TEXT, text="Hello"),
1137-
ContentPart(type=ContentType.IMAGE_URL, image_url=ImageURL(url="https://example.com/image.jpg"))
1137+
ContentPart(type=ContentType.IMAGE_URL, image_url="https://example.com/image.jpg")
11381138
]
11391139

11401140
var_defs = [VariableDef(key="multi_content", desc="Multi-part content", type=VariableType.MULTI_PART)]
@@ -1168,7 +1168,7 @@ def test_format_multi_part_text_rendering(prompt_provider):
11681168
# 创建包含模板变量的 ContentPart 列表
11691169
parts = [
11701170
ContentPart(type=ContentType.TEXT, text="Hello {{name}}!"),
1171-
ContentPart(type=ContentType.IMAGE_URL, image_url=ImageURL(url="https://example.com/image.jpg"))
1171+
ContentPart(type=ContentType.IMAGE_URL, image_url="https://example.com/image.jpg")
11721172
]
11731173

11741174
variable_def_map = {"name": VariableDef(key="name", desc="User name", type=VariableType.STRING)}
@@ -1186,7 +1186,7 @@ def test_format_multi_part_text_rendering(prompt_provider):
11861186
assert result[0].type == ContentType.TEXT
11871187
assert result[0].text == "Hello Alice!"
11881188
assert result[1].type == ContentType.IMAGE_URL
1189-
assert result[1].image_url.url == "https://example.com/image.jpg"
1189+
assert result[1].image_url == "https://example.com/image.jpg"
11901190

11911191
def test_format_multi_part_variable_expansion(prompt_provider):
11921192
"""测试多媒体变量的展开"""
@@ -1199,7 +1199,7 @@ def test_format_multi_part_variable_expansion(prompt_provider):
11991199
# 创建动态内容
12001200
dynamic_parts = [
12011201
ContentPart(type=ContentType.TEXT, text="Dynamic text"),
1202-
ContentPart(type=ContentType.IMAGE_URL, image_url=ImageURL(url="https://example.com/dynamic.jpg"))
1202+
ContentPart(type=ContentType.IMAGE_URL, image_url="https://example.com/dynamic.jpg")
12031203
]
12041204

12051205
variable_def_map = {
@@ -1221,7 +1221,7 @@ def test_format_multi_part_variable_expansion(prompt_provider):
12211221
assert result[1].type == ContentType.TEXT
12221222
assert result[1].text == "Dynamic text"
12231223
assert result[2].type == ContentType.IMAGE_URL
1224-
assert result[2].image_url.url == "https://example.com/dynamic.jpg"
1224+
assert result[2].image_url == "https://example.com/dynamic.jpg"
12251225

12261226
def test_format_multi_part_empty_parts(prompt_provider):
12271227
"""测试空的多媒体内容列表"""
@@ -1267,7 +1267,7 @@ def test_format_multi_part_filter_empty_content(prompt_provider):
12671267
ContentPart(type=ContentType.TEXT, text="Valid text"),
12681268
ContentPart(type=ContentType.TEXT, text=None), # 空文本
12691269
ContentPart(type=ContentType.IMAGE_URL, image_url=None), # 空图片
1270-
ContentPart(type=ContentType.IMAGE_URL, image_url=ImageURL(url="https://example.com/image.jpg"))
1270+
ContentPart(type=ContentType.IMAGE_URL, image_url="https://example.com/image.jpg")
12711271
]
12721272

12731273
variable_def_map = {}
@@ -1283,13 +1283,13 @@ def test_format_multi_part_filter_empty_content(prompt_provider):
12831283
# 应该过滤掉空内容的部分
12841284
assert len(result) == 2
12851285
assert result[0].text == "Valid text"
1286-
assert result[1].image_url.url == "https://example.com/image.jpg"
1286+
assert result[1].image_url == "https://example.com/image.jpg"
12871287

12881288
def test_format_multi_part_jinja2_template(prompt_provider):
12891289
"""测试使用 Jinja2 模板的多媒体内容渲染"""
12901290
parts = [
12911291
ContentPart(type=ContentType.TEXT, text="Hello {{ name }}! You have {{ count }} messages."),
1292-
ContentPart(type=ContentType.IMAGE_URL, image_url=ImageURL(url="https://example.com/avatar.jpg"))
1292+
ContentPart(type=ContentType.IMAGE_URL, image_url="https://example.com/avatar.jpg")
12931293
]
12941294

12951295
variable_def_map = {
@@ -1310,7 +1310,7 @@ def test_format_multi_part_jinja2_template(prompt_provider):
13101310
assert result[0].type == ContentType.TEXT
13111311
assert result[0].text == "Hello Bob! You have 3 messages."
13121312
assert result[1].type == ContentType.IMAGE_URL
1313-
assert result[1].image_url.url == "https://example.com/avatar.jpg"
1313+
assert result[1].image_url == "https://example.com/avatar.jpg"
13141314

13151315
def test_format_normal_messages_with_parts(prompt_provider):
13161316
"""测试包含 parts 字段的消息格式化"""
@@ -1330,7 +1330,7 @@ def test_format_normal_messages_with_parts(prompt_provider):
13301330
]
13311331

13321332
image_parts = [
1333-
ContentPart(type=ContentType.IMAGE_URL, image_url=ImageURL(url="https://example.com/photo.jpg"))
1333+
ContentPart(type=ContentType.IMAGE_URL, image_url="https://example.com/photo.jpg")
13341334
]
13351335

13361336
variables = {
@@ -1360,7 +1360,7 @@ def test_format_normal_messages_with_parts(prompt_provider):
13601360

13611361
# 验证第二个部分(展开的图片)
13621362
assert result[0].parts[1].type == ContentType.IMAGE_URL
1363-
assert result[0].parts[1].image_url.url == "https://example.com/photo.jpg"
1363+
assert result[0].parts[1].image_url == "https://example.com/photo.jpg"
13641364

13651365
def test_prompt_format_with_multi_part_integration(prompt_provider):
13661366
"""测试多媒体内容的完整集成"""
@@ -1394,7 +1394,7 @@ def test_prompt_format_with_multi_part_integration(prompt_provider):
13941394

13951395
# 创建用户图片内容
13961396
user_image_parts = [
1397-
ContentPart(type=ContentType.IMAGE_URL, image_url=ImageURL(url="https://example.com/user_photo.jpg")),
1397+
ContentPart(type=ContentType.IMAGE_URL, image_url="https://example.com/user_photo.jpg"),
13981398
ContentPart(type=ContentType.TEXT, text="What do you see in this image?")
13991399
]
14001400

@@ -1427,7 +1427,7 @@ def test_prompt_format_with_multi_part_integration(prompt_provider):
14271427

14281428
# 第二个部分是展开的图片
14291429
assert result[1].parts[1].type == ContentType.IMAGE_URL
1430-
assert result[1].parts[1].image_url.url == "https://example.com/user_photo.jpg"
1430+
assert result[1].parts[1].image_url == "https://example.com/user_photo.jpg"
14311431

14321432
# 第三个部分是展开的文本
14331433
assert result[1].parts[2].type == ContentType.TEXT

0 commit comments

Comments
 (0)