google-adk 0.0.1__py3-none-any.whl → 0.0.3__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.
- google/adk/._version.py +0 -0
- google/adk/__init__.py +20 -0
- google/adk/agents/__init__.py +32 -0
- google/adk/agents/active_streaming_tool.py +38 -0
- google/adk/agents/base_agent.py +345 -0
- google/adk/agents/callback_context.py +112 -0
- google/adk/agents/invocation_context.py +181 -0
- google/adk/agents/langgraph_agent.py +140 -0
- google/adk/agents/live_request_queue.py +64 -0
- google/adk/agents/llm_agent.py +376 -0
- google/adk/agents/loop_agent.py +62 -0
- google/adk/agents/parallel_agent.py +96 -0
- google/adk/agents/readonly_context.py +46 -0
- google/adk/agents/remote_agent.py +50 -0
- google/adk/agents/run_config.py +87 -0
- google/adk/agents/sequential_agent.py +45 -0
- google/adk/agents/transcription_entry.py +34 -0
- google/adk/artifacts/__init__.py +23 -0
- google/adk/artifacts/base_artifact_service.py +128 -0
- google/adk/artifacts/gcs_artifact_service.py +195 -0
- google/adk/artifacts/in_memory_artifact_service.py +133 -0
- google/adk/auth/__init__.py +22 -0
- google/adk/auth/auth_credential.py +220 -0
- google/adk/auth/auth_handler.py +268 -0
- google/adk/auth/auth_preprocessor.py +116 -0
- google/adk/auth/auth_schemes.py +67 -0
- google/adk/auth/auth_tool.py +55 -0
- google/adk/cli/__init__.py +15 -0
- google/adk/cli/__main__.py +18 -0
- google/adk/cli/agent_graph.py +148 -0
- google/adk/cli/browser/adk_favicon.svg +17 -0
- google/adk/cli/browser/assets/audio-processor.js +51 -0
- google/adk/cli/browser/assets/config/runtime-config.json +3 -0
- google/adk/cli/browser/index.html +33 -0
- google/adk/cli/browser/main-SY2WYYGV.js +75 -0
- google/adk/cli/browser/polyfills-FFHMD2TL.js +18 -0
- google/adk/cli/browser/styles-4VDSPQ37.css +17 -0
- google/adk/cli/cli.py +181 -0
- google/adk/cli/cli_deploy.py +181 -0
- google/adk/cli/cli_eval.py +282 -0
- google/adk/cli/cli_tools_click.py +524 -0
- google/adk/cli/fast_api.py +784 -0
- google/adk/cli/utils/__init__.py +49 -0
- google/adk/cli/utils/envs.py +57 -0
- google/adk/cli/utils/evals.py +93 -0
- google/adk/cli/utils/logs.py +72 -0
- google/adk/code_executors/__init__.py +49 -0
- google/adk/code_executors/base_code_executor.py +97 -0
- google/adk/code_executors/code_execution_utils.py +256 -0
- google/adk/code_executors/code_executor_context.py +202 -0
- google/adk/code_executors/container_code_executor.py +196 -0
- google/adk/code_executors/unsafe_local_code_executor.py +71 -0
- google/adk/code_executors/vertex_ai_code_executor.py +234 -0
- google/adk/docs/Makefile +20 -0
- google/adk/docs/build/doctrees/google-adk.doctree +0 -0
- google/adk/docs/build/html/_sources/google-adk.rst.txt +98 -0
- google/adk/docs/build/html/_sources/index.rst.txt +7 -0
- google/adk/docs/build/html/_static/autodoc_pydantic.css +27 -0
- google/adk/docs/build/html/_static/basic.css +925 -0
- google/adk/docs/build/html/_static/debug.css +85 -0
- google/adk/docs/build/html/_static/doctools.js +156 -0
- google/adk/docs/build/html/_static/documentation_options.js +29 -0
- google/adk/docs/build/html/_static/file.png +0 -0
- google/adk/docs/build/html/_static/language_data.js +199 -0
- google/adk/docs/build/html/_static/minus.png +0 -0
- google/adk/docs/build/html/_static/plus.png +0 -0
- google/adk/docs/build/html/_static/pygments.css +274 -0
- google/adk/docs/build/html/_static/scripts/furo-extensions.js +16 -0
- google/adk/docs/build/html/_static/scripts/furo.js +19 -0
- google/adk/docs/build/html/_static/scripts/furo.js.LICENSE.txt +7 -0
- google/adk/docs/build/html/_static/scripts/furo.js.map +1 -0
- google/adk/docs/build/html/_static/searchtools.js +620 -0
- google/adk/docs/build/html/_static/skeleton.css +312 -0
- google/adk/docs/build/html/_static/sphinx_highlight.js +170 -0
- google/adk/docs/build/html/_static/styles/furo-extensions.css +18 -0
- google/adk/docs/build/html/_static/styles/furo-extensions.css.map +1 -0
- google/adk/docs/build/html/_static/styles/furo.css +18 -0
- google/adk/docs/build/html/_static/styles/furo.css.map +1 -0
- google/adk/docs/build/html/genindex.html +861 -0
- google/adk/docs/build/html/google-adk.html +5461 -0
- google/adk/docs/build/html/index.html +567 -0
- google/adk/docs/build/html/objects.inv +0 -0
- google/adk/docs/build/html/py-modindex.html +373 -0
- google/adk/docs/build/html/search.html +333 -0
- google/adk/docs/build/html/searchindex.js +17 -0
- google/adk/docs/source/conf.py +133 -0
- google/adk/docs/source/google-adk.rst +98 -0
- google/adk/docs/source/index.rst +7 -0
- google/adk/evaluation/__init__.py +31 -0
- google/adk/evaluation/agent_evaluator.py +329 -0
- google/adk/evaluation/evaluation_constants.py +24 -0
- google/adk/evaluation/evaluation_generator.py +270 -0
- google/adk/evaluation/response_evaluator.py +135 -0
- google/adk/evaluation/trajectory_evaluator.py +184 -0
- google/adk/events/__init__.py +21 -0
- google/adk/events/event.py +130 -0
- google/adk/events/event_actions.py +55 -0
- google/adk/examples/__init__.py +28 -0
- google/adk/examples/base_example_provider.py +35 -0
- google/adk/examples/example.py +27 -0
- google/adk/examples/example_util.py +123 -0
- google/adk/examples/vertex_ai_example_store.py +104 -0
- google/adk/flows/__init__.py +14 -0
- google/adk/flows/llm_flows/__init__.py +20 -0
- google/adk/flows/llm_flows/_base_llm_processor.py +52 -0
- google/adk/flows/llm_flows/_code_execution.py +458 -0
- google/adk/flows/llm_flows/_nl_planning.py +129 -0
- google/adk/flows/llm_flows/agent_transfer.py +132 -0
- google/adk/flows/llm_flows/audio_transcriber.py +109 -0
- google/adk/flows/llm_flows/auto_flow.py +49 -0
- google/adk/flows/llm_flows/base_llm_flow.py +559 -0
- google/adk/flows/llm_flows/basic.py +72 -0
- google/adk/flows/llm_flows/contents.py +370 -0
- google/adk/flows/llm_flows/functions.py +486 -0
- google/adk/flows/llm_flows/identity.py +47 -0
- google/adk/flows/llm_flows/instructions.py +137 -0
- google/adk/flows/llm_flows/single_flow.py +57 -0
- google/adk/memory/__init__.py +35 -0
- google/adk/memory/base_memory_service.py +74 -0
- google/adk/memory/in_memory_memory_service.py +62 -0
- google/adk/memory/vertex_ai_rag_memory_service.py +177 -0
- google/adk/models/__init__.py +31 -0
- google/adk/models/anthropic_llm.py +243 -0
- google/adk/models/base_llm.py +87 -0
- google/adk/models/base_llm_connection.py +76 -0
- google/adk/models/gemini_llm_connection.py +200 -0
- google/adk/models/google_llm.py +331 -0
- google/adk/models/lite_llm.py +673 -0
- google/adk/models/llm_request.py +98 -0
- google/adk/models/llm_response.py +111 -0
- google/adk/models/registry.py +102 -0
- google/adk/planners/__init__.py +23 -0
- google/adk/planners/base_planner.py +66 -0
- google/adk/planners/built_in_planner.py +75 -0
- google/adk/planners/plan_re_act_planner.py +208 -0
- google/adk/runners.py +456 -0
- google/adk/sessions/__init__.py +41 -0
- google/adk/sessions/base_session_service.py +133 -0
- google/adk/sessions/database_session_service.py +522 -0
- google/adk/sessions/in_memory_session_service.py +206 -0
- google/adk/sessions/session.py +54 -0
- google/adk/sessions/state.py +71 -0
- google/adk/sessions/vertex_ai_session_service.py +356 -0
- google/adk/telemetry.py +189 -0
- google/adk/tests/__init__.py +14 -0
- google/adk/tests/integration/.env.example +10 -0
- google/adk/tests/integration/__init__.py +18 -0
- google/adk/tests/integration/conftest.py +119 -0
- google/adk/tests/integration/fixture/__init__.py +14 -0
- google/adk/tests/integration/fixture/agent_with_config/__init__.py +15 -0
- google/adk/tests/integration/fixture/agent_with_config/agent.py +88 -0
- google/adk/tests/integration/fixture/callback_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/callback_agent/agent.py +105 -0
- google/adk/tests/integration/fixture/context_update_test/OWNERS +1 -0
- google/adk/tests/integration/fixture/context_update_test/__init__.py +15 -0
- google/adk/tests/integration/fixture/context_update_test/agent.py +43 -0
- google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +582 -0
- google/adk/tests/integration/fixture/context_variable_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/context_variable_agent/agent.py +115 -0
- google/adk/tests/integration/fixture/customer_support_ma/__init__.py +15 -0
- google/adk/tests/integration/fixture/customer_support_ma/agent.py +172 -0
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +338 -0
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +69 -0
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +6 -0
- google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +15 -0
- google/adk/tests/integration/fixture/flow_complex_spark/agent.py +182 -0
- google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +190 -0
- google/adk/tests/integration/fixture/hello_world_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/hello_world_agent/agent.py +95 -0
- google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +24 -0
- google/adk/tests/integration/fixture/hello_world_agent/test_config.json +6 -0
- google/adk/tests/integration/fixture/home_automation_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/home_automation_agent/agent.py +304 -0
- google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +5 -0
- google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +5 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_config.json +5 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +18 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +17 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +6 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +18 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +17 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +5 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +5 -0
- google/adk/tests/integration/fixture/tool_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/tool_agent/agent.py +218 -0
- google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
- google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/trip_planner_agent/agent.py +110 -0
- google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +13 -0
- google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +5 -0
- google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +13 -0
- google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +5 -0
- google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +7 -0
- google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +19 -0
- google/adk/tests/integration/models/__init__.py +14 -0
- google/adk/tests/integration/models/test_google_llm.py +65 -0
- google/adk/tests/integration/test_callback.py +70 -0
- google/adk/tests/integration/test_context_variable.py +67 -0
- google/adk/tests/integration/test_evalute_agent_in_fixture.py +76 -0
- google/adk/tests/integration/test_multi_agent.py +28 -0
- google/adk/tests/integration/test_multi_turn.py +42 -0
- google/adk/tests/integration/test_single_agent.py +23 -0
- google/adk/tests/integration/test_sub_agent.py +26 -0
- google/adk/tests/integration/test_system_instruction.py +177 -0
- google/adk/tests/integration/test_tools.py +287 -0
- google/adk/tests/integration/test_with_test_file.py +34 -0
- google/adk/tests/integration/tools/__init__.py +14 -0
- google/adk/tests/integration/utils/__init__.py +16 -0
- google/adk/tests/integration/utils/asserts.py +75 -0
- google/adk/tests/integration/utils/test_runner.py +97 -0
- google/adk/tests/unittests/__init__.py +14 -0
- google/adk/tests/unittests/agents/__init__.py +14 -0
- google/adk/tests/unittests/agents/test_base_agent.py +407 -0
- google/adk/tests/unittests/agents/test_langgraph_agent.py +191 -0
- google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +138 -0
- google/adk/tests/unittests/agents/test_llm_agent_fields.py +231 -0
- google/adk/tests/unittests/agents/test_loop_agent.py +136 -0
- google/adk/tests/unittests/agents/test_parallel_agent.py +92 -0
- google/adk/tests/unittests/agents/test_sequential_agent.py +114 -0
- google/adk/tests/unittests/artifacts/__init__.py +14 -0
- google/adk/tests/unittests/artifacts/test_artifact_service.py +276 -0
- google/adk/tests/unittests/auth/test_auth_handler.py +575 -0
- google/adk/tests/unittests/conftest.py +73 -0
- google/adk/tests/unittests/fast_api/__init__.py +14 -0
- google/adk/tests/unittests/fast_api/test_fast_api.py +269 -0
- google/adk/tests/unittests/flows/__init__.py +14 -0
- google/adk/tests/unittests/flows/llm_flows/__init__.py +14 -0
- google/adk/tests/unittests/flows/llm_flows/_test_examples.py +142 -0
- google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +311 -0
- google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +244 -0
- google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +346 -0
- google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +93 -0
- google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +258 -0
- google/adk/tests/unittests/flows/llm_flows/test_identity.py +66 -0
- google/adk/tests/unittests/flows/llm_flows/test_instructions.py +164 -0
- google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +142 -0
- google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +46 -0
- google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +269 -0
- google/adk/tests/unittests/models/__init__.py +14 -0
- google/adk/tests/unittests/models/test_google_llm.py +224 -0
- google/adk/tests/unittests/models/test_litellm.py +804 -0
- google/adk/tests/unittests/models/test_models.py +60 -0
- google/adk/tests/unittests/sessions/__init__.py +14 -0
- google/adk/tests/unittests/sessions/test_session_service.py +227 -0
- google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +246 -0
- google/adk/tests/unittests/streaming/__init__.py +14 -0
- google/adk/tests/unittests/streaming/test_streaming.py +50 -0
- google/adk/tests/unittests/tools/__init__.py +14 -0
- google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +499 -0
- google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +204 -0
- google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +600 -0
- google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +630 -0
- google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +345 -0
- google/adk/tests/unittests/tools/google_api_tool/__init__.py +13 -0
- google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +657 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +145 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +68 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +153 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +196 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +573 -0
- google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +436 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +1367 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +628 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +139 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +406 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +966 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +201 -0
- google/adk/tests/unittests/tools/retrieval/__init__.py +14 -0
- google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +147 -0
- google/adk/tests/unittests/tools/test_agent_tool.py +167 -0
- google/adk/tests/unittests/tools/test_base_tool.py +141 -0
- google/adk/tests/unittests/tools/test_build_function_declaration.py +277 -0
- google/adk/tests/unittests/utils.py +304 -0
- google/adk/tools/__init__.py +51 -0
- google/adk/tools/_automatic_function_calling_util.py +346 -0
- google/adk/tools/agent_tool.py +176 -0
- google/adk/tools/apihub_tool/__init__.py +19 -0
- google/adk/tools/apihub_tool/apihub_toolset.py +209 -0
- google/adk/tools/apihub_tool/clients/__init__.py +13 -0
- google/adk/tools/apihub_tool/clients/apihub_client.py +332 -0
- google/adk/tools/apihub_tool/clients/secret_client.py +115 -0
- google/adk/tools/application_integration_tool/__init__.py +19 -0
- google/adk/tools/application_integration_tool/application_integration_toolset.py +230 -0
- google/adk/tools/application_integration_tool/clients/connections_client.py +903 -0
- google/adk/tools/application_integration_tool/clients/integration_client.py +253 -0
- google/adk/tools/base_tool.py +144 -0
- google/adk/tools/built_in_code_execution_tool.py +59 -0
- google/adk/tools/crewai_tool.py +72 -0
- google/adk/tools/example_tool.py +62 -0
- google/adk/tools/exit_loop_tool.py +23 -0
- google/adk/tools/function_parameter_parse_util.py +307 -0
- google/adk/tools/function_tool.py +87 -0
- google/adk/tools/get_user_choice_tool.py +28 -0
- google/adk/tools/google_api_tool/__init__.py +14 -0
- google/adk/tools/google_api_tool/google_api_tool.py +59 -0
- google/adk/tools/google_api_tool/google_api_tool_set.py +107 -0
- google/adk/tools/google_api_tool/google_api_tool_sets.py +55 -0
- google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +521 -0
- google/adk/tools/google_search_tool.py +68 -0
- google/adk/tools/langchain_tool.py +86 -0
- google/adk/tools/load_artifacts_tool.py +113 -0
- google/adk/tools/load_memory_tool.py +58 -0
- google/adk/tools/load_web_page.py +41 -0
- google/adk/tools/long_running_tool.py +39 -0
- google/adk/tools/mcp_tool/__init__.py +42 -0
- google/adk/tools/mcp_tool/conversion_utils.py +161 -0
- google/adk/tools/mcp_tool/mcp_tool.py +113 -0
- google/adk/tools/mcp_tool/mcp_toolset.py +272 -0
- google/adk/tools/openapi_tool/__init__.py +21 -0
- google/adk/tools/openapi_tool/auth/__init__.py +19 -0
- google/adk/tools/openapi_tool/auth/auth_helpers.py +498 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/__init__.py +25 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.py +105 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +55 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.py +117 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +97 -0
- google/adk/tools/openapi_tool/common/__init__.py +19 -0
- google/adk/tools/openapi_tool/common/common.py +300 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +32 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py +231 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +144 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +260 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +496 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +268 -0
- google/adk/tools/preload_memory_tool.py +72 -0
- google/adk/tools/retrieval/__init__.py +36 -0
- google/adk/tools/retrieval/base_retrieval_tool.py +37 -0
- google/adk/tools/retrieval/files_retrieval.py +33 -0
- google/adk/tools/retrieval/llama_index_retrieval.py +41 -0
- google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +107 -0
- google/adk/tools/tool_context.py +90 -0
- google/adk/tools/toolbox_tool.py +46 -0
- google/adk/tools/transfer_to_agent_tool.py +21 -0
- google/adk/tools/vertex_ai_search_tool.py +96 -0
- google/adk/version.py +16 -0
- google_adk-0.0.3.dist-info/METADATA +73 -0
- google_adk-0.0.3.dist-info/RECORD +340 -0
- {google_adk-0.0.1.dist-info → google_adk-0.0.3.dist-info}/WHEEL +1 -2
- google_adk-0.0.3.dist-info/entry_points.txt +3 -0
- agent_kit/__init__.py +0 -0
- google_adk-0.0.1.dist-info/LICENSE.txt +0 -170
- google_adk-0.0.1.dist-info/METADATA +0 -15
- google_adk-0.0.1.dist-info/RECORD +0 -6
- google_adk-0.0.1.dist-info/top_level.txt +0 -1
@@ -0,0 +1,206 @@
|
|
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
|
+
import copy
|
16
|
+
import time
|
17
|
+
from typing import Any
|
18
|
+
from typing import Optional
|
19
|
+
import uuid
|
20
|
+
|
21
|
+
from typing_extensions import override
|
22
|
+
|
23
|
+
from ..events.event import Event
|
24
|
+
from .base_session_service import BaseSessionService
|
25
|
+
from .base_session_service import GetSessionConfig
|
26
|
+
from .base_session_service import ListEventsResponse
|
27
|
+
from .base_session_service import ListSessionsResponse
|
28
|
+
from .session import Session
|
29
|
+
from .state import State
|
30
|
+
|
31
|
+
|
32
|
+
class InMemorySessionService(BaseSessionService):
|
33
|
+
"""An in-memory implementation of the session service."""
|
34
|
+
|
35
|
+
def __init__(self):
|
36
|
+
# A map from app name to a map from user ID to a map from session ID to session.
|
37
|
+
self.sessions: dict[str, dict[str, dict[str, Session]]] = {}
|
38
|
+
# A map from app name to a map from user ID to a map from key to the value.
|
39
|
+
self.user_state: dict[str, dict[str, dict[str, Any]]] = {}
|
40
|
+
# A map from app name to a map from key to the value.
|
41
|
+
self.app_state: dict[str, dict[str, Any]] = {}
|
42
|
+
|
43
|
+
@override
|
44
|
+
def create_session(
|
45
|
+
self,
|
46
|
+
*,
|
47
|
+
app_name: str,
|
48
|
+
user_id: str,
|
49
|
+
state: Optional[dict[str, Any]] = None,
|
50
|
+
session_id: Optional[str] = None,
|
51
|
+
) -> Session:
|
52
|
+
session_id = (
|
53
|
+
session_id.strip()
|
54
|
+
if session_id and session_id.strip()
|
55
|
+
else str(uuid.uuid4())
|
56
|
+
)
|
57
|
+
session = Session(
|
58
|
+
app_name=app_name,
|
59
|
+
user_id=user_id,
|
60
|
+
id=session_id,
|
61
|
+
state=state or {},
|
62
|
+
last_update_time=time.time(),
|
63
|
+
)
|
64
|
+
|
65
|
+
if app_name not in self.sessions:
|
66
|
+
self.sessions[app_name] = {}
|
67
|
+
if user_id not in self.sessions[app_name]:
|
68
|
+
self.sessions[app_name][user_id] = {}
|
69
|
+
self.sessions[app_name][user_id][session_id] = session
|
70
|
+
|
71
|
+
copied_session = copy.deepcopy(session)
|
72
|
+
return self._merge_state(app_name, user_id, copied_session)
|
73
|
+
|
74
|
+
@override
|
75
|
+
def get_session(
|
76
|
+
self,
|
77
|
+
*,
|
78
|
+
app_name: str,
|
79
|
+
user_id: str,
|
80
|
+
session_id: str,
|
81
|
+
config: Optional[GetSessionConfig] = None,
|
82
|
+
) -> Session:
|
83
|
+
if app_name not in self.sessions:
|
84
|
+
return None
|
85
|
+
if user_id not in self.sessions[app_name]:
|
86
|
+
return None
|
87
|
+
if session_id not in self.sessions[app_name][user_id]:
|
88
|
+
return None
|
89
|
+
|
90
|
+
session = self.sessions[app_name][user_id].get(session_id)
|
91
|
+
copied_session = copy.deepcopy(session)
|
92
|
+
|
93
|
+
if config:
|
94
|
+
if config.num_recent_events:
|
95
|
+
copied_session.events = copied_session.events[
|
96
|
+
-config.num_recent_events :
|
97
|
+
]
|
98
|
+
elif config.after_timestamp:
|
99
|
+
i = len(session.events) - 1
|
100
|
+
while i >= 0:
|
101
|
+
if copied_session.events[i].timestamp < config.after_timestamp:
|
102
|
+
break
|
103
|
+
i -= 1
|
104
|
+
if i >= 0:
|
105
|
+
copied_session.events = copied_session.events[i:]
|
106
|
+
|
107
|
+
return self._merge_state(app_name, user_id, copied_session)
|
108
|
+
|
109
|
+
def _merge_state(self, app_name: str, user_id: str, copied_session: Session):
|
110
|
+
# Merge app state
|
111
|
+
if app_name in self.app_state:
|
112
|
+
for key in self.app_state[app_name].keys():
|
113
|
+
copied_session.state[State.APP_PREFIX + key] = self.app_state[app_name][
|
114
|
+
key
|
115
|
+
]
|
116
|
+
|
117
|
+
if (
|
118
|
+
app_name not in self.user_state
|
119
|
+
or user_id not in self.user_state[app_name]
|
120
|
+
):
|
121
|
+
return copied_session
|
122
|
+
|
123
|
+
# Merge session state with user state.
|
124
|
+
for key in self.user_state[app_name][user_id].keys():
|
125
|
+
copied_session.state[State.USER_PREFIX + key] = self.user_state[app_name][
|
126
|
+
user_id
|
127
|
+
][key]
|
128
|
+
return copied_session
|
129
|
+
|
130
|
+
@override
|
131
|
+
def list_sessions(
|
132
|
+
self, *, app_name: str, user_id: str
|
133
|
+
) -> ListSessionsResponse:
|
134
|
+
empty_response = ListSessionsResponse()
|
135
|
+
if app_name not in self.sessions:
|
136
|
+
return empty_response
|
137
|
+
if user_id not in self.sessions[app_name]:
|
138
|
+
return empty_response
|
139
|
+
|
140
|
+
sessions_without_events = []
|
141
|
+
for session in self.sessions[app_name][user_id].values():
|
142
|
+
copied_session = copy.deepcopy(session)
|
143
|
+
copied_session.events = []
|
144
|
+
copied_session.state = {}
|
145
|
+
sessions_without_events.append(copied_session)
|
146
|
+
return ListSessionsResponse(sessions=sessions_without_events)
|
147
|
+
|
148
|
+
@override
|
149
|
+
def delete_session(
|
150
|
+
self, *, app_name: str, user_id: str, session_id: str
|
151
|
+
) -> None:
|
152
|
+
if (
|
153
|
+
self.get_session(
|
154
|
+
app_name=app_name, user_id=user_id, session_id=session_id
|
155
|
+
)
|
156
|
+
is None
|
157
|
+
):
|
158
|
+
return None
|
159
|
+
|
160
|
+
self.sessions[app_name][user_id].pop(session_id)
|
161
|
+
|
162
|
+
@override
|
163
|
+
def append_event(self, session: Session, event: Event) -> Event:
|
164
|
+
# Update the in-memory session.
|
165
|
+
super().append_event(session=session, event=event)
|
166
|
+
session.last_update_time = event.timestamp
|
167
|
+
|
168
|
+
# Update the storage session
|
169
|
+
app_name = session.app_name
|
170
|
+
user_id = session.user_id
|
171
|
+
session_id = session.id
|
172
|
+
if app_name not in self.sessions:
|
173
|
+
return event
|
174
|
+
if user_id not in self.sessions[app_name]:
|
175
|
+
return event
|
176
|
+
if session_id not in self.sessions[app_name][user_id]:
|
177
|
+
return event
|
178
|
+
|
179
|
+
if event.actions and event.actions.state_delta:
|
180
|
+
for key in event.actions.state_delta:
|
181
|
+
if key.startswith(State.APP_PREFIX):
|
182
|
+
self.app_state.setdefault(app_name, {})[
|
183
|
+
key.removeprefix(State.APP_PREFIX)
|
184
|
+
] = event.actions.state_delta[key]
|
185
|
+
|
186
|
+
if key.startswith(State.USER_PREFIX):
|
187
|
+
self.user_state.setdefault(app_name, {}).setdefault(user_id, {})[
|
188
|
+
key.removeprefix(State.USER_PREFIX)
|
189
|
+
] = event.actions.state_delta[key]
|
190
|
+
|
191
|
+
storage_session = self.sessions[app_name][user_id].get(session_id)
|
192
|
+
super().append_event(session=storage_session, event=event)
|
193
|
+
|
194
|
+
storage_session.last_update_time = event.timestamp
|
195
|
+
|
196
|
+
return event
|
197
|
+
|
198
|
+
@override
|
199
|
+
def list_events(
|
200
|
+
self,
|
201
|
+
*,
|
202
|
+
app_name: str,
|
203
|
+
user_id: str,
|
204
|
+
session_id: str,
|
205
|
+
) -> ListEventsResponse:
|
206
|
+
raise NotImplementedError()
|
@@ -0,0 +1,54 @@
|
|
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 typing import Any
|
16
|
+
|
17
|
+
from pydantic import BaseModel
|
18
|
+
from pydantic import ConfigDict
|
19
|
+
from pydantic import Field
|
20
|
+
|
21
|
+
from ..events.event import Event
|
22
|
+
|
23
|
+
|
24
|
+
class Session(BaseModel):
|
25
|
+
"""Represents a series of interactions between a user and agents.
|
26
|
+
|
27
|
+
Attributes:
|
28
|
+
id: The unique identifier of the session.
|
29
|
+
app_name: The name of the app.
|
30
|
+
user_id: The id of the user.
|
31
|
+
state: The state of the session.
|
32
|
+
events: The events of the session, e.g. user input, model response, function
|
33
|
+
call/response, etc.
|
34
|
+
last_update_time: The last update time of the session.
|
35
|
+
"""
|
36
|
+
|
37
|
+
model_config = ConfigDict(
|
38
|
+
extra='forbid',
|
39
|
+
arbitrary_types_allowed=True,
|
40
|
+
)
|
41
|
+
|
42
|
+
id: str
|
43
|
+
"""The unique identifier of the session."""
|
44
|
+
app_name: str
|
45
|
+
"""The name of the app."""
|
46
|
+
user_id: str
|
47
|
+
"""The id of the user."""
|
48
|
+
state: dict[str, Any] = Field(default_factory=dict)
|
49
|
+
"""The state of the session."""
|
50
|
+
events: list[Event] = Field(default_factory=list)
|
51
|
+
"""The events of the session, e.g. user input, model response, function
|
52
|
+
call/response, etc."""
|
53
|
+
last_update_time: float = 0.0
|
54
|
+
"""The last update time of the session."""
|
@@ -0,0 +1,71 @@
|
|
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 typing import Any
|
16
|
+
|
17
|
+
|
18
|
+
class State:
|
19
|
+
"""A state dict that maintain the current value and the pending-commit delta."""
|
20
|
+
|
21
|
+
APP_PREFIX = "app:"
|
22
|
+
USER_PREFIX = "user:"
|
23
|
+
TEMP_PREFIX = "temp:"
|
24
|
+
|
25
|
+
def __init__(self, value: dict[str, Any], delta: dict[str, Any]):
|
26
|
+
"""
|
27
|
+
Args:
|
28
|
+
value: The current value of the state dict.
|
29
|
+
delta: The delta change to the current value that hasn't been commited.
|
30
|
+
"""
|
31
|
+
self._value = value
|
32
|
+
self._delta = delta
|
33
|
+
|
34
|
+
def __getitem__(self, key: str) -> Any:
|
35
|
+
"""Returns the value of the state dict for the given key."""
|
36
|
+
if key in self._delta:
|
37
|
+
return self._delta[key]
|
38
|
+
return self._value[key]
|
39
|
+
|
40
|
+
def __setitem__(self, key: str, value: Any):
|
41
|
+
"""Sets the value of the state dict for the given key."""
|
42
|
+
# TODO: make new change only store in delta, so that self._value is only
|
43
|
+
# updated at the storage commit time.
|
44
|
+
self._value[key] = value
|
45
|
+
self._delta[key] = value
|
46
|
+
|
47
|
+
def __contains__(self, key: str) -> bool:
|
48
|
+
"""Whether the state dict contains the given key."""
|
49
|
+
return key in self._value or key in self._delta
|
50
|
+
|
51
|
+
def has_delta(self) -> bool:
|
52
|
+
"""Whether the state has pending detla."""
|
53
|
+
return bool(self._delta)
|
54
|
+
|
55
|
+
def get(self, key: str, default: Any = None) -> Any:
|
56
|
+
"""Returns the value of the state dict for the given key."""
|
57
|
+
if key not in self:
|
58
|
+
return default
|
59
|
+
return self[key]
|
60
|
+
|
61
|
+
def update(self, delta: dict[str, Any]):
|
62
|
+
"""Updates the state dict with the given delta."""
|
63
|
+
self._value.update(delta)
|
64
|
+
self._delta.update(delta)
|
65
|
+
|
66
|
+
def to_dict(self) -> dict[str, Any]:
|
67
|
+
"""Returns the state dict."""
|
68
|
+
result = {}
|
69
|
+
result.update(self._value)
|
70
|
+
result.update(self._delta)
|
71
|
+
return result
|
@@ -0,0 +1,356 @@
|
|
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
|
+
import logging
|
15
|
+
import re
|
16
|
+
import time
|
17
|
+
from typing import Any
|
18
|
+
from typing import Optional
|
19
|
+
|
20
|
+
from dateutil.parser import isoparse
|
21
|
+
from google import genai
|
22
|
+
from typing_extensions import override
|
23
|
+
|
24
|
+
from ..events.event import Event
|
25
|
+
from ..events.event_actions import EventActions
|
26
|
+
from .base_session_service import BaseSessionService
|
27
|
+
from .base_session_service import GetSessionConfig
|
28
|
+
from .base_session_service import ListEventsResponse
|
29
|
+
from .base_session_service import ListSessionsResponse
|
30
|
+
from .session import Session
|
31
|
+
|
32
|
+
logger = logging.getLogger(__name__)
|
33
|
+
|
34
|
+
|
35
|
+
class VertexAiSessionService(BaseSessionService):
|
36
|
+
"""Connects to the managed Vertex AI Session Service."""
|
37
|
+
|
38
|
+
def __init__(
|
39
|
+
self,
|
40
|
+
project: str = None,
|
41
|
+
location: str = None,
|
42
|
+
):
|
43
|
+
self.project = project
|
44
|
+
self.location = location
|
45
|
+
|
46
|
+
client = genai.Client(vertexai=True, project=project, location=location)
|
47
|
+
self.api_client = client._api_client
|
48
|
+
|
49
|
+
@override
|
50
|
+
def create_session(
|
51
|
+
self,
|
52
|
+
*,
|
53
|
+
app_name: str,
|
54
|
+
user_id: str,
|
55
|
+
state: Optional[dict[str, Any]] = None,
|
56
|
+
session_id: Optional[str] = None,
|
57
|
+
) -> Session:
|
58
|
+
reasoning_engine_id = _parse_reasoning_engine_id(app_name)
|
59
|
+
|
60
|
+
session_json_dict = {'user_id': user_id}
|
61
|
+
if state:
|
62
|
+
session_json_dict['session_state'] = state
|
63
|
+
|
64
|
+
api_response = self.api_client.request(
|
65
|
+
http_method='POST',
|
66
|
+
path=f'reasoningEngines/{reasoning_engine_id}/sessions',
|
67
|
+
request_dict=session_json_dict,
|
68
|
+
)
|
69
|
+
logger.info(f'Create Session response {api_response}')
|
70
|
+
|
71
|
+
session_id = api_response['name'].split('/')[-3]
|
72
|
+
operation_id = api_response['name'].split('/')[-1]
|
73
|
+
|
74
|
+
max_retry_attempt = 5
|
75
|
+
while max_retry_attempt >= 0:
|
76
|
+
lro_response = self.api_client.request(
|
77
|
+
http_method='GET',
|
78
|
+
path=f'operations/{operation_id}',
|
79
|
+
request_dict={},
|
80
|
+
)
|
81
|
+
|
82
|
+
if lro_response.get('done', None):
|
83
|
+
break
|
84
|
+
|
85
|
+
time.sleep(1)
|
86
|
+
max_retry_attempt -= 1
|
87
|
+
|
88
|
+
# Get session resource
|
89
|
+
get_session_api_response = self.api_client.request(
|
90
|
+
http_method='GET',
|
91
|
+
path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}',
|
92
|
+
request_dict={},
|
93
|
+
)
|
94
|
+
|
95
|
+
update_timestamp = isoparse(
|
96
|
+
get_session_api_response['updateTime']
|
97
|
+
).timestamp()
|
98
|
+
session = Session(
|
99
|
+
app_name=str(app_name),
|
100
|
+
user_id=str(user_id),
|
101
|
+
id=str(session_id),
|
102
|
+
state=get_session_api_response.get('sessionState', {}),
|
103
|
+
last_update_time=update_timestamp,
|
104
|
+
)
|
105
|
+
return session
|
106
|
+
|
107
|
+
@override
|
108
|
+
def get_session(
|
109
|
+
self,
|
110
|
+
*,
|
111
|
+
app_name: str,
|
112
|
+
user_id: str,
|
113
|
+
session_id: str,
|
114
|
+
config: Optional[GetSessionConfig] = None,
|
115
|
+
) -> Session:
|
116
|
+
reasoning_engine_id = _parse_reasoning_engine_id(app_name)
|
117
|
+
|
118
|
+
# Get session resource
|
119
|
+
get_session_api_response = self.api_client.request(
|
120
|
+
http_method='GET',
|
121
|
+
path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}',
|
122
|
+
request_dict={},
|
123
|
+
)
|
124
|
+
|
125
|
+
session_id = get_session_api_response['name'].split('/')[-1]
|
126
|
+
update_timestamp = isoparse(
|
127
|
+
get_session_api_response['updateTime']
|
128
|
+
).timestamp()
|
129
|
+
session = Session(
|
130
|
+
app_name=str(app_name),
|
131
|
+
user_id=str(user_id),
|
132
|
+
id=str(session_id),
|
133
|
+
state=get_session_api_response.get('sessionState', {}),
|
134
|
+
last_update_time=update_timestamp,
|
135
|
+
)
|
136
|
+
|
137
|
+
list_events_api_response = self.api_client.request(
|
138
|
+
http_method='GET',
|
139
|
+
path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}/events',
|
140
|
+
request_dict={},
|
141
|
+
)
|
142
|
+
|
143
|
+
# Handles empty response case
|
144
|
+
if list_events_api_response.get('httpHeaders', None):
|
145
|
+
return session
|
146
|
+
|
147
|
+
session.events = [
|
148
|
+
_from_api_event(event)
|
149
|
+
for event in list_events_api_response['sessionEvents']
|
150
|
+
]
|
151
|
+
session.events = [
|
152
|
+
event for event in session.events if event.timestamp <= update_timestamp
|
153
|
+
]
|
154
|
+
session.events.sort(key=lambda event: event.timestamp)
|
155
|
+
|
156
|
+
if config:
|
157
|
+
if config.num_recent_events:
|
158
|
+
session.events = session.events[-config.num_recent_events :]
|
159
|
+
elif config.after_timestamp:
|
160
|
+
i = len(session.events) - 1
|
161
|
+
while i >= 0:
|
162
|
+
if session.events[i].timestamp < config.after_timestamp:
|
163
|
+
break
|
164
|
+
i -= 1
|
165
|
+
if i >= 0:
|
166
|
+
session.events = session.events[i:]
|
167
|
+
|
168
|
+
return session
|
169
|
+
|
170
|
+
@override
|
171
|
+
def list_sessions(
|
172
|
+
self, *, app_name: str, user_id: str
|
173
|
+
) -> ListSessionsResponse:
|
174
|
+
reasoning_engine_id = _parse_reasoning_engine_id(app_name)
|
175
|
+
|
176
|
+
api_response = self.api_client.request(
|
177
|
+
http_method='GET',
|
178
|
+
path=f'reasoningEngines/{reasoning_engine_id}/sessions?filter=user_id={user_id}',
|
179
|
+
request_dict={},
|
180
|
+
)
|
181
|
+
|
182
|
+
# Handles empty response case
|
183
|
+
if api_response.get('httpHeaders', None):
|
184
|
+
return ListSessionsResponse()
|
185
|
+
|
186
|
+
sessions = []
|
187
|
+
for api_session in api_response['sessions']:
|
188
|
+
session = Session(
|
189
|
+
app_name=app_name,
|
190
|
+
user_id=user_id,
|
191
|
+
id=api_session['name'].split('/')[-1],
|
192
|
+
state={},
|
193
|
+
last_update_time=isoparse(api_session['updateTime']).timestamp(),
|
194
|
+
)
|
195
|
+
sessions.append(session)
|
196
|
+
return ListSessionsResponse(sessions=sessions)
|
197
|
+
|
198
|
+
def delete_session(
|
199
|
+
self, *, app_name: str, user_id: str, session_id: str
|
200
|
+
) -> None:
|
201
|
+
reasoning_engine_id = _parse_reasoning_engine_id(app_name)
|
202
|
+
self.api_client.request(
|
203
|
+
http_method='DELETE',
|
204
|
+
path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}',
|
205
|
+
request_dict={},
|
206
|
+
)
|
207
|
+
|
208
|
+
@override
|
209
|
+
def list_events(
|
210
|
+
self,
|
211
|
+
*,
|
212
|
+
app_name: str,
|
213
|
+
user_id: str,
|
214
|
+
session_id: str,
|
215
|
+
) -> ListEventsResponse:
|
216
|
+
reasoning_engine_id = _parse_reasoning_engine_id(app_name)
|
217
|
+
api_response = self.api_client.request(
|
218
|
+
http_method='GET',
|
219
|
+
path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}/events',
|
220
|
+
request_dict={},
|
221
|
+
)
|
222
|
+
|
223
|
+
logger.info(f'List events response {api_response}')
|
224
|
+
|
225
|
+
# Handles empty response case
|
226
|
+
if api_response.get('httpHeaders', None):
|
227
|
+
return ListEventsResponse()
|
228
|
+
|
229
|
+
session_events = api_response['sessionEvents']
|
230
|
+
|
231
|
+
return ListEventsResponse(
|
232
|
+
events=[_from_api_event(event) for event in session_events]
|
233
|
+
)
|
234
|
+
|
235
|
+
@override
|
236
|
+
def append_event(self, session: Session, event: Event) -> Event:
|
237
|
+
# Update the in-memory session.
|
238
|
+
super().append_event(session=session, event=event)
|
239
|
+
|
240
|
+
reasoning_engine_id = _parse_reasoning_engine_id(session.app_name)
|
241
|
+
self.api_client.request(
|
242
|
+
http_method='POST',
|
243
|
+
path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session.id}:appendEvent',
|
244
|
+
request_dict=_convert_event_to_json(event),
|
245
|
+
)
|
246
|
+
|
247
|
+
return event
|
248
|
+
|
249
|
+
|
250
|
+
def _convert_event_to_json(event: Event):
|
251
|
+
metadata_json = {
|
252
|
+
'partial': event.partial,
|
253
|
+
'turn_complete': event.turn_complete,
|
254
|
+
'interrupted': event.interrupted,
|
255
|
+
'branch': event.branch,
|
256
|
+
'long_running_tool_ids': (
|
257
|
+
list(event.long_running_tool_ids)
|
258
|
+
if event.long_running_tool_ids
|
259
|
+
else None
|
260
|
+
),
|
261
|
+
}
|
262
|
+
if event.grounding_metadata:
|
263
|
+
metadata_json['grounding_metadata'] = event.grounding_metadata.model_dump(
|
264
|
+
exclude_none=True
|
265
|
+
)
|
266
|
+
|
267
|
+
event_json = {
|
268
|
+
'author': event.author,
|
269
|
+
'invocation_id': event.invocation_id,
|
270
|
+
'timestamp': {
|
271
|
+
'seconds': int(event.timestamp),
|
272
|
+
'nanos': int(
|
273
|
+
(event.timestamp - int(event.timestamp)) * 1_000_000_000
|
274
|
+
),
|
275
|
+
},
|
276
|
+
'error_code': event.error_code,
|
277
|
+
'error_message': event.error_message,
|
278
|
+
'event_metadata': metadata_json,
|
279
|
+
}
|
280
|
+
|
281
|
+
if event.actions:
|
282
|
+
actions_json = {
|
283
|
+
'skip_summarization': event.actions.skip_summarization,
|
284
|
+
'state_delta': event.actions.state_delta,
|
285
|
+
'artifact_delta': event.actions.artifact_delta,
|
286
|
+
'transfer_agent': event.actions.transfer_to_agent,
|
287
|
+
'escalate': event.actions.escalate,
|
288
|
+
'requested_auth_configs': event.actions.requested_auth_configs,
|
289
|
+
}
|
290
|
+
event_json['actions'] = actions_json
|
291
|
+
if event.content:
|
292
|
+
event_json['content'] = event.content.model_dump(exclude_none=True)
|
293
|
+
if event.error_code:
|
294
|
+
event_json['error_code'] = event.error_code
|
295
|
+
if event.error_message:
|
296
|
+
event_json['error_message'] = event.error_message
|
297
|
+
return event_json
|
298
|
+
|
299
|
+
|
300
|
+
def _from_api_event(api_event: dict) -> Event:
|
301
|
+
event_actions = EventActions()
|
302
|
+
if api_event.get('actions', None):
|
303
|
+
event_actions = EventActions(
|
304
|
+
skip_summarization=api_event['actions'].get('skipSummarization', None),
|
305
|
+
state_delta=api_event['actions'].get('stateDelta', {}),
|
306
|
+
artifact_delta=api_event['actions'].get('artifactDelta', {}),
|
307
|
+
transfer_to_agent=api_event['actions'].get('transferAgent', None),
|
308
|
+
escalate=api_event['actions'].get('escalate', None),
|
309
|
+
requested_auth_configs=api_event['actions'].get(
|
310
|
+
'requestedAuthConfigs', {}
|
311
|
+
),
|
312
|
+
)
|
313
|
+
|
314
|
+
event = Event(
|
315
|
+
id=api_event['name'].split('/')[-1],
|
316
|
+
invocation_id=api_event['invocationId'],
|
317
|
+
author=api_event['author'],
|
318
|
+
actions=event_actions,
|
319
|
+
content=api_event.get('content', None),
|
320
|
+
timestamp=isoparse(api_event['timestamp']).timestamp(),
|
321
|
+
error_code=api_event.get('errorCode', None),
|
322
|
+
error_message=api_event.get('errorMessage', None),
|
323
|
+
)
|
324
|
+
|
325
|
+
if api_event.get('eventMetadata', None):
|
326
|
+
long_running_tool_ids_list = api_event['eventMetadata'].get(
|
327
|
+
'longRunningToolIds', None
|
328
|
+
)
|
329
|
+
event.partial = api_event['eventMetadata'].get('partial', None)
|
330
|
+
event.turn_complete = api_event['eventMetadata'].get('turnComplete', None)
|
331
|
+
event.interrupted = api_event['eventMetadata'].get('interrupted', None)
|
332
|
+
event.branch = api_event['eventMetadata'].get('branch', None)
|
333
|
+
event.grounding_metadata = api_event['eventMetadata'].get(
|
334
|
+
'groundingMetadata', None
|
335
|
+
)
|
336
|
+
event.long_running_tool_ids = (
|
337
|
+
set(long_running_tool_ids_list) if long_running_tool_ids_list else None
|
338
|
+
)
|
339
|
+
|
340
|
+
return event
|
341
|
+
|
342
|
+
|
343
|
+
def _parse_reasoning_engine_id(app_name: str):
|
344
|
+
if app_name.isdigit():
|
345
|
+
return app_name
|
346
|
+
|
347
|
+
pattern = r'^projects/([a-zA-Z0-9-_]+)/locations/([a-zA-Z0-9-_]+)/reasoningEngines/(\d+)$'
|
348
|
+
match = re.fullmatch(pattern, app_name)
|
349
|
+
|
350
|
+
if not bool(match):
|
351
|
+
raise ValueError(
|
352
|
+
f'App name {app_name} is not valid. It should either be the full'
|
353
|
+
' ReasoningEngine resource name, or the reasoning engine id.'
|
354
|
+
)
|
355
|
+
|
356
|
+
return match.groups()[-1]
|