Skip to content

Commit df7479b

Browse files
committed
feat(http_options): add dynamic HTTP options support via RunConfig
Enable per-request HTTP configuration (headers, timeout, retry_options) to be passed via RunConfig and propagated through the request pipeline to models.
1 parent 585ebfd commit df7479b

File tree

6 files changed

+206
-51
lines changed

6 files changed

+206
-51
lines changed

src/google/adk/agents/run_config.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,6 @@ class StreamingMode(Enum):
178178
For bidirectional streaming, use runner.run_live() instead of run_async().
179179
"""
180180

181-
182181
class RunConfig(BaseModel):
183182
"""Configs for runtime behavior of agents.
184183
@@ -193,6 +192,9 @@ class RunConfig(BaseModel):
193192
speech_config: Optional[types.SpeechConfig] = None
194193
"""Speech configuration for the live agent."""
195194

195+
http_options: Optional[types.HttpOptions] = None
196+
"""HTTP options for the agent execution (e.g. custom headers)."""
197+
196198
response_modalities: Optional[list[str]] = None
197199
"""The output modalities. If not set, it's default to AUDIO."""
198200

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,22 @@ async def _preprocess_async(
520520
f'Expected agent to be an LlmAgent, but got {type(agent)}'
521521
)
522522

523+
# Propagate http_options from RunConfig to LlmRequest as defaults.
524+
# Request-level settings (from callbacks/processors) take precedence.
525+
if (
526+
invocation_context.run_config
527+
and invocation_context.run_config.http_options
528+
):
529+
run_opts = invocation_context.run_config.http_options
530+
if not llm_request.config.http_options:
531+
# Deep-copy to avoid mutating the user's RunConfig across steps.
532+
llm_request.config.http_options = run_opts.model_copy(deep=True)
533+
elif run_opts.headers:
534+
# Merge headers: request-level headers win (use setdefault).
535+
if not llm_request.config.http_options.headers:
536+
llm_request.config.http_options.headers = {}
537+
for key, value in run_opts.headers.items():
538+
llm_request.config.http_options.headers.setdefault(key, value)
523539
# Runs processors.
524540
for processor in self.request_processors:
525541
async with Aclosing(

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

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from __future__ import annotations
1818

1919
from typing import AsyncGenerator
20-
from typing import Generator
2120

2221
from google.genai import types
2322
from typing_extensions import override
@@ -28,7 +27,6 @@
2827
from ...utils.output_schema_utils import can_use_output_schema_with_tools
2928
from ._base_llm_processor import BaseLlmRequestProcessor
3029

31-
3230
def _build_basic_request(
3331
invocation_context: InvocationContext,
3432
llm_request: LlmRequest,
@@ -45,11 +43,42 @@ def _build_basic_request(
4543
agent = invocation_context.agent
4644
model = agent.canonical_model
4745
llm_request.model = model if isinstance(model, str) else model.model
46+
47+
# Preserve http_options propagated from RunConfig
48+
run_config_http_options = llm_request.config.http_options
49+
4850
llm_request.config = (
4951
agent.generate_content_config.model_copy(deep=True)
5052
if agent.generate_content_config
5153
else types.GenerateContentConfig()
5254
)
55+
56+
if run_config_http_options:
57+
# Merge RunConfig http_options back, overriding agent config
58+
if not llm_request.config.http_options:
59+
llm_request.config.http_options = run_config_http_options
60+
else:
61+
# Merge headers
62+
if run_config_http_options.headers:
63+
if not llm_request.config.http_options.headers:
64+
llm_request.config.http_options.headers = {}
65+
llm_request.config.http_options.headers.update(
66+
run_config_http_options.headers
67+
)
68+
69+
# Merge other http_options fields if present in RunConfig.
70+
# RunConfig values override agent defaults.
71+
# Note: base_url, api_version, base_url_resource_scope are intentionally
72+
# excluded as they are configuration-time settings, not request-time.
73+
for field in [
74+
'timeout',
75+
'retry_options',
76+
'extra_body',
77+
]:
78+
val = getattr(run_config_http_options, field, None)
79+
if val is not None:
80+
setattr(llm_request.config.http_options, field, val)
81+
5382
# Only set output_schema if no tools are specified. as of now, model don't
5483
# support output_schema and tools together. we have a workaround to support
5584
# both output_schema and tools at the same time. see
@@ -100,5 +129,4 @@ async def run_async(
100129
return
101130
yield # Generator requires yield statement in function body.
102131

103-
104132
request_processor = _BasicLlmRequestProcessor()

0 commit comments

Comments
 (0)