Skip to content

Commit 13bef9c

Browse files
DeanChensjcopybara-github
authored andcommitted
feat: support user labels in RunConfig
Allow callers to supply custom user labels via RunConfig to propagate billing and attribution labels down to LlmRequest and Vertex API requests. Co-authored-by: Shangjie Chen <deanchen@google.com> PiperOrigin-RevId: 952960713
1 parent 19df9b9 commit 13bef9c

3 files changed

Lines changed: 36 additions & 0 deletions

File tree

src/google/adk/agents/run_config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ class RunConfig(BaseModel):
199199
http_options: Optional[types.HttpOptions] = None
200200
"""HTTP options for the agent execution (e.g. custom headers)."""
201201

202+
labels: Optional[dict[str, str]] = None
203+
"""User labels for the current invocation (e.g. for billing/attribution)."""
204+
202205
response_modalities: Optional[list[types.Modality]] = None
203206
"""The output modalities. If not set, it's default to AUDIO."""
204207

src/google/adk/flows/llm_flows/basic.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ def _build_basic_request(
8181

8282
if run_config_http_options:
8383
_merge_run_config_http_options(llm_request.config, run_config_http_options)
84+
85+
# Merge per-invocation user labels from RunConfig into the request config
86+
# (e.g. for billing, telemetry, and revenue attribution across services).
87+
if invocation_context.run_config and invocation_context.run_config.labels:
88+
if llm_request.config.labels is None:
89+
llm_request.config.labels = {}
90+
llm_request.config.labels.update(invocation_context.run_config.labels)
8491
# Only set output_schema if no tools are specified. as of now, model don't
8592
# support output_schema and tools together. we have a workaround to support
8693
# both output_schema and tools at the same time. see

tests/unittests/flows/llm_flows/test_basic_processor.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,29 @@ async def test_merges_http_options_without_headers(self):
373373
assert (
374374
llm_request.config.http_options.headers['Agent-Header'] == 'agent-val'
375375
)
376+
377+
@pytest.mark.asyncio
378+
async def test_merges_run_config_labels(self):
379+
"""RunConfig labels are merged into llm_request.config.labels."""
380+
agent = LlmAgent(
381+
name='test_agent',
382+
model='gemini-1.5-flash',
383+
generate_content_config=types.GenerateContentConfig(
384+
labels={'agent_label': 'val1'}
385+
),
386+
)
387+
388+
invocation_context = await _create_invocation_context(agent)
389+
invocation_context.run_config = RunConfig(
390+
labels={'goog-originating-logical-product-id': 'prod1'}
391+
)
392+
llm_request = LlmRequest()
393+
394+
processor = _BasicLlmRequestProcessor()
395+
async for _ in processor.run_async(invocation_context, llm_request):
396+
pass
397+
398+
assert llm_request.config.labels == {
399+
'agent_label': 'val1',
400+
'goog-originating-logical-product-id': 'prod1',
401+
}

0 commit comments

Comments
 (0)