feat(Tracing): add agent (invoke_agent) and tool (execute_tool) spans#1
Closed
cdaguerre wants to merge 6 commits into
Closed
Conversation
Extends the AI platform tracing with the two higher levels of the Symfony AI stack, following the OTel gen_ai semantic conventions: - TracingAgent decorates ai.agent services, emitting an INTERNAL `invoke_agent` span (gen_ai.agent.name) that parents the platform's CLIENT `chat` spans. - TracingToolbox decorates ai.toolbox services, emitting an INTERNAL `execute_tool` span (gen_ai.tool.name, gen_ai.tool.call.id) per call. Both are wired via AIAgentTracingCompilerPass, mirroring the platform pass: abstract services in config/tracing/ai.php, decoration keyed on the ai.agent / ai.toolbox tags at priority -512 (outermost). Attribute names and values use OpenTelemetry\SemConv constants. symfony/ai-agent added as a dev/suggested optional dependency. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…roviders for AI agent/tool Aligns the agent/tool tracing decorators with the bundle's conventions: - Inject TracerProviderInterface (via TracerAwareTrait) instead of the static Tracing facade. The static accessor is intended for application code outside the bundle; in-bundle services use constructor injection. - Extract the inline gen_ai.* attributes into AgentAttributeProvider / ToolAttributeProvider behind interfaces registered in semconv.php, so consumers can override them (matching the other instrumentations). Attribute names/values use OpenTelemetry\SemConv constants. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…form calls Adds an opt-in (metrics.ai.enabled) MeteringPlatform decorator that records the OTel gen_ai semconv histogram gen_ai.client.token.usage, split by gen_ai.token.type (input/output) with gen_ai.system / gen_ai.request.model / gen_ai.operation.name attributes. Mirrors the tracing platform wiring: an abstract service in config/metrics/ai.php decorated onto ai.platform tagged services by AIPlatformMetricsCompilerPass. Metrics and tracing stay independent (separate toggle, separate decorator), each wrapping the result converter to read token usage; they compose when both are enabled. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Inject TracerProviderInterface (via TracerAwareTrait) into TracingPlatform instead of the static Tracing facade. - Extract span attributes into a swappable PlatformAttributeProvider behind an interface registered in semconv.php, consistent with the agent/tool/request/ doctrine providers. - Use OpenTelemetry\SemConv constants for the gen_ai.* attribute names (including the token usage attributes in TracingTokenUsageExtractor). - Drop the nullable from TracingResultConverter::getTokenUsageExtractor(): it always returns a wrapper, so the previous ?type tripped PHPStan. Also resolves the pre-existing PHPStan (return.unusedType) and cs-fixer failures on the base branch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e resolvers for AI - TracingResultConverter gets a __destruct backstop that ends the platform span if the deferred result is never consumed (Span::end is idempotent, so it is a no-op on the normal path). Mirrors HttpClient's TracedResponse and addresses the original review's span-leak concern. - Span naming moves out of the decorators into swappable Platform/Agent/Tool OperationNameResolver services (registered in semconv.php), matching the request/command/message/httpclient resolvers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…AI platform calls Adds the second OTel gen_ai client metric (semconv): operation duration in seconds, measured from platform invoke() to result conversion, with error.type set when the call fails. Token usage and duration recording are centralised in a shared AiMetricRecorder used across the metering decorator chain. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author
|
Superseded by worldia#89, which targets master directly (full AI instrumentation: platform + agent + tool + metrics) so CI runs without cross-repo approval. |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Targets worldia#86 (
feat/instrumentation_ia), building on its platform-level tracing.What
Adds the two higher levels of the Symfony AI stack to the OTel instrumentation, so a single agent run produces a complete trace tree:
TracingAgentdecoratesai.agent-tagged services and wrapsAgentInterface::call()in aninvoke_agentspan (gen_ai.operation.name=invoke_agent,gen_ai.agent.name).INTERNALkind — the agent orchestrates in-process and parents the platform'sCLIENTchatspans.TracingToolboxdecoratesai.toolbox-tagged services and wrapsToolboxInterface::execute()in anexecute_toolspan (gen_ai.operation.name=execute_tool,gen_ai.tool.name,gen_ai.tool.call.id).AIAgentTracingCompilerPassmirrorsAIPlatformTracingCompilerPass: abstract services inconfig/tracing/ai.php, decoration keyed on theai.agent/ai.toolboxtags at priority-512(outermost, so the span covers inner decorators including the profiler's traceable wrappers at-1024).Gated by the existing
tracing.ai.enabledtoggle — no new config node.symfony/ai-agentadded as arequire-dev/suggestoptional dependency, consistent with howsymfony/ai-platformis declared.Conventions / notes
OpenTelemetry\SemConv\TraceAttributes, values useTraceAttributeValues(theinvoke_agent/execute_tooloperation values live there). Worth aligning the existingTracingPlatformonto these constants too (it currently uses string literals) in a follow-up.finallyand record exceptions — synchronous calls, no deferred-result lifecycle to manage here (unlike the platform'sDeferredResult).gen_ai.*attributes into swappableAttributeProviders to match the rest of the bundle, and the token-usage metrics histogram discussed on feat(Tracing): add token usage for AI worldia/instrumentation-bundle#86.Tests
19 AI tracing tests pass (
tests/Tracing/AI/), including newTracingAgentTestandTracingToolboxTest(span name/kind, gen_ai attributes, OK status, exception recording, delegation). Full suite green; new files clean under PHPStan.🤖 Generated with Claude Code