-
Notifications
You must be signed in to change notification settings - Fork 0
Add OpenAI Responses API adapter and developer role support #17
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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
adc81c0
a5eb46c
0ba7684
5533112
ae38c03
773a6fb
7307ba9
66b8cb9
a78f5a6
164a993
fe03beb
1892d6f
0960253
74bee68
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ | |
| import logging | ||
| import warnings | ||
| from abc import ABC, abstractmethod | ||
| from dataclasses import asdict, dataclass | ||
| from dataclasses import asdict, dataclass, replace | ||
| from pathlib import Path | ||
| from typing import ( | ||
| Any, | ||
|
|
@@ -172,8 +172,16 @@ def formatted_output_schema(self) -> Any: | |
| return self._formatted_output_schema | ||
|
|
||
| def all_messages(self, new_message: ProviderMessage) -> List[Dict[str, Any]]: | ||
| converted_message = convert_provider_message_to_dict(new_message) | ||
| return self._messages + [converted_message] | ||
| converted = convert_provider_message_to_dict(new_message) | ||
| if not isinstance(converted, list): | ||
| return self._messages + [converted] | ||
| # Responses API: output is a list of typed items. Wrap input | ||
| # messages as OpenAI Responses message items so the full list | ||
| # uses a consistent format for the recording API. | ||
| wrapped: List[Dict[str, Any]] = [ | ||
| {"type": "message", **m} for m in self._messages | ||
| ] | ||
| return wrapped + converted | ||
|
|
||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| class BoundPrompt: | ||
|
|
@@ -236,6 +244,16 @@ def __format_tool_schema(flavor_name: str, tool_schema: List[ToolSchema]) -> Any | |
| return [Tool(function_declarations=function_declarations)] | ||
| except ImportError: | ||
| raise VertexAIToolSchemaError() | ||
| elif flavor_name == "openai_responses": | ||
| return [ | ||
| { | ||
| "type": "function", | ||
| "name": t.name, | ||
| "description": t.description, | ||
| "parameters": t.parameters, | ||
| } | ||
| for t in tool_schema | ||
| ] | ||
| elif flavor_name == "gemini_api_chat": | ||
| function_declarations = [ | ||
| { | ||
|
|
@@ -256,6 +274,9 @@ def __format_output_schema( | |
| # For OpenAI and Azure OpenAI, the normalized format is compatible with the API format | ||
| if flavor_name in ["openai_chat", "azure_openai_chat"]: | ||
| return output_schema | ||
| elif flavor_name == "openai_responses": | ||
| inner = output_schema.get("json_schema", {}) | ||
| return {"format": {"type": "json_schema", **inner}} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a guard for missing When 馃挕 Proposed fix elif flavor_name == "openai_responses":
- inner = output_schema.get("json_schema", {})
+ inner = output_schema.get("json_schema")
+ if not inner:
+ raise FreeplayConfigurationError(
+ "Missing json_schema in output_schema for openai_responses flavor."
+ )
return {"format": {"type": "json_schema", **inner}}馃 Prompt for AI Agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i'm not sure this handling is consistent with the other flavors -- they don't provide the top level json_schema annotation.. It is a bit different than how we handle tools. |
||
| # Add other flavors as necessary - currently only OpenAI-compatible models support output schema | ||
| raise UnsupportedOutputSchema() | ||
|
|
||
|
|
@@ -274,17 +295,23 @@ def format(self, flavor_name: Optional[str] = None) -> FormattedPrompt: | |
| else None | ||
| ) | ||
|
|
||
| effective_prompt_info = ( | ||
| replace(self.prompt_info, flavor_name=final_flavor) | ||
| if final_flavor != self.prompt_info.flavor_name | ||
| else self.prompt_info | ||
| ) | ||
|
|
||
| if isinstance(formatted_prompt, str): | ||
| return FormattedPrompt( | ||
| prompt_info=self.prompt_info, | ||
| prompt_info=effective_prompt_info, | ||
| messages=self.messages, | ||
| formatted_prompt_text=formatted_prompt, | ||
| tool_schema=formatted_tool_schema, | ||
| formatted_output_schema=formatted_output_schema, | ||
| ) | ||
| else: | ||
| return FormattedPrompt( | ||
| prompt_info=self.prompt_info, | ||
| prompt_info=effective_prompt_info, | ||
| messages=self.messages, | ||
| formatted_prompt=formatted_prompt, | ||
| tool_schema=formatted_tool_schema, | ||
|
|
@@ -609,6 +636,7 @@ def __flavor_to_provider(flavor: str) -> str: | |
| "azure_openai_chat": "azure", | ||
| "anthropic_chat": "anthropic", | ||
| "openai_chat": "openai", | ||
| "openai_responses": "openai", | ||
| "gemini_chat": "vertex", | ||
| "gemini_api_chat": "gemini", | ||
| } | ||
|
|
||
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.
The output schema param is really called
text?