-
Notifications
You must be signed in to change notification settings - Fork 3
Fix issue where span creation was not allowing List[Any] #229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This change is primarily to fix an issue where if you try to create a trace span using a List instead of a dictionary or BaseModel it errored out even though the upper function signature specified that List[Any] is allowed. To be able to verify this with built in tests I had to update the requirements * .lock files and then the uv.lock file also got updated. This all resulted in no longer needing or being required to limit the nox session to pydantic 1.x and it was failing because the code wants pydantic 2 so i removed the pydantic 1.x requirement from the nox file.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
| input: dict[str, Any] | list[dict[str, Any]] | BaseModel | None = None, | ||
| data: dict[str, Any] | list[dict[str, Any]] | BaseModel | None = None, | ||
| input: dict[str, Any] | list[Any] | BaseModel | None = None, | ||
| data: dict[str, Any] | list[Any] | BaseModel | None = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this will work because the Span object has this restriction too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change makes the trace input signature match the Span input signature.
I found this because I was trying to do span( input=['a string here']) which is valid for the span signature. but failed when it got down to the trace.
I followed the code down into the dump object function to verify that it could handle a list of Any and then decided to make trace match span instead of span match trace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the context. I traced through the code more carefully and I think there might be some confusion about what the Span signature actually accepts.
Looking at types/span.py, the Span model has:
input: Union[Dict[str, object], List[Dict[str, object]], None] = None
But ['a string here'] is a List[str], not a List[Dict[str, object]], so it technically doesn't match the Span signature either.
More importantly, I tested this and even if the local code accepts it, the SGP API backend rejects it with:
Error code: 422 - {'detail': [{'type': 'dict_type', 'loc': ['body', 'items', 0, 'input'], 'msg': 'Input should be a valid
dictionary', 'input': [...]}]}
This happens in sgp_tracing_processor.py when it calls spans.upsert_batch().
Can you confirm you were able to successfully create a span with input=['a string here'] end-to-end? Or did it fail at the API level?
| name=name, | ||
| parent_id=parent_id, | ||
| start_time=start_time, | ||
| input=serialized_input, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the type here is : data: Union[Dict[str, object], List[Dict[str, object]], None] = None
"""Any additional metadata or context for the span"""
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the source code for tracing.py:
`@asynccontextmanager
async def span(
self,
trace_id: str,
name: str,
input: list[Any] | dict[str, Any] | BaseModel | None = None,
data: list[Any] | dict[str, Any] | BaseModel | None = None,
parent_id: str | None = None,
start_to_close_timeout: timedelta = timedelta(seconds=5),
heartbeat_timeout: timedelta = timedelta(seconds=5),
retry_policy: RetryPolicy = DEFAULT_RETRY_POLICY,
) -> AsyncGenerator[Span | None, None]:
"""
Async context manager for creating and automatically closing a span.
Yields the started span object. The span is automatically ended when the context exits.
If trace_id is falsy, acts as a no-op context manager.
Args:
trace_id (str): The trace ID for the span.
name (str): The name of the span.
input (Union[List, Dict, BaseModel]): The input for the span.
parent_id (Optional[str]): The parent span ID for the span.
data (Optional[Union[List, Dict, BaseModel]]): The data for the span.
start_to_close_timeout (timedelta): The start to close timeout for the span.
heartbeat_timeout (timedelta): The heartbeat timeout for the span.
retry_policy (RetryPolicy): The retry policy for the span.
Returns:
AsyncGenerator[Optional[Span], None]: An async generator that yields the started span object.
"""`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see - you're pointing to TracingModule.span() in adk/_modules/tracing.py, which does accept list[Any]. So the mismatch you found is:
TracingModule.span() → list[Any] ✅ (adk/_modules/tracing.py)
↓
AsyncTrace.span() → list[dict[str, Any]] ❌ (core/tracing/trace.py - your fix)
↓
Span model → List[Dict[str, object]] (types/span.py)
↓
SGP API → Dict only
Your fix aligns trace.py with the upper TracingModule layer - that part makes sense.
The issue is the chain continues downward. Even with your fix, passing ['a string'] will still hit restrictions at:
- The Span model (List[Dict[str, object]], not List[Any])
- The SGP API (rejects non-dict values for input)
Did you test this end-to-end with input=['a string']? I'm getting a 422 from the API when the span is sent to the backend via sgp_tracing_processor.
If the goal is to support list[Any] fully, we'd need the API team to update the backend as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with ether way, just need the documentation, and signatures of actually used code to match.
I have not been able to get my local adk package to integrate with the agentex platform as signatures don't match what is expected. So i have not been able to do end-to-end testing. I would appreciate guidance on that if possible so I can better test changes in the future.
potentially a better solution would be to change the top level tracing so it is an honest type check |
…not allowing List[Any] This flips the fix on it's head and instead of allowing List[Any] goes the other way and requires that a list be a List[Dict[str, Any]] which is what the deeper SPAN object actually wants. I noticed that the `data` parameter suffers the same lack of type consistency that the `input` parameter had where the SPAN object actually specifies only dicts and lists of dicts are accepted, but upper level functions allow list[Any] so I normalized those as well.
|
I reversed the fix so that it goes the other way: requires List[Dict[str, Any]] all the way up the chain. Also noticed that the same inconsistency exists for the |
This change is primarily to fix an issue where if you try to create a trace span using a List instead of a dictionary or BaseModel it errored out even though the upper function signature specified that List[Any] is allowed.
To be able to verify this with built in tests I had to update the requirements * .lock files and then the uv.lock file also got updated.
This all resulted in no longer needing or being required to limit the nox session to pydantic 1.x and it was failing because the code wants pydantic 2 so i removed the pydantic 1.x requirement from the nox file.