Execute a tool handler and send the result back via HandlePendingToolCall RPC.
(
self,
request_id: str,
tool_name: str,
tool_call_id: str,
arguments: Any,
handler: ToolHandler,
traceparent: str | None = None,
tracestate: str | None = None,
)
| 1921 | logger.warning("failed to deserialize session.canvas.closed payload: %s", exc) |
| 1922 | |
| 1923 | async def _execute_tool_and_respond( |
| 1924 | self, |
| 1925 | request_id: str, |
| 1926 | tool_name: str, |
| 1927 | tool_call_id: str, |
| 1928 | arguments: Any, |
| 1929 | handler: ToolHandler, |
| 1930 | traceparent: str | None = None, |
| 1931 | tracestate: str | None = None, |
| 1932 | ) -> None: |
| 1933 | """Execute a tool handler and send the result back via HandlePendingToolCall RPC.""" |
| 1934 | try: |
| 1935 | invocation = ToolInvocation( |
| 1936 | session_id=self.session_id, |
| 1937 | tool_call_id=tool_call_id, |
| 1938 | tool_name=tool_name, |
| 1939 | arguments=arguments, |
| 1940 | ) |
| 1941 | |
| 1942 | with trace_context(traceparent, tracestate): |
| 1943 | handler_start = time.perf_counter() |
| 1944 | result = handler(invocation) |
| 1945 | if inspect.isawaitable(result): |
| 1946 | result = await result |
| 1947 | log_timing( |
| 1948 | logger, |
| 1949 | logging.DEBUG, |
| 1950 | "CopilotSession._execute_tool_and_respond tool dispatch", |
| 1951 | handler_start, |
| 1952 | session_id=self.session_id, |
| 1953 | request_id=request_id, |
| 1954 | tool_call_id=tool_call_id, |
| 1955 | tool_name=tool_name, |
| 1956 | ) |
| 1957 | |
| 1958 | tool_result: ToolResult |
| 1959 | if result is None: |
| 1960 | tool_result = ToolResult( |
| 1961 | text_result_for_llm="Tool returned no result.", |
| 1962 | result_type="failure", |
| 1963 | error="tool returned no result", |
| 1964 | tool_telemetry={}, |
| 1965 | ) |
| 1966 | else: |
| 1967 | tool_result = result # type: ignore[assignment] |
| 1968 | |
| 1969 | # Exception-originated failures (from define_tool's exception handler) are |
| 1970 | # sent via the top-level error param so the CLI formats them with its |
| 1971 | # standard "Failed to execute..." message. Deliberate user-returned |
| 1972 | # failures send the full structured result to preserve metadata. |
| 1973 | if tool_result._from_exception: |
| 1974 | rpc_start = time.perf_counter() |
| 1975 | await self.rpc.tools.handle_pending_tool_call( |
| 1976 | HandlePendingToolCallRequest( |
| 1977 | request_id=request_id, |
| 1978 | error=tool_result.error, |
| 1979 | ) |
| 1980 | ) |
no test coverage detected