and "function_call" in generation.message.additional_kwargs
                    else {}
                ),
            }
            for generation in response.generations[0]
        ]
        event = {
            "event": "end",
            "type": "llm",
            "runId": str(run_id),
            "parent_run_id": str(parent_run_id) if parent_run_id else None,
            "output": parsed_output,
            "tokensUsage": {
                "prompt": token_usage.get("prompt_tokens"),
                "completion": token_usage.get("completion_tokens"),
            },
        }
        self.__send_event(event)
[docs]    def on_tool_start(
        self,
        serialized: Dict[str, Any],
        input_str: str,
        *,
        run_id: UUID,
        parent_run_id: Union[UUID, None] = None,
        tags: Union[List[str], None] = None,
        metadata: Union[Dict[str, Any], None] = None,
        **kwargs: Any,
    ) -> None:
        user_id = _get_user_id(metadata)
        user_props = _get_user_props(metadata)
        event = {
            "event": "start",
            "type": "tool",
            "userId": user_id,
            "runId": str(run_id),
            "parentRunId": str(parent_run_id) if parent_run_id else None,
            "name": serialized.get("name"),
            "input": input_str,
            "tags": tags,
            "metadata": metadata,
        }
        if user_props:
            event["userProps"] = user_props
        self.__send_event(event)
[docs]    def on_tool_end(
        self,
        output: str,
        *,