-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Provide a standard base class for creating custom Signature field type #8217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
dspy/adapters/types/base_type.py
Outdated
# Custom type messages are only in user messages | ||
continue | ||
|
||
pattern = r"<<CUSTOM-TYPE-START-IDENTIFIER>>(.*?)<<CUSTOM-TYPE-END-IDENTIFIER>>" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we make <CUSTOM-TYPE-START-IDENTIFIER>
a const?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes!
dspy/adapters/types/base_type.py
Outdated
pattern = r"<<CUSTOM-TYPE-START-IDENTIFIER>>(.*?)<<CUSTOM-TYPE-END-IDENTIFIER>>" | ||
result = [] | ||
last_end = 0 | ||
content = message["content"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a fair assumption that content here is always a single string rather than a content part list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With current adapter design, yes, we format user inputs into a string, then split around custom type. Before this PR, we only split around the image tag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, can we add a comment for the context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sg, added!
dspy/adapters/types/image.py
Outdated
def format(self) -> Union[list[dict[str, Any]], str]: | ||
try: | ||
url = self.url | ||
if isinstance(url, str) and "<DSPY_IMAGE_START>" in url and "<DSPY_IMAGE_END>" in url: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should we make <DSPY_IMAGE_START>
and <DSPY_IMAGE_END>
a const?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a condition check for legacy code's compatibility, which we can remove in 1-2 version, so i would prefer not exposing a file-level constant.
tests/adapters/test_chat_adapter.py
Outdated
expected_image_content = {"type": "image_url", "image_url": {"url": "https://example.com/image.jpg"}} | ||
assert expected_image_content in user_message_content | ||
|
||
# Test formatting with few-shot examples |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: shall we parameterize or split the test for clear test cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Splitting sounds good to me
dspy/adapters/types/image.py
Outdated
try: | ||
url = self.url | ||
if isinstance(url, str) and "<DSPY_IMAGE_START>" in url and "<DSPY_IMAGE_END>" in url: | ||
url = url.split("<DSPY_IMAGE_START>", 1)[-1].split("<DSPY_IMAGE_END>", 1)[0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: we can use re.search
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I read the existing dspy.Image's code again, and i think we can safely delete this code chunk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was just checking how DSPY_IMAGE_START
is used after this code change and reached the same conclusion 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Modifying from #8210 by @arnavsinghvi11.
dspy.BaseType
will be the base class for custom types for signature usage, includingdspy.Image
,dspy.Audio
and so on.dspy.History
does not subclass fromdspy.BaseType
because it needs to modify the signature and get formatted as multiturn messages.