google-adk 0.0.1__py3-none-any.whl → 0.0.2__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 (312) hide show
  1. google/adk/__init__.py +20 -0
  2. google/adk/agents/__init__.py +32 -0
  3. google/adk/agents/active_streaming_tool.py +38 -0
  4. google/adk/agents/base_agent.py +345 -0
  5. google/adk/agents/callback_context.py +112 -0
  6. google/adk/agents/invocation_context.py +181 -0
  7. google/adk/agents/langgraph_agent.py +140 -0
  8. google/adk/agents/live_request_queue.py +64 -0
  9. google/adk/agents/llm_agent.py +376 -0
  10. google/adk/agents/loop_agent.py +62 -0
  11. google/adk/agents/parallel_agent.py +96 -0
  12. google/adk/agents/readonly_context.py +46 -0
  13. google/adk/agents/remote_agent.py +50 -0
  14. google/adk/agents/run_config.py +87 -0
  15. google/adk/agents/sequential_agent.py +45 -0
  16. google/adk/agents/transcription_entry.py +34 -0
  17. google/adk/artifacts/__init__.py +23 -0
  18. google/adk/artifacts/base_artifact_service.py +128 -0
  19. google/adk/artifacts/gcs_artifact_service.py +195 -0
  20. google/adk/artifacts/in_memory_artifact_service.py +133 -0
  21. google/adk/auth/__init__.py +22 -0
  22. google/adk/auth/auth_credential.py +220 -0
  23. google/adk/auth/auth_handler.py +268 -0
  24. google/adk/auth/auth_preprocessor.py +116 -0
  25. google/adk/auth/auth_schemes.py +67 -0
  26. google/adk/auth/auth_tool.py +55 -0
  27. google/adk/cli/__init__.py +15 -0
  28. google/adk/cli/__main__.py +18 -0
  29. google/adk/cli/agent_graph.py +122 -0
  30. google/adk/cli/browser/adk_favicon.svg +17 -0
  31. google/adk/cli/browser/assets/audio-processor.js +51 -0
  32. google/adk/cli/browser/assets/config/runtime-config.json +3 -0
  33. google/adk/cli/browser/index.html +33 -0
  34. google/adk/cli/browser/main-XUU6OGCC.js +75 -0
  35. google/adk/cli/browser/polyfills-FFHMD2TL.js +18 -0
  36. google/adk/cli/browser/styles-4VDSPQ37.css +17 -0
  37. google/adk/cli/cli.py +181 -0
  38. google/adk/cli/cli_deploy.py +181 -0
  39. google/adk/cli/cli_eval.py +282 -0
  40. google/adk/cli/cli_tools_click.py +479 -0
  41. google/adk/cli/fast_api.py +774 -0
  42. google/adk/cli/media_streamer/__init__.py +19 -0
  43. google/adk/cli/media_streamer/index.html +228 -0
  44. google/adk/cli/utils/__init__.py +49 -0
  45. google/adk/cli/utils/envs.py +57 -0
  46. google/adk/cli/utils/evals.py +93 -0
  47. google/adk/cli/utils/logs.py +72 -0
  48. google/adk/code_executors/__init__.py +49 -0
  49. google/adk/code_executors/base_code_executor.py +97 -0
  50. google/adk/code_executors/code_execution_utils.py +256 -0
  51. google/adk/code_executors/code_executor_context.py +202 -0
  52. google/adk/code_executors/container_code_executor.py +196 -0
  53. google/adk/code_executors/unsafe_local_code_executor.py +71 -0
  54. google/adk/code_executors/vertex_ai_code_executor.py +234 -0
  55. google/adk/evaluation/__init__.py +31 -0
  56. google/adk/evaluation/agent_evaluator.py +329 -0
  57. google/adk/evaluation/evaluation_constants.py +24 -0
  58. google/adk/evaluation/evaluation_generator.py +270 -0
  59. google/adk/evaluation/response_evaluator.py +135 -0
  60. google/adk/evaluation/trajectory_evaluator.py +184 -0
  61. google/adk/events/__init__.py +21 -0
  62. google/adk/events/event.py +130 -0
  63. google/adk/events/event_actions.py +55 -0
  64. google/adk/examples/__init__.py +28 -0
  65. google/adk/examples/base_example_provider.py +35 -0
  66. google/adk/examples/example.py +27 -0
  67. google/adk/examples/example_util.py +123 -0
  68. google/adk/examples/vertex_ai_example_store.py +104 -0
  69. google/adk/flows/__init__.py +14 -0
  70. google/adk/flows/llm_flows/__init__.py +20 -0
  71. google/adk/flows/llm_flows/_base_llm_processor.py +52 -0
  72. google/adk/flows/llm_flows/_code_execution.py +458 -0
  73. google/adk/flows/llm_flows/_nl_planning.py +129 -0
  74. google/adk/flows/llm_flows/agent_transfer.py +132 -0
  75. google/adk/flows/llm_flows/audio_transcriber.py +109 -0
  76. google/adk/flows/llm_flows/auto_flow.py +49 -0
  77. google/adk/flows/llm_flows/base_llm_flow.py +559 -0
  78. google/adk/flows/llm_flows/basic.py +72 -0
  79. google/adk/flows/llm_flows/contents.py +370 -0
  80. google/adk/flows/llm_flows/functions.py +486 -0
  81. google/adk/flows/llm_flows/identity.py +47 -0
  82. google/adk/flows/llm_flows/instructions.py +137 -0
  83. google/adk/flows/llm_flows/single_flow.py +57 -0
  84. google/adk/memory/__init__.py +35 -0
  85. google/adk/memory/base_memory_service.py +74 -0
  86. google/adk/memory/in_memory_memory_service.py +62 -0
  87. google/adk/memory/vertex_ai_rag_memory_service.py +177 -0
  88. google/adk/models/__init__.py +31 -0
  89. google/adk/models/anthropic_llm.py +243 -0
  90. google/adk/models/base_llm.py +87 -0
  91. google/adk/models/base_llm_connection.py +76 -0
  92. google/adk/models/gemini_llm_connection.py +200 -0
  93. google/adk/models/google_llm.py +331 -0
  94. google/adk/models/lite_llm.py +673 -0
  95. google/adk/models/llm_request.py +98 -0
  96. google/adk/models/llm_response.py +111 -0
  97. google/adk/models/registry.py +102 -0
  98. google/adk/planners/__init__.py +23 -0
  99. google/adk/planners/base_planner.py +66 -0
  100. google/adk/planners/built_in_planner.py +75 -0
  101. google/adk/planners/plan_re_act_planner.py +208 -0
  102. google/adk/runners.py +456 -0
  103. google/adk/sessions/__init__.py +41 -0
  104. google/adk/sessions/base_session_service.py +133 -0
  105. google/adk/sessions/database_session_service.py +522 -0
  106. google/adk/sessions/in_memory_session_service.py +206 -0
  107. google/adk/sessions/session.py +54 -0
  108. google/adk/sessions/state.py +71 -0
  109. google/adk/sessions/vertex_ai_session_service.py +356 -0
  110. google/adk/telemetry.py +189 -0
  111. google/adk/tests/__init__.py +14 -0
  112. google/adk/tests/integration/.env.example +10 -0
  113. google/adk/tests/integration/__init__.py +18 -0
  114. google/adk/tests/integration/conftest.py +119 -0
  115. google/adk/tests/integration/fixture/__init__.py +14 -0
  116. google/adk/tests/integration/fixture/agent_with_config/__init__.py +15 -0
  117. google/adk/tests/integration/fixture/agent_with_config/agent.py +88 -0
  118. google/adk/tests/integration/fixture/callback_agent/__init__.py +15 -0
  119. google/adk/tests/integration/fixture/callback_agent/agent.py +105 -0
  120. google/adk/tests/integration/fixture/context_update_test/OWNERS +1 -0
  121. google/adk/tests/integration/fixture/context_update_test/__init__.py +15 -0
  122. google/adk/tests/integration/fixture/context_update_test/agent.py +43 -0
  123. google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +582 -0
  124. google/adk/tests/integration/fixture/context_variable_agent/__init__.py +15 -0
  125. google/adk/tests/integration/fixture/context_variable_agent/agent.py +115 -0
  126. google/adk/tests/integration/fixture/customer_support_ma/__init__.py +15 -0
  127. google/adk/tests/integration/fixture/customer_support_ma/agent.py +172 -0
  128. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +15 -0
  129. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +338 -0
  130. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +69 -0
  131. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +6 -0
  132. google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +15 -0
  133. google/adk/tests/integration/fixture/flow_complex_spark/agent.py +182 -0
  134. google/adk/tests/integration/fixture/flow_complex_spark/sample.debug.log +243 -0
  135. google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +190 -0
  136. google/adk/tests/integration/fixture/hello_world_agent/__init__.py +15 -0
  137. google/adk/tests/integration/fixture/hello_world_agent/agent.py +95 -0
  138. google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +24 -0
  139. google/adk/tests/integration/fixture/hello_world_agent/test_config.json +6 -0
  140. google/adk/tests/integration/fixture/home_automation_agent/__init__.py +15 -0
  141. google/adk/tests/integration/fixture/home_automation_agent/agent.py +304 -0
  142. google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +5 -0
  143. google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +5 -0
  144. google/adk/tests/integration/fixture/home_automation_agent/test_config.json +5 -0
  145. google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +18 -0
  146. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +17 -0
  147. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +6 -0
  148. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +18 -0
  149. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +17 -0
  150. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +5 -0
  151. google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +5 -0
  152. google/adk/tests/integration/fixture/tool_agent/__init__.py +15 -0
  153. google/adk/tests/integration/fixture/tool_agent/agent.py +218 -0
  154. google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
  155. google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +15 -0
  156. google/adk/tests/integration/fixture/trip_planner_agent/agent.py +110 -0
  157. google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +13 -0
  158. google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +5 -0
  159. google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +13 -0
  160. google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +5 -0
  161. google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +7 -0
  162. google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +19 -0
  163. google/adk/tests/integration/models/__init__.py +14 -0
  164. google/adk/tests/integration/models/test_google_llm.py +65 -0
  165. google/adk/tests/integration/test_callback.py +70 -0
  166. google/adk/tests/integration/test_context_variable.py +67 -0
  167. google/adk/tests/integration/test_evalute_agent_in_fixture.py +76 -0
  168. google/adk/tests/integration/test_multi_agent.py +28 -0
  169. google/adk/tests/integration/test_multi_turn.py +42 -0
  170. google/adk/tests/integration/test_single_agent.py +23 -0
  171. google/adk/tests/integration/test_sub_agent.py +26 -0
  172. google/adk/tests/integration/test_system_instruction.py +177 -0
  173. google/adk/tests/integration/test_tools.py +287 -0
  174. google/adk/tests/integration/test_with_test_file.py +34 -0
  175. google/adk/tests/integration/tools/__init__.py +14 -0
  176. google/adk/tests/integration/utils/__init__.py +16 -0
  177. google/adk/tests/integration/utils/asserts.py +75 -0
  178. google/adk/tests/integration/utils/test_runner.py +97 -0
  179. google/adk/tests/unittests/__init__.py +14 -0
  180. google/adk/tests/unittests/agents/__init__.py +14 -0
  181. google/adk/tests/unittests/agents/test_base_agent.py +407 -0
  182. google/adk/tests/unittests/agents/test_langgraph_agent.py +191 -0
  183. google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +138 -0
  184. google/adk/tests/unittests/agents/test_llm_agent_fields.py +231 -0
  185. google/adk/tests/unittests/agents/test_loop_agent.py +136 -0
  186. google/adk/tests/unittests/agents/test_parallel_agent.py +92 -0
  187. google/adk/tests/unittests/agents/test_sequential_agent.py +114 -0
  188. google/adk/tests/unittests/artifacts/__init__.py +14 -0
  189. google/adk/tests/unittests/artifacts/test_artifact_service.py +276 -0
  190. google/adk/tests/unittests/auth/test_auth_handler.py +575 -0
  191. google/adk/tests/unittests/conftest.py +73 -0
  192. google/adk/tests/unittests/fast_api/__init__.py +14 -0
  193. google/adk/tests/unittests/fast_api/test_fast_api.py +269 -0
  194. google/adk/tests/unittests/flows/__init__.py +14 -0
  195. google/adk/tests/unittests/flows/llm_flows/__init__.py +14 -0
  196. google/adk/tests/unittests/flows/llm_flows/_test_examples.py +142 -0
  197. google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +311 -0
  198. google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +244 -0
  199. google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +346 -0
  200. google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +93 -0
  201. google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +258 -0
  202. google/adk/tests/unittests/flows/llm_flows/test_identity.py +66 -0
  203. google/adk/tests/unittests/flows/llm_flows/test_instructions.py +164 -0
  204. google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +142 -0
  205. google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +46 -0
  206. google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +269 -0
  207. google/adk/tests/unittests/models/__init__.py +14 -0
  208. google/adk/tests/unittests/models/test_google_llm.py +224 -0
  209. google/adk/tests/unittests/models/test_litellm.py +804 -0
  210. google/adk/tests/unittests/models/test_models.py +60 -0
  211. google/adk/tests/unittests/sessions/__init__.py +14 -0
  212. google/adk/tests/unittests/sessions/test_session_service.py +227 -0
  213. google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +246 -0
  214. google/adk/tests/unittests/streaming/__init__.py +14 -0
  215. google/adk/tests/unittests/streaming/test_streaming.py +50 -0
  216. google/adk/tests/unittests/tools/__init__.py +14 -0
  217. google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +499 -0
  218. google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +204 -0
  219. google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +600 -0
  220. google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +630 -0
  221. google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +345 -0
  222. google/adk/tests/unittests/tools/google_api_tool/__init__.py +13 -0
  223. google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +657 -0
  224. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +145 -0
  225. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +68 -0
  226. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +153 -0
  227. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +196 -0
  228. google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +573 -0
  229. google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +436 -0
  230. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +1367 -0
  231. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +628 -0
  232. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +139 -0
  233. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +406 -0
  234. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +966 -0
  235. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +201 -0
  236. google/adk/tests/unittests/tools/retrieval/__init__.py +14 -0
  237. google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +147 -0
  238. google/adk/tests/unittests/tools/test_agent_tool.py +167 -0
  239. google/adk/tests/unittests/tools/test_base_tool.py +141 -0
  240. google/adk/tests/unittests/tools/test_build_function_declaration.py +277 -0
  241. google/adk/tests/unittests/utils.py +304 -0
  242. google/adk/tools/__init__.py +51 -0
  243. google/adk/tools/_automatic_function_calling_util.py +346 -0
  244. google/adk/tools/agent_tool.py +176 -0
  245. google/adk/tools/apihub_tool/__init__.py +19 -0
  246. google/adk/tools/apihub_tool/apihub_toolset.py +209 -0
  247. google/adk/tools/apihub_tool/clients/__init__.py +13 -0
  248. google/adk/tools/apihub_tool/clients/apihub_client.py +332 -0
  249. google/adk/tools/apihub_tool/clients/secret_client.py +115 -0
  250. google/adk/tools/application_integration_tool/__init__.py +19 -0
  251. google/adk/tools/application_integration_tool/application_integration_toolset.py +230 -0
  252. google/adk/tools/application_integration_tool/clients/connections_client.py +903 -0
  253. google/adk/tools/application_integration_tool/clients/integration_client.py +253 -0
  254. google/adk/tools/base_tool.py +144 -0
  255. google/adk/tools/built_in_code_execution_tool.py +59 -0
  256. google/adk/tools/crewai_tool.py +72 -0
  257. google/adk/tools/example_tool.py +62 -0
  258. google/adk/tools/exit_loop_tool.py +23 -0
  259. google/adk/tools/function_parameter_parse_util.py +307 -0
  260. google/adk/tools/function_tool.py +87 -0
  261. google/adk/tools/get_user_choice_tool.py +28 -0
  262. google/adk/tools/google_api_tool/__init__.py +14 -0
  263. google/adk/tools/google_api_tool/google_api_tool.py +59 -0
  264. google/adk/tools/google_api_tool/google_api_tool_set.py +107 -0
  265. google/adk/tools/google_api_tool/google_api_tool_sets.py +55 -0
  266. google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +521 -0
  267. google/adk/tools/google_search_tool.py +68 -0
  268. google/adk/tools/langchain_tool.py +86 -0
  269. google/adk/tools/load_artifacts_tool.py +113 -0
  270. google/adk/tools/load_memory_tool.py +58 -0
  271. google/adk/tools/load_web_page.py +41 -0
  272. google/adk/tools/long_running_tool.py +39 -0
  273. google/adk/tools/mcp_tool/__init__.py +42 -0
  274. google/adk/tools/mcp_tool/conversion_utils.py +161 -0
  275. google/adk/tools/mcp_tool/mcp_tool.py +113 -0
  276. google/adk/tools/mcp_tool/mcp_toolset.py +272 -0
  277. google/adk/tools/openapi_tool/__init__.py +21 -0
  278. google/adk/tools/openapi_tool/auth/__init__.py +19 -0
  279. google/adk/tools/openapi_tool/auth/auth_helpers.py +498 -0
  280. google/adk/tools/openapi_tool/auth/credential_exchangers/__init__.py +25 -0
  281. google/adk/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.py +105 -0
  282. google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +55 -0
  283. google/adk/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.py +117 -0
  284. google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +97 -0
  285. google/adk/tools/openapi_tool/common/__init__.py +19 -0
  286. google/adk/tools/openapi_tool/common/common.py +300 -0
  287. google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +32 -0
  288. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py +231 -0
  289. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +144 -0
  290. google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +260 -0
  291. google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +496 -0
  292. google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +268 -0
  293. google/adk/tools/preload_memory_tool.py +72 -0
  294. google/adk/tools/retrieval/__init__.py +36 -0
  295. google/adk/tools/retrieval/base_retrieval_tool.py +37 -0
  296. google/adk/tools/retrieval/files_retrieval.py +33 -0
  297. google/adk/tools/retrieval/llama_index_retrieval.py +41 -0
  298. google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +107 -0
  299. google/adk/tools/tool_context.py +90 -0
  300. google/adk/tools/toolbox_tool.py +46 -0
  301. google/adk/tools/transfer_to_agent_tool.py +21 -0
  302. google/adk/tools/vertex_ai_search_tool.py +96 -0
  303. google/adk/version.py +16 -0
  304. google_adk-0.0.1.dist-info/LICENSE.txt → google_adk-0.0.2.dist-info/LICENSE +32 -0
  305. google_adk-0.0.2.dist-info/METADATA +73 -0
  306. google_adk-0.0.2.dist-info/RECORD +308 -0
  307. {google_adk-0.0.1.dist-info → google_adk-0.0.2.dist-info}/WHEEL +1 -2
  308. google_adk-0.0.2.dist-info/entry_points.txt +3 -0
  309. agent_kit/__init__.py +0 -0
  310. google_adk-0.0.1.dist-info/METADATA +0 -15
  311. google_adk-0.0.1.dist-info/RECORD +0 -6
  312. google_adk-0.0.1.dist-info/top_level.txt +0 -1
@@ -0,0 +1,145 @@
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
+ """Unit tests for AutoAuthCredentialExchanger."""
16
+
17
+ from typing import Dict
18
+ from typing import Optional
19
+ from typing import Type
20
+ from unittest.mock import MagicMock
21
+
22
+ from google.adk.auth.auth_credential import AuthCredential
23
+ from google.adk.auth.auth_credential import AuthCredentialTypes
24
+ from google.adk.auth.auth_schemes import AuthScheme
25
+ from google.adk.tools.openapi_tool.auth.credential_exchangers.auto_auth_credential_exchanger import AutoAuthCredentialExchanger
26
+ from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import BaseAuthCredentialExchanger
27
+ from google.adk.tools.openapi_tool.auth.credential_exchangers.oauth2_exchanger import OAuth2CredentialExchanger
28
+ from google.adk.tools.openapi_tool.auth.credential_exchangers.service_account_exchanger import ServiceAccountCredentialExchanger
29
+ import pytest
30
+
31
+
32
+ class MockCredentialExchanger(BaseAuthCredentialExchanger):
33
+ """Mock credential exchanger for testing."""
34
+
35
+ def exchange_credential(
36
+ self,
37
+ auth_scheme: AuthScheme,
38
+ auth_credential: Optional[AuthCredential] = None,
39
+ ) -> AuthCredential:
40
+ """Mock exchange credential method."""
41
+ return auth_credential
42
+
43
+
44
+ @pytest.fixture
45
+ def auto_exchanger():
46
+ """Fixture for creating an AutoAuthCredentialExchanger instance."""
47
+ return AutoAuthCredentialExchanger()
48
+
49
+
50
+ @pytest.fixture
51
+ def auth_scheme():
52
+ """Fixture for creating a mock AuthScheme instance."""
53
+ scheme = MagicMock(spec=AuthScheme)
54
+ return scheme
55
+
56
+
57
+ def test_init_with_custom_exchangers():
58
+ """Test initialization with custom exchangers."""
59
+ custom_exchangers: Dict[str, Type[BaseAuthCredentialExchanger]] = {
60
+ AuthCredentialTypes.API_KEY: MockCredentialExchanger
61
+ }
62
+
63
+ auto_exchanger = AutoAuthCredentialExchanger(
64
+ custom_exchangers=custom_exchangers
65
+ )
66
+
67
+ assert (
68
+ auto_exchanger.exchangers[AuthCredentialTypes.API_KEY]
69
+ == MockCredentialExchanger
70
+ )
71
+ assert (
72
+ auto_exchanger.exchangers[AuthCredentialTypes.OPEN_ID_CONNECT]
73
+ == OAuth2CredentialExchanger
74
+ )
75
+
76
+
77
+ def test_exchange_credential_no_auth_credential(auto_exchanger, auth_scheme):
78
+ """Test exchange_credential with no auth_credential."""
79
+
80
+ assert auto_exchanger.exchange_credential(auth_scheme, None) is None
81
+
82
+
83
+ def test_exchange_credential_no_exchange(auto_exchanger, auth_scheme):
84
+ """Test exchange_credential with NoExchangeCredentialExchanger."""
85
+ auth_credential = AuthCredential(auth_type=AuthCredentialTypes.API_KEY)
86
+
87
+ result = auto_exchanger.exchange_credential(auth_scheme, auth_credential)
88
+
89
+ assert result == auth_credential
90
+
91
+
92
+ def test_exchange_credential_open_id_connect(auto_exchanger, auth_scheme):
93
+ """Test exchange_credential with OpenID Connect scheme."""
94
+ auth_credential = AuthCredential(
95
+ auth_type=AuthCredentialTypes.OPEN_ID_CONNECT
96
+ )
97
+ mock_exchanger = MagicMock(spec=OAuth2CredentialExchanger)
98
+ mock_exchanger.exchange_credential.return_value = "exchanged_credential"
99
+ auto_exchanger.exchangers[AuthCredentialTypes.OPEN_ID_CONNECT] = (
100
+ lambda: mock_exchanger
101
+ )
102
+
103
+ result = auto_exchanger.exchange_credential(auth_scheme, auth_credential)
104
+
105
+ assert result == "exchanged_credential"
106
+ mock_exchanger.exchange_credential.assert_called_once_with(
107
+ auth_scheme, auth_credential
108
+ )
109
+
110
+
111
+ def test_exchange_credential_service_account(auto_exchanger, auth_scheme):
112
+ """Test exchange_credential with Service Account scheme."""
113
+ auth_credential = AuthCredential(
114
+ auth_type=AuthCredentialTypes.SERVICE_ACCOUNT
115
+ )
116
+ mock_exchanger = MagicMock(spec=ServiceAccountCredentialExchanger)
117
+ mock_exchanger.exchange_credential.return_value = "exchanged_credential_sa"
118
+ auto_exchanger.exchangers[AuthCredentialTypes.SERVICE_ACCOUNT] = (
119
+ lambda: mock_exchanger
120
+ )
121
+
122
+ result = auto_exchanger.exchange_credential(auth_scheme, auth_credential)
123
+
124
+ assert result == "exchanged_credential_sa"
125
+ mock_exchanger.exchange_credential.assert_called_once_with(
126
+ auth_scheme, auth_credential
127
+ )
128
+
129
+
130
+ def test_exchange_credential_custom_exchanger(auto_exchanger, auth_scheme):
131
+ """Test that exchange_credential calls the correct (custom) exchanger."""
132
+ # Use a custom exchanger via the initialization
133
+ mock_exchanger = MagicMock(spec=MockCredentialExchanger)
134
+ mock_exchanger.exchange_credential.return_value = "custom_credential"
135
+ auto_exchanger.exchangers[AuthCredentialTypes.API_KEY] = (
136
+ lambda: mock_exchanger
137
+ )
138
+ auth_credential = AuthCredential(auth_type=AuthCredentialTypes.API_KEY)
139
+
140
+ result = auto_exchanger.exchange_credential(auth_scheme, auth_credential)
141
+
142
+ assert result == "custom_credential"
143
+ mock_exchanger.exchange_credential.assert_called_once_with(
144
+ auth_scheme, auth_credential
145
+ )
@@ -0,0 +1,68 @@
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
+ """Tests for the BaseAuthCredentialExchanger class."""
16
+
17
+ from typing import Optional
18
+ from unittest.mock import MagicMock
19
+
20
+ from google.adk.auth.auth_credential import AuthCredential
21
+ from google.adk.auth.auth_credential import AuthCredentialTypes
22
+ from google.adk.auth.auth_schemes import AuthScheme
23
+ from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import AuthCredentialMissingError
24
+ from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import BaseAuthCredentialExchanger
25
+ import pytest
26
+
27
+
28
+ class MockAuthCredentialExchanger(BaseAuthCredentialExchanger):
29
+
30
+ def exchange_credential(
31
+ self,
32
+ auth_scheme: AuthScheme,
33
+ auth_credential: Optional[AuthCredential] = None,
34
+ ) -> AuthCredential:
35
+ return AuthCredential(token="some-token")
36
+
37
+
38
+ class TestBaseAuthCredentialExchanger:
39
+ """Tests for the BaseAuthCredentialExchanger class."""
40
+
41
+ @pytest.fixture
42
+ def base_exchanger(self):
43
+ return BaseAuthCredentialExchanger()
44
+
45
+ @pytest.fixture
46
+ def auth_scheme(self):
47
+ scheme = MagicMock(spec=AuthScheme)
48
+ scheme.type = "apiKey"
49
+ scheme.name = "x-api-key"
50
+ return scheme
51
+
52
+ def test_exchange_credential_not_implemented(
53
+ self, base_exchanger, auth_scheme
54
+ ):
55
+ auth_credential = AuthCredential(
56
+ auth_type=AuthCredentialTypes.API_KEY, token="some-token"
57
+ )
58
+ with pytest.raises(NotImplementedError) as exc_info:
59
+ base_exchanger.exchange_credential(auth_scheme, auth_credential)
60
+ assert "Subclasses must implement exchange_credential." in str(
61
+ exc_info.value
62
+ )
63
+
64
+ def test_auth_credential_missing_error(self):
65
+ error_message = "Test missing credential"
66
+ error = AuthCredentialMissingError(error_message)
67
+ # assert error.message == error_message
68
+ assert str(error) == error_message
@@ -0,0 +1,153 @@
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
+ """Tests for OAuth2CredentialExchanger."""
16
+
17
+ import copy
18
+ from unittest.mock import MagicMock
19
+
20
+ from google.adk.auth.auth_credential import AuthCredential
21
+ from google.adk.auth.auth_credential import AuthCredentialTypes
22
+ from google.adk.auth.auth_credential import OAuth2Auth
23
+ from google.adk.auth.auth_schemes import AuthSchemeType
24
+ from google.adk.auth.auth_schemes import OpenIdConnectWithConfig
25
+ from google.adk.tools.openapi_tool.auth.credential_exchangers import OAuth2CredentialExchanger
26
+ from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import AuthCredentialMissingError
27
+ import pytest
28
+
29
+
30
+ @pytest.fixture
31
+ def oauth2_exchanger():
32
+ return OAuth2CredentialExchanger()
33
+
34
+
35
+ @pytest.fixture
36
+ def auth_scheme():
37
+ openid_config = OpenIdConnectWithConfig(
38
+ type_=AuthSchemeType.openIdConnect,
39
+ authorization_endpoint="https://example.com/auth",
40
+ token_endpoint="https://example.com/token",
41
+ scopes=["openid", "profile"],
42
+ )
43
+ return openid_config
44
+
45
+
46
+ def test_check_scheme_credential_type_success(oauth2_exchanger, auth_scheme):
47
+ auth_credential = AuthCredential(
48
+ auth_type=AuthCredentialTypes.OAUTH2,
49
+ oauth2=OAuth2Auth(
50
+ client_id="test_client",
51
+ client_secret="test_secret",
52
+ redirect_uri="http://localhost:8080",
53
+ ),
54
+ )
55
+ # Check that the method does not raise an exception
56
+ oauth2_exchanger._check_scheme_credential_type(auth_scheme, auth_credential)
57
+
58
+
59
+ def test_check_scheme_credential_type_missing_credential(
60
+ oauth2_exchanger, auth_scheme
61
+ ):
62
+ # Test case: auth_credential is None
63
+ with pytest.raises(ValueError) as exc_info:
64
+ oauth2_exchanger._check_scheme_credential_type(auth_scheme, None)
65
+ assert "auth_credential is empty" in str(exc_info.value)
66
+
67
+
68
+ def test_check_scheme_credential_type_invalid_scheme_type(
69
+ oauth2_exchanger, auth_scheme: OpenIdConnectWithConfig
70
+ ):
71
+ """Test case: Invalid AuthSchemeType."""
72
+ # Test case: Invalid AuthSchemeType
73
+ invalid_scheme = copy.deepcopy(auth_scheme)
74
+ invalid_scheme.type_ = AuthSchemeType.apiKey
75
+ auth_credential = AuthCredential(
76
+ auth_type=AuthCredentialTypes.OAUTH2,
77
+ oauth2=OAuth2Auth(
78
+ client_id="test_client",
79
+ client_secret="test_secret",
80
+ redirect_uri="http://localhost:8080",
81
+ ),
82
+ )
83
+ with pytest.raises(ValueError) as exc_info:
84
+ oauth2_exchanger._check_scheme_credential_type(
85
+ invalid_scheme, auth_credential
86
+ )
87
+ assert "Invalid security scheme" in str(exc_info.value)
88
+
89
+
90
+ def test_check_scheme_credential_type_missing_openid_connect(
91
+ oauth2_exchanger, auth_scheme
92
+ ):
93
+ auth_credential = AuthCredential(
94
+ auth_type=AuthCredentialTypes.OAUTH2,
95
+ )
96
+ with pytest.raises(ValueError) as exc_info:
97
+ oauth2_exchanger._check_scheme_credential_type(auth_scheme, auth_credential)
98
+ assert "auth_credential is not configured with oauth2" in str(exc_info.value)
99
+
100
+
101
+ def test_generate_auth_token_success(
102
+ oauth2_exchanger, auth_scheme, monkeypatch
103
+ ):
104
+ """Test case: Successful generation of access token."""
105
+ # Test case: Successful generation of access token
106
+ auth_credential = AuthCredential(
107
+ auth_type=AuthCredentialTypes.OAUTH2,
108
+ oauth2=OAuth2Auth(
109
+ client_id="test_client",
110
+ client_secret="test_secret",
111
+ redirect_uri="http://localhost:8080",
112
+ auth_response_uri="https://example.com/callback?code=test_code",
113
+ token={"access_token": "test_access_token"},
114
+ ),
115
+ )
116
+ updated_credential = oauth2_exchanger.generate_auth_token(auth_credential)
117
+
118
+ assert updated_credential.auth_type == AuthCredentialTypes.HTTP
119
+ assert updated_credential.http.scheme == "bearer"
120
+ assert updated_credential.http.credentials.token == "test_access_token"
121
+
122
+
123
+ def test_exchange_credential_generate_auth_token(
124
+ oauth2_exchanger, auth_scheme, monkeypatch
125
+ ):
126
+ """Test exchange_credential when auth_response_uri is present."""
127
+ auth_credential = AuthCredential(
128
+ auth_type=AuthCredentialTypes.OAUTH2,
129
+ oauth2=OAuth2Auth(
130
+ client_id="test_client",
131
+ client_secret="test_secret",
132
+ redirect_uri="http://localhost:8080",
133
+ auth_response_uri="https://example.com/callback?code=test_code",
134
+ token={"access_token": "test_access_token"},
135
+ ),
136
+ )
137
+
138
+ updated_credential = oauth2_exchanger.exchange_credential(
139
+ auth_scheme, auth_credential
140
+ )
141
+
142
+ assert updated_credential.auth_type == AuthCredentialTypes.HTTP
143
+ assert updated_credential.http.scheme == "bearer"
144
+ assert updated_credential.http.credentials.token == "test_access_token"
145
+
146
+
147
+ def test_exchange_credential_auth_missing(oauth2_exchanger, auth_scheme):
148
+ """Test exchange_credential when auth_credential is missing."""
149
+ with pytest.raises(ValueError) as exc_info:
150
+ oauth2_exchanger.exchange_credential(auth_scheme, None)
151
+ assert "auth_credential is empty. Please create AuthCredential using" in str(
152
+ exc_info.value
153
+ )
@@ -0,0 +1,196 @@
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
+ """Unit tests for the service account credential exchanger."""
16
+
17
+ from unittest.mock import MagicMock
18
+
19
+ from google.adk.auth.auth_credential import AuthCredential
20
+ from google.adk.auth.auth_credential import AuthCredentialTypes
21
+ from google.adk.auth.auth_credential import ServiceAccount
22
+ from google.adk.auth.auth_credential import ServiceAccountCredential
23
+ from google.adk.auth.auth_schemes import AuthScheme
24
+ from google.adk.auth.auth_schemes import AuthSchemeType
25
+ from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import AuthCredentialMissingError
26
+ from google.adk.tools.openapi_tool.auth.credential_exchangers.service_account_exchanger import ServiceAccountCredentialExchanger
27
+ import google.auth
28
+ import pytest
29
+
30
+
31
+ @pytest.fixture
32
+ def service_account_exchanger():
33
+ return ServiceAccountCredentialExchanger()
34
+
35
+
36
+ @pytest.fixture
37
+ def auth_scheme():
38
+ scheme = MagicMock(spec=AuthScheme)
39
+ scheme.type_ = AuthSchemeType.oauth2
40
+ scheme.description = "Google Service Account"
41
+ return scheme
42
+
43
+
44
+ def test_exchange_credential_success(
45
+ service_account_exchanger, auth_scheme, monkeypatch
46
+ ):
47
+ """Test successful exchange of service account credentials."""
48
+ mock_credentials = MagicMock()
49
+ mock_credentials.token = "mock_access_token"
50
+
51
+ # Mock the from_service_account_info method
52
+ mock_from_service_account_info = MagicMock(return_value=mock_credentials)
53
+ target_path = (
54
+ "google.adk.tools.openapi_tool.auth.credential_exchangers."
55
+ "service_account_exchanger.service_account.Credentials."
56
+ "from_service_account_info"
57
+ )
58
+ monkeypatch.setattr(
59
+ target_path,
60
+ mock_from_service_account_info,
61
+ )
62
+
63
+ # Mock the refresh method
64
+ mock_credentials.refresh = MagicMock()
65
+
66
+ # Create a valid AuthCredential with service account info
67
+ auth_credential = AuthCredential(
68
+ auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
69
+ service_account=ServiceAccount(
70
+ service_account_credential=ServiceAccountCredential(
71
+ type_="service_account",
72
+ project_id="your_project_id",
73
+ private_key_id="your_private_key_id",
74
+ private_key="-----BEGIN PRIVATE KEY-----...",
75
+ client_email="...@....iam.gserviceaccount.com",
76
+ client_id="your_client_id",
77
+ auth_uri="https://accounts.google.com/o/oauth2/auth",
78
+ token_uri="https://oauth2.googleapis.com/token",
79
+ auth_provider_x509_cert_url=(
80
+ "https://www.googleapis.com/oauth2/v1/certs"
81
+ ),
82
+ client_x509_cert_url=(
83
+ "https://www.googleapis.com/robot/v1/metadata/x509/..."
84
+ ),
85
+ universe_domain="googleapis.com",
86
+ ),
87
+ scopes=["https://www.googleapis.com/auth/cloud-platform"],
88
+ ),
89
+ )
90
+
91
+ result = service_account_exchanger.exchange_credential(
92
+ auth_scheme, auth_credential
93
+ )
94
+
95
+ assert result.auth_type == AuthCredentialTypes.HTTP
96
+ assert result.http.scheme == "bearer"
97
+ assert result.http.credentials.token == "mock_access_token"
98
+ mock_from_service_account_info.assert_called_once()
99
+ mock_credentials.refresh.assert_called_once()
100
+
101
+
102
+ def test_exchange_credential_use_default_credential_success(
103
+ service_account_exchanger, auth_scheme, monkeypatch
104
+ ):
105
+ """Test successful exchange of service account credentials using default credential."""
106
+ mock_credentials = MagicMock()
107
+ mock_credentials.token = "mock_access_token"
108
+ mock_google_auth_default = MagicMock(
109
+ return_value=(mock_credentials, "test_project")
110
+ )
111
+ monkeypatch.setattr(google.auth, "default", mock_google_auth_default)
112
+
113
+ auth_credential = AuthCredential(
114
+ auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
115
+ service_account=ServiceAccount(
116
+ use_default_credential=True,
117
+ scopes=["https://www.googleapis.com/auth/cloud-platform"],
118
+ ),
119
+ )
120
+
121
+ result = service_account_exchanger.exchange_credential(
122
+ auth_scheme, auth_credential
123
+ )
124
+
125
+ assert result.auth_type == AuthCredentialTypes.HTTP
126
+ assert result.http.scheme == "bearer"
127
+ assert result.http.credentials.token == "mock_access_token"
128
+ mock_google_auth_default.assert_called_once()
129
+ mock_credentials.refresh.assert_called_once()
130
+
131
+
132
+ def test_exchange_credential_missing_auth_credential(
133
+ service_account_exchanger, auth_scheme
134
+ ):
135
+ """Test missing auth credential during exchange."""
136
+ with pytest.raises(AuthCredentialMissingError) as exc_info:
137
+ service_account_exchanger.exchange_credential(auth_scheme, None)
138
+ assert "Service account credentials are missing" in str(exc_info.value)
139
+
140
+
141
+ def test_exchange_credential_missing_service_account_info(
142
+ service_account_exchanger, auth_scheme
143
+ ):
144
+ """Test missing service account info during exchange."""
145
+ auth_credential = AuthCredential(
146
+ auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
147
+ )
148
+ with pytest.raises(AuthCredentialMissingError) as exc_info:
149
+ service_account_exchanger.exchange_credential(auth_scheme, auth_credential)
150
+ assert "Service account credentials are missing" in str(exc_info.value)
151
+
152
+
153
+ def test_exchange_credential_exchange_failure(
154
+ service_account_exchanger, auth_scheme, monkeypatch
155
+ ):
156
+ """Test failure during service account token exchange."""
157
+ mock_from_service_account_info = MagicMock(
158
+ side_effect=Exception("Failed to load credentials")
159
+ )
160
+ target_path = (
161
+ "google.adk.tools.openapi_tool.auth.credential_exchangers."
162
+ "service_account_exchanger.service_account.Credentials."
163
+ "from_service_account_info"
164
+ )
165
+ monkeypatch.setattr(
166
+ target_path,
167
+ mock_from_service_account_info,
168
+ )
169
+
170
+ auth_credential = AuthCredential(
171
+ auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
172
+ service_account=ServiceAccount(
173
+ service_account_credential=ServiceAccountCredential(
174
+ type_="service_account",
175
+ project_id="your_project_id",
176
+ private_key_id="your_private_key_id",
177
+ private_key="-----BEGIN PRIVATE KEY-----...",
178
+ client_email="...@....iam.gserviceaccount.com",
179
+ client_id="your_client_id",
180
+ auth_uri="https://accounts.google.com/o/oauth2/auth",
181
+ token_uri="https://oauth2.googleapis.com/token",
182
+ auth_provider_x509_cert_url=(
183
+ "https://www.googleapis.com/oauth2/v1/certs"
184
+ ),
185
+ client_x509_cert_url=(
186
+ "https://www.googleapis.com/robot/v1/metadata/x509/..."
187
+ ),
188
+ universe_domain="googleapis.com",
189
+ ),
190
+ scopes=["https://www.googleapis.com/auth/cloud-platform"],
191
+ ),
192
+ )
193
+ with pytest.raises(AuthCredentialMissingError) as exc_info:
194
+ service_account_exchanger.exchange_credential(auth_scheme, auth_credential)
195
+ assert "Failed to exchange service account token" in str(exc_info.value)
196
+ mock_from_service_account_info.assert_called_once()