google-adk 1.6.1__py3-none-any.whl → 1.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. google/adk/a2a/converters/event_converter.py +5 -85
  2. google/adk/a2a/converters/request_converter.py +1 -2
  3. google/adk/a2a/executor/a2a_agent_executor.py +45 -16
  4. google/adk/a2a/logs/log_utils.py +1 -2
  5. google/adk/a2a/utils/__init__.py +0 -0
  6. google/adk/a2a/utils/agent_card_builder.py +544 -0
  7. google/adk/a2a/utils/agent_to_a2a.py +118 -0
  8. google/adk/agents/__init__.py +5 -0
  9. google/adk/agents/agent_config.py +46 -0
  10. google/adk/agents/base_agent.py +239 -41
  11. google/adk/agents/callback_context.py +41 -0
  12. google/adk/agents/common_configs.py +79 -0
  13. google/adk/agents/config_agent_utils.py +184 -0
  14. google/adk/agents/config_schemas/AgentConfig.json +566 -0
  15. google/adk/agents/invocation_context.py +5 -1
  16. google/adk/agents/live_request_queue.py +15 -0
  17. google/adk/agents/llm_agent.py +201 -9
  18. google/adk/agents/loop_agent.py +35 -1
  19. google/adk/agents/parallel_agent.py +24 -3
  20. google/adk/agents/remote_a2a_agent.py +17 -5
  21. google/adk/agents/sequential_agent.py +22 -1
  22. google/adk/artifacts/gcs_artifact_service.py +110 -20
  23. google/adk/auth/auth_handler.py +3 -3
  24. google/adk/auth/credential_manager.py +23 -23
  25. google/adk/auth/credential_service/base_credential_service.py +6 -6
  26. google/adk/auth/credential_service/in_memory_credential_service.py +10 -8
  27. google/adk/auth/credential_service/session_state_credential_service.py +8 -8
  28. google/adk/auth/exchanger/oauth2_credential_exchanger.py +3 -3
  29. google/adk/auth/oauth2_credential_util.py +2 -2
  30. google/adk/auth/refresher/oauth2_credential_refresher.py +4 -4
  31. google/adk/cli/agent_graph.py +3 -1
  32. google/adk/cli/browser/index.html +2 -2
  33. google/adk/cli/browser/main-W7QZBYAR.js +3914 -0
  34. google/adk/cli/browser/polyfills-B6TNHZQ6.js +17 -0
  35. google/adk/cli/cli_eval.py +87 -12
  36. google/adk/cli/cli_tools_click.py +143 -82
  37. google/adk/cli/fast_api.py +150 -69
  38. google/adk/cli/utils/agent_loader.py +35 -1
  39. google/adk/code_executors/base_code_executor.py +14 -19
  40. google/adk/code_executors/built_in_code_executor.py +4 -1
  41. google/adk/evaluation/base_eval_service.py +46 -2
  42. google/adk/evaluation/eval_metrics.py +4 -0
  43. google/adk/evaluation/eval_sets_manager.py +5 -1
  44. google/adk/evaluation/evaluation_generator.py +1 -1
  45. google/adk/evaluation/final_response_match_v2.py +2 -2
  46. google/adk/evaluation/gcs_eval_sets_manager.py +2 -1
  47. google/adk/evaluation/in_memory_eval_sets_manager.py +151 -0
  48. google/adk/evaluation/local_eval_service.py +389 -0
  49. google/adk/evaluation/local_eval_set_results_manager.py +2 -2
  50. google/adk/evaluation/local_eval_sets_manager.py +24 -9
  51. google/adk/evaluation/metric_evaluator_registry.py +16 -6
  52. google/adk/evaluation/vertex_ai_eval_facade.py +7 -1
  53. google/adk/events/event.py +7 -2
  54. google/adk/flows/llm_flows/auto_flow.py +6 -11
  55. google/adk/flows/llm_flows/base_llm_flow.py +66 -29
  56. google/adk/flows/llm_flows/contents.py +16 -10
  57. google/adk/flows/llm_flows/functions.py +89 -52
  58. google/adk/memory/in_memory_memory_service.py +21 -15
  59. google/adk/memory/vertex_ai_memory_bank_service.py +12 -10
  60. google/adk/models/anthropic_llm.py +46 -6
  61. google/adk/models/base_llm_connection.py +2 -0
  62. google/adk/models/gemini_llm_connection.py +17 -6
  63. google/adk/models/google_llm.py +46 -11
  64. google/adk/models/lite_llm.py +52 -22
  65. google/adk/plugins/__init__.py +17 -0
  66. google/adk/plugins/base_plugin.py +317 -0
  67. google/adk/plugins/plugin_manager.py +265 -0
  68. google/adk/runners.py +122 -18
  69. google/adk/sessions/database_session_service.py +51 -52
  70. google/adk/sessions/vertex_ai_session_service.py +27 -12
  71. google/adk/tools/__init__.py +2 -0
  72. google/adk/tools/_automatic_function_calling_util.py +20 -2
  73. google/adk/tools/agent_tool.py +15 -3
  74. google/adk/tools/apihub_tool/apihub_toolset.py +38 -39
  75. google/adk/tools/application_integration_tool/application_integration_toolset.py +35 -37
  76. google/adk/tools/application_integration_tool/integration_connector_tool.py +2 -3
  77. google/adk/tools/base_tool.py +9 -9
  78. google/adk/tools/base_toolset.py +29 -5
  79. google/adk/tools/bigquery/__init__.py +3 -3
  80. google/adk/tools/bigquery/metadata_tool.py +2 -0
  81. google/adk/tools/bigquery/query_tool.py +15 -1
  82. google/adk/tools/computer_use/__init__.py +13 -0
  83. google/adk/tools/computer_use/base_computer.py +265 -0
  84. google/adk/tools/computer_use/computer_use_tool.py +166 -0
  85. google/adk/tools/computer_use/computer_use_toolset.py +220 -0
  86. google/adk/tools/enterprise_search_tool.py +4 -2
  87. google/adk/tools/exit_loop_tool.py +1 -0
  88. google/adk/tools/google_api_tool/google_api_tool.py +16 -1
  89. google/adk/tools/google_api_tool/google_api_toolset.py +9 -7
  90. google/adk/tools/google_api_tool/google_api_toolsets.py +41 -20
  91. google/adk/tools/google_search_tool.py +4 -2
  92. google/adk/tools/langchain_tool.py +16 -6
  93. google/adk/tools/long_running_tool.py +21 -0
  94. google/adk/tools/mcp_tool/mcp_toolset.py +27 -28
  95. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py +5 -0
  96. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +8 -8
  97. google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +4 -6
  98. google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +3 -2
  99. google/adk/tools/tool_context.py +0 -10
  100. google/adk/tools/url_context_tool.py +4 -2
  101. google/adk/tools/vertex_ai_search_tool.py +4 -2
  102. google/adk/utils/model_name_utils.py +90 -0
  103. google/adk/version.py +1 -1
  104. {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/METADATA +3 -2
  105. {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/RECORD +108 -91
  106. google/adk/cli/browser/main-RXDVX3K6.js +0 -3914
  107. google/adk/cli/browser/polyfills-FFHMD2TL.js +0 -17
  108. {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/WHEEL +0 -0
  109. {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/entry_points.txt +0 -0
  110. {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,46 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import Union
18
+
19
+ from pydantic import RootModel
20
+
21
+ from ..utils.feature_decorator import working_in_progress
22
+ from .llm_agent import LlmAgentConfig
23
+ from .loop_agent import LoopAgentConfig
24
+ from .parallel_agent import ParallelAgentConfig
25
+ from .sequential_agent import SequentialAgentConfig
26
+
27
+ # A discriminated union of all possible agent configurations.
28
+ ConfigsUnion = Union[
29
+ LlmAgentConfig,
30
+ LoopAgentConfig,
31
+ ParallelAgentConfig,
32
+ SequentialAgentConfig,
33
+ ]
34
+
35
+
36
+ # Use a RootModel to represent the agent directly at the top level.
37
+ # The `discriminator` is applied to the union within the RootModel.
38
+ @working_in_progress("AgentConfig is not ready for use.")
39
+ class AgentConfig(RootModel[ConfigsUnion]):
40
+ """The config for the YAML schema to create an agent."""
41
+
42
+ class Config:
43
+ # Pydantic v2 requires this for discriminated unions on RootModel
44
+ # This tells the model to look at the 'agent_class' field of the input
45
+ # data to decide which model from the `ConfigsUnion` to use.
46
+ discriminator = "agent_class"
@@ -19,24 +19,32 @@ from typing import Any
19
19
  from typing import AsyncGenerator
20
20
  from typing import Awaitable
21
21
  from typing import Callable
22
+ from typing import Dict
22
23
  from typing import final
24
+ from typing import List
25
+ from typing import Literal
23
26
  from typing import Mapping
24
27
  from typing import Optional
28
+ from typing import Type
25
29
  from typing import TYPE_CHECKING
26
30
  from typing import TypeVar
27
31
  from typing import Union
28
32
 
29
33
  from google.genai import types
30
34
  from opentelemetry import trace
35
+ from pydantic import alias_generators
31
36
  from pydantic import BaseModel
32
37
  from pydantic import ConfigDict
33
38
  from pydantic import Field
34
39
  from pydantic import field_validator
40
+ from pydantic import model_validator
35
41
  from typing_extensions import override
36
42
  from typing_extensions import TypeAlias
37
43
 
38
44
  from ..events.event import Event
45
+ from ..utils.feature_decorator import working_in_progress
39
46
  from .callback_context import CallbackContext
47
+ from .common_configs import CodeConfig
40
48
 
41
49
  if TYPE_CHECKING:
42
50
  from .invocation_context import InvocationContext
@@ -223,11 +231,18 @@ class BaseAgent(BaseModel):
223
231
  """
224
232
  with tracer.start_as_current_span(f'agent_run [{self.name}]'):
225
233
  ctx = self._create_invocation_context(parent_context)
226
- # TODO(hangfei): support before/after_agent_callback
234
+
235
+ if event := await self.__handle_before_agent_callback(ctx):
236
+ yield event
237
+ if ctx.end_invocation:
238
+ return
227
239
 
228
240
  async for event in self._run_live_impl(ctx):
229
241
  yield event
230
242
 
243
+ if event := await self.__handle_after_agent_callback(ctx):
244
+ yield event
245
+
231
246
  async def _run_async_impl(
232
247
  self, ctx: InvocationContext
233
248
  ) -> AsyncGenerator[Event, None]:
@@ -331,73 +346,99 @@ class BaseAgent(BaseModel):
331
346
  ) -> Optional[Event]:
332
347
  """Runs the before_agent_callback if it exists.
333
348
 
349
+ Args:
350
+ ctx: InvocationContext, the invocation context for this agent.
351
+
334
352
  Returns:
335
353
  Optional[Event]: an event if callback provides content or changed state.
336
354
  """
337
- ret_event = None
338
-
339
- if not self.canonical_before_agent_callbacks:
340
- return ret_event
341
-
342
355
  callback_context = CallbackContext(ctx)
343
356
 
344
- for callback in self.canonical_before_agent_callbacks:
345
- before_agent_callback_content = callback(
346
- callback_context=callback_context
347
- )
348
- if inspect.isawaitable(before_agent_callback_content):
349
- before_agent_callback_content = await before_agent_callback_content
350
- if before_agent_callback_content:
351
- ret_event = Event(
352
- invocation_id=ctx.invocation_id,
353
- author=self.name,
354
- branch=ctx.branch,
355
- content=before_agent_callback_content,
356
- actions=callback_context._event_actions,
357
+ # Run callbacks from the plugins.
358
+ before_agent_callback_content = (
359
+ await ctx.plugin_manager.run_before_agent_callback(
360
+ agent=self, callback_context=callback_context
357
361
  )
358
- ctx.end_invocation = True
359
- return ret_event
362
+ )
360
363
 
361
- if callback_context.state.has_delta():
364
+ # If no overrides are provided from the plugins, further run the canonical
365
+ # callbacks.
366
+ if (
367
+ not before_agent_callback_content
368
+ and self.canonical_before_agent_callbacks
369
+ ):
370
+ for callback in self.canonical_before_agent_callbacks:
371
+ before_agent_callback_content = callback(
372
+ callback_context=callback_context
373
+ )
374
+ if inspect.isawaitable(before_agent_callback_content):
375
+ before_agent_callback_content = await before_agent_callback_content
376
+ if before_agent_callback_content:
377
+ break
378
+
379
+ # Process the override content if exists, and further process the state
380
+ # change if exists.
381
+ if before_agent_callback_content:
362
382
  ret_event = Event(
383
+ invocation_id=ctx.invocation_id,
384
+ author=self.name,
385
+ branch=ctx.branch,
386
+ content=before_agent_callback_content,
387
+ actions=callback_context._event_actions,
388
+ )
389
+ ctx.end_invocation = True
390
+ return ret_event
391
+
392
+ if callback_context.state.has_delta():
393
+ return Event(
363
394
  invocation_id=ctx.invocation_id,
364
395
  author=self.name,
365
396
  branch=ctx.branch,
366
397
  actions=callback_context._event_actions,
367
398
  )
368
399
 
369
- return ret_event
400
+ return None
370
401
 
371
402
  async def __handle_after_agent_callback(
372
403
  self, invocation_context: InvocationContext
373
404
  ) -> Optional[Event]:
374
405
  """Runs the after_agent_callback if it exists.
375
406
 
407
+ Args:
408
+ invocation_context: InvocationContext, the invocation context for this
409
+ agent.
410
+
376
411
  Returns:
377
412
  Optional[Event]: an event if callback provides content or changed state.
378
413
  """
379
- ret_event = None
380
-
381
- if not self.canonical_after_agent_callbacks:
382
- return ret_event
383
414
 
384
415
  callback_context = CallbackContext(invocation_context)
385
416
 
386
- for callback in self.canonical_after_agent_callbacks:
387
- after_agent_callback_content = callback(callback_context=callback_context)
388
- if inspect.isawaitable(after_agent_callback_content):
389
- after_agent_callback_content = await after_agent_callback_content
390
- if after_agent_callback_content:
391
- ret_event = Event(
392
- invocation_id=invocation_context.invocation_id,
393
- author=self.name,
394
- branch=invocation_context.branch,
395
- content=after_agent_callback_content,
396
- actions=callback_context._event_actions,
417
+ # Run callbacks from the plugins.
418
+ after_agent_callback_content = (
419
+ await invocation_context.plugin_manager.run_after_agent_callback(
420
+ agent=self, callback_context=callback_context
397
421
  )
398
- return ret_event
422
+ )
399
423
 
400
- if callback_context.state.has_delta():
424
+ # If no overrides are provided from the plugins, further run the canonical
425
+ # callbacks.
426
+ if (
427
+ not after_agent_callback_content
428
+ and self.canonical_after_agent_callbacks
429
+ ):
430
+ for callback in self.canonical_after_agent_callbacks:
431
+ after_agent_callback_content = callback(
432
+ callback_context=callback_context
433
+ )
434
+ if inspect.isawaitable(after_agent_callback_content):
435
+ after_agent_callback_content = await after_agent_callback_content
436
+ if after_agent_callback_content:
437
+ break
438
+
439
+ # Process the override content if exists, and further process the state
440
+ # change if exists.
441
+ if after_agent_callback_content:
401
442
  ret_event = Event(
402
443
  invocation_id=invocation_context.invocation_id,
403
444
  author=self.name,
@@ -405,8 +446,17 @@ class BaseAgent(BaseModel):
405
446
  content=after_agent_callback_content,
406
447
  actions=callback_context._event_actions,
407
448
  )
449
+ return ret_event
408
450
 
409
- return ret_event
451
+ if callback_context.state.has_delta():
452
+ return Event(
453
+ invocation_id=invocation_context.invocation_id,
454
+ author=self.name,
455
+ branch=invocation_context.branch,
456
+ content=after_agent_callback_content,
457
+ actions=callback_context._event_actions,
458
+ )
459
+ return None
410
460
 
411
461
  @override
412
462
  def model_post_init(self, __context: Any) -> None:
@@ -439,3 +489,151 @@ class BaseAgent(BaseModel):
439
489
  )
440
490
  sub_agent.parent_agent = self
441
491
  return self
492
+
493
+ @classmethod
494
+ @working_in_progress('BaseAgent.from_config is not ready for use.')
495
+ def from_config(
496
+ cls: Type[SelfAgent],
497
+ config: BaseAgentConfig,
498
+ config_abs_path: str,
499
+ ) -> SelfAgent:
500
+ """Creates an agent from a config.
501
+
502
+ This method converts fields in a config to the corresponding
503
+ fields in an agent.
504
+
505
+ Child classes should re-implement this method to support loading from their
506
+ custom config types.
507
+
508
+ Args:
509
+ config: The config to create the agent from.
510
+
511
+ Returns:
512
+ The created agent.
513
+ """
514
+ from .config_agent_utils import build_sub_agent
515
+ from .config_agent_utils import resolve_callbacks
516
+
517
+ kwargs: Dict[str, Any] = {
518
+ 'name': config.name,
519
+ 'description': config.description,
520
+ }
521
+ if config.sub_agents:
522
+ sub_agents = []
523
+ for sub_agent_config in config.sub_agents:
524
+ sub_agent = build_sub_agent(
525
+ sub_agent_config, config_abs_path.rsplit('/', 1)[0]
526
+ )
527
+ sub_agents.append(sub_agent)
528
+ kwargs['sub_agents'] = sub_agents
529
+
530
+ if config.before_agent_callbacks:
531
+ kwargs['before_agent_callback'] = resolve_callbacks(
532
+ config.before_agent_callbacks
533
+ )
534
+ if config.after_agent_callbacks:
535
+ kwargs['after_agent_callback'] = resolve_callbacks(
536
+ config.after_agent_callbacks
537
+ )
538
+ return cls(**kwargs)
539
+
540
+
541
+ class SubAgentConfig(BaseModel):
542
+ """The config for a sub-agent."""
543
+
544
+ model_config = ConfigDict(extra='forbid')
545
+
546
+ config: Optional[str] = None
547
+ """The YAML config file path of the sub-agent.
548
+
549
+ Only one of `config` or `code` can be set.
550
+
551
+ Example:
552
+
553
+ ```
554
+ sub_agents:
555
+ - config: search_agent.yaml
556
+ - config: my_library/my_custom_agent.yaml
557
+ ```
558
+ """
559
+
560
+ code: Optional[str] = None
561
+ """The agent instance defined in the code.
562
+
563
+ Only one of `config` or `code` can be set.
564
+
565
+ Example:
566
+
567
+ For the following agent defined in Python code:
568
+
569
+ ```
570
+ # my_library/custom_agents.py
571
+ from google.adk.agents import LlmAgent
572
+
573
+ my_custom_agent = LlmAgent(
574
+ name="my_custom_agent",
575
+ instruction="You are a helpful custom agent.",
576
+ model="gemini-2.0-flash",
577
+ )
578
+ ```
579
+
580
+ The yaml config should be:
581
+
582
+ ```
583
+ sub_agents:
584
+ - code: my_library.custom_agents.my_custom_agent
585
+ ```
586
+ """
587
+
588
+ @model_validator(mode='after')
589
+ def validate_exactly_one_field(self):
590
+ code_provided = self.code is not None
591
+ config_provided = self.config is not None
592
+
593
+ if code_provided and config_provided:
594
+ raise ValueError('Only one of code or config should be provided')
595
+ if not code_provided and not config_provided:
596
+ raise ValueError('Exactly one of code or config must be provided')
597
+
598
+ return self
599
+
600
+
601
+ @working_in_progress('BaseAgentConfig is not ready for use.')
602
+ class BaseAgentConfig(BaseModel):
603
+ """The config for the YAML schema of a BaseAgent.
604
+
605
+ Do not use this class directly. It's the base class for all agent configs.
606
+ """
607
+
608
+ model_config = ConfigDict(
609
+ extra='forbid',
610
+ alias_generator=alias_generators.to_camel,
611
+ populate_by_name=True,
612
+ )
613
+
614
+ agent_class: Literal['BaseAgent'] = 'BaseAgent'
615
+ """Required. The class of the agent. The value is used to differentiate
616
+ among different agent classes."""
617
+
618
+ name: str
619
+ """Required. The name of the agent."""
620
+
621
+ description: str = ''
622
+ """Optional. The description of the agent."""
623
+
624
+ sub_agents: Optional[List[SubAgentConfig]] = None
625
+ """Optional. The sub-agents of the agent."""
626
+
627
+ before_agent_callbacks: Optional[List[CodeConfig]] = None
628
+ """Optional. The before_agent_callbacks of the agent.
629
+
630
+ Example:
631
+
632
+ ```
633
+ before_agent_callbacks:
634
+ - name: my_library.security_callbacks.before_agent_callback
635
+ ```
636
+ """
637
+
638
+ after_agent_callbacks: Optional[List[CodeConfig]] = None
639
+ """Optional. The after_agent_callbacks of the agent."""
@@ -24,6 +24,8 @@ from .readonly_context import ReadonlyContext
24
24
  if TYPE_CHECKING:
25
25
  from google.genai import types
26
26
 
27
+ from ..auth.auth_credential import AuthCredential
28
+ from ..auth.auth_tool import AuthConfig
27
29
  from ..events.event_actions import EventActions
28
30
  from ..sessions.state import State
29
31
  from .invocation_context import InvocationContext
@@ -105,3 +107,42 @@ class CallbackContext(ReadonlyContext):
105
107
  )
106
108
  self._event_actions.artifact_delta[filename] = version
107
109
  return version
110
+
111
+ async def list_artifacts(self) -> list[str]:
112
+ """Lists the filenames of the artifacts attached to the current session."""
113
+ if self._invocation_context.artifact_service is None:
114
+ raise ValueError("Artifact service is not initialized.")
115
+ return await self._invocation_context.artifact_service.list_artifact_keys(
116
+ app_name=self._invocation_context.app_name,
117
+ user_id=self._invocation_context.user_id,
118
+ session_id=self._invocation_context.session.id,
119
+ )
120
+
121
+ async def save_credential(self, auth_config: AuthConfig) -> None:
122
+ """Saves a credential to the credential service.
123
+
124
+ Args:
125
+ auth_config: The authentication configuration containing the credential.
126
+ """
127
+ if self._invocation_context.credential_service is None:
128
+ raise ValueError("Credential service is not initialized.")
129
+ await self._invocation_context.credential_service.save_credential(
130
+ auth_config, self
131
+ )
132
+
133
+ async def load_credential(
134
+ self, auth_config: AuthConfig
135
+ ) -> Optional[AuthCredential]:
136
+ """Loads a credential from the credential service.
137
+
138
+ Args:
139
+ auth_config: The authentication configuration for the credential.
140
+
141
+ Returns:
142
+ The loaded credential, or None if not found.
143
+ """
144
+ if self._invocation_context.credential_service is None:
145
+ raise ValueError("Credential service is not initialized.")
146
+ return await self._invocation_context.credential_service.load_credential(
147
+ auth_config, self
148
+ )
@@ -0,0 +1,79 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Common configuration classes for agent YAML configs."""
16
+ from __future__ import annotations
17
+
18
+ from typing import Any
19
+ from typing import List
20
+ from typing import Optional
21
+
22
+ from pydantic import BaseModel
23
+ from pydantic import ConfigDict
24
+
25
+ from ..utils.feature_decorator import working_in_progress
26
+
27
+
28
+ @working_in_progress("ArgumentConfig is not ready for use.")
29
+ class ArgumentConfig(BaseModel):
30
+ """An argument passed to a function or a class's constructor."""
31
+
32
+ model_config = ConfigDict(extra="forbid")
33
+
34
+ name: Optional[str] = None
35
+ """Optional. The argument name.
36
+
37
+ When the argument is for a positional argument, this can be omitted.
38
+ """
39
+
40
+ value: Any
41
+ """The argument value."""
42
+
43
+
44
+ @working_in_progress("CodeConfig is not ready for use.")
45
+ class CodeConfig(BaseModel):
46
+ """Code reference config for a variable, a function, or a class.
47
+
48
+ This config is used for configuring callbacks and tools.
49
+ """
50
+
51
+ model_config = ConfigDict(extra="forbid")
52
+
53
+ name: str
54
+ """Required. The name of the variable, function, class, etc. in code.
55
+
56
+ Examples:
57
+
58
+ When used for tools,
59
+ - It can be ADK built-in tools, such as `google_search` and `AgentTool`.
60
+ - It can also be users' custom tools, e.g. my_library.my_tools.my_tool.
61
+
62
+ When used for callbacks, it refers to a function, e.g. `my_library.my_callbacks.my_callback`
63
+ """
64
+
65
+ args: Optional[List[ArgumentConfig]] = None
66
+ """Optional. The arguments for the code when `name` refers to a function or a
67
+ class's contructor.
68
+
69
+ Examples:
70
+ ```
71
+ tools
72
+ - name: AgentTool
73
+ args:
74
+ - name: agent
75
+ value: search_agent.yaml
76
+ - name: skip_summarization
77
+ value: True
78
+ ```
79
+ """