feat(runtime): add agent label to librefang_tool_call_total (#6226)#6229
Merged
Conversation
The tool-call counter added in #3495 was labeled only by tool and outcome, so tool failures could not be attributed to the agent that issued them. Add an agent dimension so the counter becomes librefang_tool_call_total{agent, tool, outcome}, mirroring the existing per-agent librefang_cron_fires_total{agent} precedent. record_tool_call_metric now takes the agent id, threaded from session.agent_id (ctx.agent_id_str) at every call site — the serial execute_single_tool_call wrapper and both the serial and concurrent arms of execute_tool_group. The agent id is sanitized and length-capped via the shared sanitize_tool_label helper, identical to the tool label, so a hallucinated or hostile caller id cannot blow up metric cardinality. Tests: existing failure/success metric tests updated for the new signature; new test_record_tool_call_metric_carries_agent_label asserts the counter emits agent/tool/outcome labels and that the agent value is control-char-stripped and capped at 64 chars.
…nd inline comments The five comment blocks added by this PR split sentences across multiple lines, violating the repo's prose-wrapping rule (one sentence = one line in all prose, including doc-comments and inline comments). Unfold each to a single line per sentence; no logic change.
The #6226 change added an `agent` dimension to `librefang_tool_call_total` in record_tool_call_metric, but the metric's describe_counter! help string still read "labeled by tool name and outcome". Operators reading /metrics would not know the agent label exists, and the cron description that cites this counter as its cardinality precedent was now inconsistent. Update the help string to "labeled by agent, tool name, and outcome" to match the emitted labels.
Contributor
Author
|
Adversarial review follow-up: the |
houko
enabled auto-merge (squash)
June 19, 2026 07:28
…gent-label # Conflicts: # crates/librefang-runtime/src/agent_loop/tests/utilities.rs
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.
Summary
librefang_tool_call_total(added in #3495) was labeled only bytoolandoutcome, so tool failures could not be attributed per-agent.This adds an
agentdimension so the counter becomeslibrefang_tool_call_total{agent, tool, outcome}, mirroring the existing per-agentlibrefang_cron_fires_total{agent}precedent already accepted in the codebase.Changes
crates/librefang-runtime/src/agent_loop/tool_call.rsrecord_tool_call_metricnow takes anagent_id: &strfirst argument and emits anagentlabel.sanitize_tool_labelhelper — identical handling to thetoollabel — so a hallucinated or hostile caller id cannot blow up metric cardinality. The helper doc-comment is generalized to cover both dimensions.session.agent_id(ctx.agent_id_str):execute_single_tool_call(Ok + Err paths).execute_tool_groupPhase 1 serial pre-check (Blocked+CircuitBreak).execute_tool_groupPhase 2 concurrent collector (Ok + Err) — the agent id is captured once from the shared&ctxborrow so the concurrent loop needs no re-borrow.crates/librefang-runtime/src/agent_loop/tests/utilities.rsrecord_tool_call_metrictests for the new signature.test_record_tool_call_metric_carries_agent_label(regression for librefang_tool_call_total has no agent dimension — tool failures can't be attributed per-agent #6226): asserts the counter emitsagent/tool/outcomelabels, and that an over-long id containing a control char is control-char-stripped and capped at 64 chars.CHANGELOG.md: entry under## [Unreleased]→### Added.Verification
Run via the repo's Docker dev image (
librefang-rust-dev:latest), scoped tolibrefang-runtime, per CLAUDE.md (no native cargo on host).cargo check -p librefang-runtime --lib— Finished, no errors.cargo clippy -p librefang-runtime --all-targets -- -D warnings— Finished, zero warnings.cargo test -p librefang-runtime --lib record_tool_call_metric— 3 passed; 0 failed:test_record_tool_call_metric_success_outcometest_record_tool_call_metric_failure_outcometest_record_tool_call_metric_carries_agent_labelcargo fmt -p librefang-runtimeapplied.Deferred work: none.
Closes #6226