You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds a find_spans MCP tool alongside the existing ones: an agent can now ask for spans matching service/name/attribute/duration/error criteria across however many traces in one call, via querysvc.QueryService.FindSpans (the same call get_span_details's identity-filter fast path already uses).
Today that takes search_traces (trace summaries only, no spans) followed by one or more get_span_details calls, or reading whole traces: the two-call detour RFC 0016 §10 describes as the motivation for this RFC.
Design
Input mirrors search_traces's flat, LLM-friendly parameters (service_name, span_name, attributes, with_errors, duration_min/duration_max) rather than exposing the RFC 0005 filter AST to the model directly. The handler translates them into an AND of Eq/Gte/Lte predicates, the same way get_span_details.go's buildIdentityFilter builds a filter from Go.
Unlike search_traces, the time range is required (RFC 0016 §4.5): a span search has no other bound to default it against.
An attribute value from the input map is passed as an untyped AnyValue rather than a StringValue, so it resolves against whatever kind the attribute is actually stored as, not only a literal string (RFC 0005 §5.4).
with_errors reads as the error virtual attribute every backend's filter lowering special-cases (the elasticsearch backend's asErrorTagEquality, and the memory backend's own equivalent), not a stored attribute of that name.
Output reuses types.SpanDetail, already defined for get_span_details, rather than inventing a second span shape.
The memory backend declares SearchCapabilities.SpanSearch and serves the tool. A backend that does not declare it refuses with the existing ErrSpanSearchUnsupported message. There is no fallback path the way get_span_details needs one, since find_spans has no pre-RFC-0016 equivalent to fall back to.
❌ Patch coverage is 98.05825% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.60%. Comparing base (d82a87c) to head (3864880).
An agent that wants spans matching service/name/attribute/duration/error
criteria across however many traces previously had to call search_traces
(trace summaries only, no spans) and then get_span_details per trace, or
read whole traces, the two-call detour RFC 0016 §10 describes. find_spans
answers that in one call via querysvc.QueryService.FindSpans, which
search_traces and get_span_details already use for the trace and
identity-filter paths respectively.
The tool's input mirrors search_traces's flat, LLM-friendly parameters
(service_name, span_name, attributes, with_errors, duration_min/max)
rather than exposing the RFC 0005 filter AST to the model; the handler
translates them into an AND of Eq/Gte/Lte predicates the same way
get_span_details.go's buildIdentityFilter builds one from Go. Unlike
search_traces, the time range is required (RFC 0016 §4.5): a span
search has no other bound to default it against.
An attribute value from the input map is passed as an untyped AnyValue
rather than a StringValue, so "500" matches a numeric or boolean
attribute stored under that key, not only a literal string (RFC 0005
§5.4). with_errors reads as the error virtual attribute every backend's
filter lowering special-cases (e.g. the elasticsearch backend's
asErrorTagEquality, and the memory backend's own equivalent), not a
stored attribute of that name.
No backend on main yet declares SearchCapabilities.SpanSearch (RFC 0016
M3 through M6 are still landing), so the tool refuses cleanly with the
existing ErrSpanSearchUnsupported message until one does; there is no
fallback path the way get_span_details needs one, since find_spans has
no pre-RFC-0016 equivalent to fall back to.
Fixesjaegertracing#9639
Signed-off-by: Om Kulkarni <kulkarniom7057@gmail.com>
…he search limit
A duration_min or duration_max of "0s" is a bound the caller sent, but
buildSearchFilter treated any zero duration as absent, so "0s" as
duration_max returned spans of every duration. The bounds are now nil
when absent, so an explicit zero is applied.
find_spans was capped by MaxSpanDetailsPerRequest, a per-request limit
for get_span_details. It now uses MaxSearchResults, the same cap
search_traces uses, which is what the PR description says it mirrors.
Signed-off-by: Om Kulkarni <kulkarniom7057@gmail.com>
The effective max_results is applied only while flattening the response; the query is sent with a zero page size, so QueryService replaces it with DefaultPageSize (100). A request for one span still makes the backend fetch a full page, and a configured/requested limit above 100 is silently truncated to that first page. Set Pagination.PageSize to the effective positive limit (clamped to the query-service maximum), or follow NextPageToken when a larger result is intended.
with_errors was sent as a typed boolean. The Elasticsearch and OpenSearch
lowering reads a comparison's constant as text and refuses a typed
boolean there, so with_errors=true failed on those backends. The
constant is now untyped, which every span-search lowering reads as text
and parses against the error tag.
Signed-off-by: Om Kulkarni <kulkarniom7057@gmail.com>
The reason will be displayed to describe this comment to others. Learn more.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
This branch has not been deployed
No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a
find_spansMCP tool alongside the existing ones: an agent can now ask for spans matching service/name/attribute/duration/error criteria across however many traces in one call, viaquerysvc.QueryService.FindSpans(the same callget_span_details's identity-filter fast path already uses).Today that takes
search_traces(trace summaries only, no spans) followed by one or moreget_span_detailscalls, or reading whole traces: the two-call detour RFC 0016 §10 describes as the motivation for this RFC.Design
search_traces's flat, LLM-friendly parameters (service_name,span_name,attributes,with_errors,duration_min/duration_max) rather than exposing the RFC 0005 filter AST to the model directly. The handler translates them into anANDofEq/Gte/Ltepredicates, the same wayget_span_details.go'sbuildIdentityFilterbuilds a filter from Go.search_traces, the time range is required (RFC 0016 §4.5): a span search has no other bound to default it against.AnyValuerather than aStringValue, so it resolves against whatever kind the attribute is actually stored as, not only a literal string (RFC 0005 §5.4).with_errorsreads as theerrorvirtual attribute every backend's filter lowering special-cases (the elasticsearch backend'sasErrorTagEquality, and the memory backend's own equivalent), not a stored attribute of that name.types.SpanDetail, already defined forget_span_details, rather than inventing a second span shape.SearchCapabilities.SpanSearchand serves the tool. A backend that does not declare it refuses with the existingErrSpanSearchUnsupportedmessage. There is no fallback path the wayget_span_detailsneeds one, sincefind_spanshas no pre-RFC-0016 equivalent to fall back to.Fixes #9639