Commit e4e56f9
feat: LE-374 token usage tracking for LLM and Agent components (#11891)
* feat: add token usage tracking for LLM and Agent components
Track input/output/total tokens across LLM providers (OpenAI, Anthropic,
Ollama) and display them on both node badges and chat messages.
Backend: thread-safe callback handler for agent token accumulation,
usage_metadata extraction for Ollama/LangChain standard, pipeline
integration from component through vertex to API response.
Frontend: token count formatting utility, Coins icon badge on nodes
with tooltip breakdown, chat message status with token display.
* feat: accumulate token usage across serial LLMs on chat messages
Add upstream token usage accumulation so chat messages display the
total tokens from all LLMs in the pipeline, not just the last one.
Output vertex node badges hide token counts since the accumulated
total is shown on the chat message instead.
* chore: add CLAUDE.local.md to .gitignore
* chore: update starter project templates for token usage tracking
* fix: enable token usage tracking for streaming LLM responses
Enable stream_usage=True on OpenAI and Anthropic model constructors so
the API includes token counts in streaming chunks.
Fix _handle_stream to propagate the AIMessage back to _get_chat_result
when not connected to a chat output, so usage can be extracted from the
invoke fallback path.
Accumulate usage across multiple streaming chunks instead of overwriting,
since Anthropic splits input/output tokens across separate events.
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
* refactor: centralize token usage extraction into shared module
Extract duplicated token usage logic from Component, LCModelComponent,
TokenUsageCallbackHandler, and Vertex into a shared lfx.schema.token_usage
module. Replace loose dict typing with the existing Usage Pydantic model
throughout the token tracking pipeline. Declare _token_usage on Component
__init__ instead of dynamically injecting it.
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
* [autofix.ci] apply automated fixes
* feat: add validation for token_usage field in ResultDataResponse
* feat: enable stream_usage in OpenAI model tests
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes
* refactor: consolidate token usage extraction into single source of truth
Eliminate ~75 lines of duplicated LLMResult token extraction logic between
the token usage feature (TokenUsageCallbackHandler) and the traces feature
(NativeCallbackHandler) by adding a shared extract_usage_from_llm_result()
function. Also fix missing usage property mapping in chat history hook so
token counts display correctly in playground messages.
* feat: add token usage tracking to all LLM components
Add token usage extraction to the 7 remaining components that make LLM
calls but weren't tracking token consumption:
- Smart Router: direct extract_usage_from_message after invoke
- Guardrails: accumulate_usage across multiple guardrail checks
- Batch Run: accumulate_usage across batch responses
- Smart Transform: extract after ainvoke (already done in prior commit)
- Structured Output: via token_usage_callback on get_chat_result
- LLM Selector: direct extract for judge + callback for selected model
- NotDiamond: via token_usage_callback on get_chat_result
Also adds a backward-compatible token_usage_callback parameter to
get_chat_result() so components using that shared helper can capture
the AIMessage before it's reduced to .content.
* [autofix.ci] apply automated fixes
* fix: update mock_get_chat_result signatures to accept token_usage_callback
The structured output test mocks define explicit parameter lists for
get_chat_result but were missing the new token_usage_callback kwarg,
causing CI failure. Add **kwargs to all mock definitions.
* fix: address PR review findings for token usage UI and data flow
- Remove bare "bg" Tailwind class and replace hard-coded bg-neutral-700
with semantic bg-success-background on success tooltip (C2/C3)
- Propagate usage properties regardless of source.id presence so agent
inner messages still show token counts (H9)
- Make PropertiesType.source optional to match the new data flow
- Restore "in" preposition in "Finished in X.Xs" chat message (M10)
- Fix misleading "optional dependency" comment in native_callback.py (C1)
* fix: structured output token usage not captured due to config key mismatch
get_chat_result() reads "get_langchain_callbacks" as a callable, but
structured output was passing "callbacks" as a list — the token handler
was silently dropped. Fix by matching the expected key names and
injecting TokenUsageCallbackHandler via the LangChain callback chain
instead of the token_usage_callback parameter (which doesn't fire for
structured output chains that return Pydantic models, not AIMessages).
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
* chore: update component index
* test: add E2E tests for token usage tracking
* [autofix.ci] apply automated fixes
* test: add missing unit tests from PR review
Adds the 4 recommended test scenarios identified in Cristhianzl's review
of PR #11891 (token usage tracking):
- TestStreamingTokenAccumulation: verifies extract_usage_from_chunk() +
accumulate_usage() correctly accumulates across multiple streaming chunks
(OpenAI, Anthropic, and usage_metadata formats)
- TestChatOutputTokenUsageAccumulation: verifies message_response() sets
upstream token usage on the message and updates the stored message when
applicable
- TestAgentTokenCallbackWiring: verifies TokenUsageCallbackHandler is wired
into run_agent() callbacks and its result is stored on _token_usage
- TestResultDataResponseTokenUsageValidator: verifies the field_validator
converts Usage Pydantic models to dicts and passes through None/dict values
* [autofix.ci] apply automated fixes
* Revert "[autofix.ci] apply automated fixes"
This reverts commit c618b12.
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes
* fix: move hover action bar above message to prevent overlap with header row
Position the EditMessageButton toolbar using \`bottom-full\` instead of \`-top-4\` so it always sits fully above the message container. This prevents the button bar from overlapping the 'Finished in' usage/time row in bot messages.
* [autofix.ci] apply automated fixes
* feat: add token usage tooltip to bot message and fix node status background
- Wrap "Finished in" stat in a ShadTooltip showing last run time, duration, input/output token breakdown
- Fix node status success background color from bg-success-background to bg-zinc-700
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>1 parent 511d500 commit e4e56f9
3 files changed
Lines changed: 65 additions & 10 deletions
File tree
- src/frontend/src/components/core/playgroundComponent/chat-view/chat-messages/components
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
292 | 292 | | |
293 | 293 | | |
294 | 294 | | |
295 | | - | |
| 295 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
502 | 502 | | |
503 | 503 | | |
504 | 504 | | |
505 | | - | |
| 505 | + | |
506 | 506 | | |
507 | 507 | | |
508 | 508 | | |
| |||
2926 | 2926 | | |
2927 | 2927 | | |
2928 | 2928 | | |
| 2929 | + | |
| 2930 | + | |
| 2931 | + | |
| 2932 | + | |
| 2933 | + | |
| 2934 | + | |
| 2935 | + | |
| 2936 | + | |
| 2937 | + | |
2929 | 2938 | | |
2930 | 2939 | | |
2931 | 2940 | | |
| |||
3341 | 3350 | | |
3342 | 3351 | | |
3343 | 3352 | | |
| 3353 | + | |
| 3354 | + | |
| 3355 | + | |
| 3356 | + | |
| 3357 | + | |
| 3358 | + | |
| 3359 | + | |
| 3360 | + | |
| 3361 | + | |
3344 | 3362 | | |
3345 | 3363 | | |
3346 | 3364 | | |
| |||
3471 | 3489 | | |
3472 | 3490 | | |
3473 | 3491 | | |
3474 | | - | |
| 3492 | + | |
3475 | 3493 | | |
3476 | 3494 | | |
3477 | 3495 | | |
| |||
3525 | 3543 | | |
3526 | 3544 | | |
3527 | 3545 | | |
3528 | | - | |
| 3546 | + | |
3529 | 3547 | | |
3530 | 3548 | | |
3531 | 3549 | | |
3532 | 3550 | | |
3533 | 3551 | | |
3534 | 3552 | | |
3535 | 3553 | | |
3536 | | - | |
| 3554 | + | |
3537 | 3555 | | |
3538 | 3556 | | |
3539 | 3557 | | |
3540 | 3558 | | |
3541 | 3559 | | |
3542 | 3560 | | |
3543 | 3561 | | |
3544 | | - | |
| 3562 | + | |
3545 | 3563 | | |
3546 | 3564 | | |
3547 | 3565 | | |
| |||
3655 | 3673 | | |
3656 | 3674 | | |
3657 | 3675 | | |
3658 | | - | |
| 3676 | + | |
3659 | 3677 | | |
3660 | 3678 | | |
3661 | 3679 | | |
| |||
8238 | 8256 | | |
8239 | 8257 | | |
8240 | 8258 | | |
8241 | | - | |
| 8259 | + | |
8242 | 8260 | | |
8243 | 8261 | | |
8244 | 8262 | | |
8245 | 8263 | | |
8246 | 8264 | | |
8247 | 8265 | | |
8248 | 8266 | | |
8249 | | - | |
| 8267 | + | |
8250 | 8268 | | |
8251 | 8269 | | |
8252 | 8270 | | |
8253 | 8271 | | |
8254 | 8272 | | |
8255 | 8273 | | |
8256 | 8274 | | |
8257 | | - | |
| 8275 | + | |
8258 | 8276 | | |
8259 | 8277 | | |
8260 | 8278 | | |
| |||
Lines changed: 37 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
126 | 127 | | |
127 | 128 | | |
128 | 129 | | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
129 | 166 | | |
130 | 167 | | |
131 | 168 | | |
| |||
0 commit comments