|
25 | 25 | from typing import List, Dict, Any, Union |
26 | 26 |
|
27 | 27 |
|
28 | | -# ============================================================================= |
29 | | -# OpenAI -> AgentScope conversion |
30 | | -# ============================================================================= |
31 | | - |
32 | | -def openai_to_agentscope_single(msg: Dict[str, Any]) -> Dict[str, Any]: |
33 | | - """ |
34 | | - Convert a single OpenAI format message to AgentScope format. |
35 | | -
|
36 | | - Args: |
37 | | - msg: Message dict in OpenAI format |
38 | | -
|
39 | | - Returns: |
40 | | - Message dict in AgentScope format |
41 | | - """ |
42 | | - role = msg.get("role", "user") |
43 | | - content = msg.get("content", "") |
44 | | - tool_calls = msg.get("tool_calls", []) |
45 | | - tool_call_id = msg.get("tool_call_id", "") |
46 | | - |
47 | | - if tool_calls: |
48 | | - # Assistant message contains tool_calls -> convert to ToolUseBlock format |
49 | | - content_blocks = [] |
50 | | - # If there's text content, add TextBlock first |
51 | | - if content: |
52 | | - content_blocks.append({"type": "text", "text": content}) |
53 | | - # Convert each tool_call to ToolUseBlock |
54 | | - for tc in tool_calls: |
55 | | - func_info = tc.get("function", {}) if isinstance(tc.get("function"), dict) else {} |
56 | | - tool_use_block = { |
57 | | - "type": "tool_use", |
58 | | - "id": tc.get("id", ""), |
59 | | - "name": func_info.get("name", ""), |
60 | | - "input": func_info.get("arguments", "{}") |
61 | | - } |
62 | | - # Try to parse arguments as dict |
63 | | - if isinstance(tool_use_block["input"], str): |
64 | | - try: |
65 | | - tool_use_block["input"] = json.loads(tool_use_block["input"]) |
66 | | - except: |
67 | | - pass |
68 | | - content_blocks.append(tool_use_block) |
69 | | - return { |
70 | | - "name": "assistant", |
71 | | - "role": "assistant", |
72 | | - "content": content_blocks |
73 | | - } |
74 | | - |
75 | | - elif role == "tool" and tool_call_id: |
76 | | - # Tool return result -> convert to ToolResultBlock format |
77 | | - tool_result_block = { |
78 | | - "type": "tool_result", |
79 | | - "id": tool_call_id, |
80 | | - "output": content |
81 | | - } |
82 | | - return { |
83 | | - "name": "tool", |
84 | | - "role": "user", # tool_result in AgentScope is treated as user message |
85 | | - "content": [tool_result_block] |
86 | | - } |
87 | | - |
88 | | - else: |
89 | | - # Normal message, keep original format |
90 | | - return { |
91 | | - "name": role, |
92 | | - "role": role, |
93 | | - "content": content |
94 | | - } |
95 | | - |
96 | | - |
97 | | -def openai_to_agentscope(messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]: |
98 | | - """ |
99 | | - Convert OpenAI format message list to AgentScope format. |
100 | | -
|
101 | | - Args: |
102 | | - messages: Message list in OpenAI format |
103 | | -
|
104 | | - Returns: |
105 | | - Message list in AgentScope format |
106 | | - """ |
107 | | - return [openai_to_agentscope_single(msg) for msg in messages] |
108 | | - |
109 | | - |
110 | | -def openai_to_agentscope_grouped(timelines: List[List[Dict[str, Any]]]) -> List[List[Dict[str, Any]]]: |
111 | | - """ |
112 | | - Convert timelines (multi-turn conversation steps) from OpenAI format to AgentScope format. |
113 | | -
|
114 | | - Args: |
115 | | - timelines: List of List of dict in OpenAI format |
116 | | -
|
117 | | - Returns: |
118 | | - Trajectory data in AgentScope format |
119 | | - """ |
120 | | - return [[openai_to_agentscope_single(msg) for msg in step] for step in timelines] |
121 | | - |
122 | | - |
123 | | -# ============================================================================= |
124 | | -# AgentScope -> OpenAI conversion |
125 | | -# ============================================================================= |
126 | | - |
127 | | -def agentscope_to_openai_single(msg: Dict[str, Any]) -> Dict[str, Any]: |
128 | | - """ |
129 | | - Convert a single AgentScope format message to OpenAI format. |
130 | | -
|
131 | | - Args: |
132 | | - msg: Message dict in AgentScope format |
133 | | -
|
134 | | - Returns: |
135 | | - Message dict in OpenAI format |
136 | | - """ |
137 | | - role = msg.get("role", "user") |
138 | | - content = msg.get("content", "") |
139 | | - |
140 | | - # If content is string, return directly |
141 | | - if isinstance(content, str): |
142 | | - return { |
143 | | - "role": role, |
144 | | - "content": content |
145 | | - } |
146 | | - |
147 | | - # If content is list (AgentScope block format) |
148 | | - if isinstance(content, list): |
149 | | - text_parts = [] |
150 | | - tool_calls = [] |
151 | | - tool_call_id = "" |
152 | | - tool_output = "" |
153 | | - is_tool_result = False |
154 | | - |
155 | | - for item in content: |
156 | | - if not isinstance(item, dict): |
157 | | - continue |
158 | | - |
159 | | - item_type = item.get("type", "") |
160 | | - |
161 | | - if item_type == "text": |
162 | | - # TextBlock |
163 | | - text_parts.append(item.get("text", "")) |
164 | | - |
165 | | - elif item_type == "tool_use": |
166 | | - # ToolUseBlock -> tool_calls |
167 | | - arguments = item.get("input", {}) |
168 | | - if isinstance(arguments, dict): |
169 | | - arguments = json.dumps(arguments, ensure_ascii=False) |
170 | | - tool_calls.append({ |
171 | | - "id": item.get("id", ""), |
172 | | - "type": "function", |
173 | | - "function": { |
174 | | - "name": item.get("name", ""), |
175 | | - "arguments": arguments |
176 | | - } |
177 | | - }) |
178 | | - |
179 | | - elif item_type == "tool_result": |
180 | | - # ToolResultBlock -> tool response |
181 | | - is_tool_result = True |
182 | | - tool_call_id = item.get("id", "") |
183 | | - output = item.get("output", "") |
184 | | - if isinstance(output, str): |
185 | | - tool_output += output |
186 | | - else: |
187 | | - tool_output += str(output) |
188 | | - |
189 | | - # Build OpenAI format based on parsing result |
190 | | - if is_tool_result and tool_call_id: |
191 | | - return { |
192 | | - "role": "tool", |
193 | | - "content": tool_output, |
194 | | - "tool_call_id": tool_call_id |
195 | | - } |
196 | | - elif tool_calls: |
197 | | - result = { |
198 | | - "role": "assistant", |
199 | | - "content": "".join(text_parts) if text_parts else "", |
200 | | - "tool_calls": tool_calls |
201 | | - } |
202 | | - return result |
203 | | - else: |
204 | | - return { |
205 | | - "role": role, |
206 | | - "content": "".join(text_parts) if text_parts else "" |
207 | | - } |
208 | | - |
209 | | - # Otherwise, return as is |
210 | | - return { |
211 | | - "role": role, |
212 | | - "content": str(content) if content else "" |
213 | | - } |
214 | | - |
215 | | - |
216 | | -def agentscope_to_openai(messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]: |
217 | | - """ |
218 | | - Convert AgentScope format message list to OpenAI format. |
219 | | -
|
220 | | - Args: |
221 | | - messages: Message list in AgentScope format |
222 | | -
|
223 | | - Returns: |
224 | | - Message list in OpenAI format |
225 | | - """ |
226 | | - return [agentscope_to_openai_single(msg) for msg in messages] |
227 | | - |
228 | | - |
229 | | -def agentscope_to_openai_grouped(timelines: List[List[Dict[str, Any]]]) -> List[List[Dict[str, Any]]]: |
230 | | - """ |
231 | | - Convert timelines (multi-turn conversation steps) from AgentScope format to OpenAI format. |
232 | | -
|
233 | | - Args: |
234 | | - timelines: List of List of dict in AgentScope format |
235 | | -
|
236 | | - Returns: |
237 | | - Trajectory data in OpenAI format |
238 | | - """ |
239 | | - return [[agentscope_to_openai_single(msg) for msg in step] for step in timelines] |
240 | | - |
241 | 28 |
|
242 | 29 | # ============================================================================= |
243 | 30 | # ExtendedMessage -> OpenAI conversion (backward compatible functions) |
|
0 commit comments