Skip trace work when disabled; share the agent span builder

With TRACES_ENABLED off, LLM calls record no GenAI metrics, and a streamed
answer is joined into a preview only when a span keeps it. Agent runs and
continuations build their invoke_agent span in one place, which now reads
the model from model_id. The trace panel shows a stream's model time next
to how long it was open. Adds missing type hints.
This commit is contained in:
arc53-machine committed 2026-09-23 22:09:58 +01:00
1 parent 699906a015
commit 0bbbac0eb2
18 files changed
+88 -35

No files matched your search

+2 -17
View File
@@ -32,7 +32,7 @@ from docsgpt.guardrails.stream import StreamingOutputGuard
from docsgpt.guardrails.types import Action, Stage, resolve_tool_result
from docsgpt.llm.handlers.handler_creator import LLMHandlerCreator
from docsgpt.llm.llm_creator import LLMCreator
from docsgpt.logging import build_stack_data, log_activity, LogContext
from docsgpt.logging import build_stack_data, log_activity, LogContext, start_agent_span
logger = logging.getLogger(__name__)
@@ -504,22 +504,7 @@ class BaseAgent(ABC):
pending_tool_calls: The pending tool call descriptors from the pause.
tool_actions: Client-provided actions resolving the pending calls.
"""
label = type(self).__name__
span = tracing.start_span(
tracing.KIND_AGENT,
f"invoke_agent {label}",
attributes={
k: v
for k, v in {
"gen_ai.operation.name": "invoke_agent",
"gen_ai.agent.id": str(self.agent_id) if getattr(self, "agent_id", None) else None,
"gen_ai.request.model": getattr(self, "model_id", None),
"docsgpt.agent_type": label,
"docsgpt.continuation": True,
}.items()
if v is not None
},
)
span = start_agent_span(self, continuation=True)
completed = False
try:
yield from self._gen_continuation_inner(
+2 -2
View File
@@ -2,7 +2,7 @@ import json
import logging
import os
import time
from typing import Dict, Generator, List, Optional
from typing import Any, Dict, Generator, List, Optional
from docsgpt import tracing
from docsgpt.agents.base import BaseAgent
@@ -53,7 +53,7 @@ SYNTHESIS_PROMPT = _load_prompt("synthesis.txt")
def _phase_span(phase: str, **attributes):
def _phase_span(phase: str, **attributes: Any) -> Any:
"""Open a trace span for one research phase (clarify, plan, a step, synthesis)."""
return tracing.start_span(
tracing.KIND_STEP,
+1 -1
View File
@@ -30,7 +30,7 @@ from docsgpt.storage.db.session import db_readonly, db_session
logger = logging.getLogger(__name__)
def record_tool_span_start(call: Any, **attributes: Any):
def record_tool_span_start(call: Any, **attributes: Any) -> Any:
"""Open an ``execute_tool`` span for ``call`` (no-op without an active trace)."""
llm_name = getattr(call, "name", None) or "unknown"
base = {