-
Notifications
You must be signed in to change notification settings - Fork 19k
feat: standard outputs #31967
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
feat: standard outputs #31967
Conversation
libs/partners/openai/tests/integration_tests/chat_models/test_responses_api.py
Show resolved
Hide resolved
return dict(annotation) | ||
|
||
|
||
def _implode_reasoning_blocks(blocks: list[dict[str, Any]]) -> Iterable[dict[str, Any]]: |
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.
Perhaps avoid i
and n
? It's not looking like conventional python code. i
and n
are more typical of c code
i -> idx, n
-> num_blocks
or num_total
or total
Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
for key in ( | ||
"url", | ||
"base64", | ||
"file_id", |
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.
each block has file_id
, should this be removed so that this is a set of only non-required keys? if so we should consider adding title
and context
|
||
|
||
def convert_to_openai_image_block(content_block: dict[str, Any]) -> dict: | ||
"""Convert image content block to format expected by OpenAI Chat Completions API.""" | ||
if content_block["source_type"] == "url": | ||
if "url" in content_block: |
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.
should this also check the input content_block
for type = "image"
?
@@ -117,36 +792,38 @@ def convert_to_openai_data_block(block: dict) -> dict: | |||
formatted_block = convert_to_openai_image_block(block) | |||
|
|||
elif block["type"] == "file": | |||
if block["source_type"] == "base64": | |||
file = {"file_data": f"data:{block['mime_type']};base64,{block['data']}"} | |||
if "base64" in block or block.get("source_type") == "base64": |
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.
same here, check for type in set(DataContentBlock.type)
?
"""The name of the tool to be called.""" | ||
args: dict[str, Any] | ||
"""The arguments to the tool call.""" | ||
id: Optional[str] |
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.
should we be using Optional
or NotRequired
?
|
||
id: str | ||
tool_call_id: str | ||
content: list[dict[str, Any]] |
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.
why isn't this list[types.ContentBlock]
?
if isinstance(content, str): | ||
self.content = [{"type": "text", "text": 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.
for each case where we have self.content = [{"type": "text", "text": content}]
, could we use the approach where we construct the TypedDict and then convert to dict? e.g.:
if isinstance(content, str): | |
self.content = [{"type": "text", "text": content}] | |
if isinstance(content, str): | |
content_typed = TextContentBlock(type="text", text=content) | |
self.content = [content_typed.asdict()] |
if text_blocks: | ||
return "".join(block["text"] for block in text_blocks) | ||
return None | ||
|
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 think a property for reasoning
is missing here, no?
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.
It's present for Chunk
else: | ||
self.content = content | ||
|
||
def text(self) -> str: |
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.
doesn't this need @property
?
else: | ||
self.content = content | ||
|
||
def text(self) -> str: |
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.
same here, @property
?
…rt_to_openai_image_block()`
@@ -293,6 +299,45 @@ def _create_message_from_message_type( | |||
return message | |||
|
|||
|
|||
def _convert_from_v1_message(message: MessageV1) -> BaseMessage: |
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 this still a WIP? the v0 AIMessage will have content
with dicts in the shape of the new content blocks - is there a plan to convert back to the non-std-output (or is that even possible?) don't think so, but wanted to ask for clarity
if isinstance(message.content, str): | ||
content: list[types.ContentBlock] = [] | ||
if message.content: | ||
content = [{"type": "text", "text": 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.
perhaps the same asdict
conversion here?
Co-authored-by: Nuno Campos <nuno@langchain.dev>
No description provided.