Repository: pydantic/pydantic-ai
File: pydantic_ai_slim/pydantic_ai/agent/__init__.py (Python)

Code before:
            history_processors=self.history_processors,
            builtin_tools=list(self._builtin_tools),
            tool_manager=tool_manager,
            tracer=tracer,
            get_instructions=get_instructions,
            instrumentation_settings=instrumentation_settings,
        )

        # Apply overrides to the start node if present
        if override_system_prompts := self._override_system_prompts.get():
            system_prompts = override_system_prompts.value
        else:
            system_prompts = self._system_prompts

        if override_instructions := self._override_instructions.get():
            instructions_for_node = override_instructions.value
            instructions_functions_for_node: list[_system_prompt.SystemPromptRunner[AgentDepsT]] = []
        else:
            instructions_for_node = self._instructions
            instructions_functions_for_node = self._instructions_functions

        start_node = _agent_graph.UserPromptNode[AgentDepsT](
            user_prompt=user_prompt,
            deferred_tool_results=deferred_tool_results,
            instructions=instructions_for_node,
            instructions_functions=instructions_functions_for_node,
            system_prompts=system_prompts,
            system_prompt_functions=self._system_prompt_functions,
            system_prompt_dynamic_functions=self._system_prompt_dynamic_functions,
        )

        agent_name = self.name or 'agent'
        run_span = tracer.start_span(
            'agent run',
            attributes={
                'model_name': model_used.model_name if model_used else 'no-model',
                'agent_name': agent_name,
                'logfire.msg': f'{agent_name} run',
            },
        )

        try:
            async with toolset:
                async with graph.iter(
                    start_node,
                    state=state,
                    deps=graph_deps,
                    span=use_span(run_span) if run_span.is_recording() else None,
                    infer_name=False,
                ) as graph_run:
                    agent_run = AgentRun(graph_run)

Review comment (suggestion):
These 2 fields are not actually used anywhere, but I suppose we can't remove them or stop setting them because `UserPromptNode` is public (exposed via `pydantic_ai.agent`) and people may be using them...

Code after:
                'agent_name': agent_name,
                'gen_ai.agent.name': agent_name,
                'logfire.msg': f'{agent_name} run',
            },
        )

        try:
            async with toolset:
                async with graph.iter(
                    start_node,
                    state=state,
                    deps=graph_deps,
                    span=use_span(run_span) if run_span.is_recording() else None,
                    infer_name=False,
                ) as graph_run:
                    agent_run = AgentRun(graph_run)
                    yield agent_run
                    if (final_result := agent_run.result) is not None and run_span.is_recording():
                        if instrumentation_settings and instrumentation_settings.include_content:
                            run_span.set_attribute(
                                'final_result',
                                (
                                    final_result.output
                                    if isinstance(final_result.output, str)
                                    else json.dumps(InstrumentedModel.serialize_any(final_result.output))
                                ),
                            )
        finally:
            try:
                if instrumentation_settings and run_span.is_recording():
                    run_span.set_attributes(self._run_span_end_attributes(state, usage, instrumentation_settings))
            finally:
                run_span.end()

    def _run_span_end_attributes(
        self, state: _agent_graph.GraphAgentState, usage: _usage.RunUsage, settings: InstrumentationSettings
    ):
        literal_instructions, _ = self._get_instructions()

        if settings.version == 1:
            attrs = {
                'all_messages_events': json.dumps(
                    [
                        InstrumentedModel.event_to_dict(e)
                        for e in settings.messages_to_otel_events(state.message_history)
                    ]
                )
            }
        else:
            attrs = {
                'pydantic_ai.all_messages': json.dumps(settings.messages_to_otel_messages(state.message_history)),