Prepare and validate request, return (combined prompt, attachment path list, tool_exec_results).
(
req_id: str,
request: ChatCompletionRequest,
check_client_disconnected: Callable,
fc_state: Optional[FunctionCallingState] = None,
)
| 158 | |
| 159 | |
| 160 | async def _prepare_and_validate_request( |
| 161 | req_id: str, |
| 162 | request: ChatCompletionRequest, |
| 163 | check_client_disconnected: Callable, |
| 164 | fc_state: Optional[FunctionCallingState] = None, |
| 165 | ) -> Tuple[str, List[str], Optional[List[Dict[str, Any]]]]: |
| 166 | """Prepare and validate request, return (combined prompt, attachment path list, tool_exec_results).""" |
| 167 | try: |
| 168 | validate_chat_request(request.messages, req_id) |
| 169 | except ValueError as e: |
| 170 | raise bad_request(req_id, f"Invalid request: {e}") |
| 171 | |
| 172 | prepared_prompt, attachments_list = prepare_combined_prompt( |
| 173 | request.messages, |
| 174 | req_id, |
| 175 | getattr(request, "tools", None), |
| 176 | getattr(request, "tool_choice", None), |
| 177 | fc_state=fc_state, |
| 178 | ) |
| 179 | # Active function execution based on tools/tool_choice (supports per-request MCP endpoints) |
| 180 | try: |
| 181 | # Inject mcp_endpoint into utils.maybe_execute_tools registration logic |
| 182 | if hasattr(request, "mcp_endpoint") and request.mcp_endpoint: |
| 183 | from .tools_registry import register_runtime_tools |
| 184 | |
| 185 | register_runtime_tools( |
| 186 | getattr(request, "tools", None), request.mcp_endpoint |
| 187 | ) |
| 188 | tool_exec_results = await maybe_execute_tools( |
| 189 | request.messages, request.tools, getattr(request, "tool_choice", None) |
| 190 | ) |
| 191 | except asyncio.CancelledError: |
| 192 | raise |
| 193 | except Exception: |
| 194 | tool_exec_results = None |
| 195 | |
| 196 | check_client_disconnected("After Prompt Prep") |
| 197 | # Inline results at the end of the prompt for submission together |
| 198 | if tool_exec_results: |
| 199 | try: |
| 200 | for res in tool_exec_results: |
| 201 | name = res.get("name") |
| 202 | args = res.get("arguments") |
| 203 | result_str = res.get("result") |
| 204 | prepared_prompt += f"\n---\nTool Execution: {name}\nArguments:\n{args}\nResult:\n{result_str}\n" |
| 205 | except Exception: |
| 206 | pass |
| 207 | |
| 208 | # Process and validate attachments |
| 209 | # Acceptance criteria: Only accept data:/file:/absolute paths provided by current request |
| 210 | final_attachments = collect_and_validate_attachments( |
| 211 | request, req_id, attachments_list |
| 212 | ) |
| 213 | |
| 214 | return prepared_prompt, final_attachments, tool_exec_results |
| 215 | |
| 216 | |
| 217 | async def _handle_response_processing( |