Full Code of google/adk-go for AI

main d06c264127d8 cached
374 files
6.6 MB
1.7M tokens
12465 symbols
1 requests
Download .txt
Showing preview only (6,984K chars total). Download the full file or copy to clipboard to get everything.
Repository: google/adk-go
Branch: main
Commit: d06c264127d8
Files: 374
Total size: 6.6 MB

Directory structure:
gitextract_gssbqr3a/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── actions/
│   │   └── setup/
│   │       └── action.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── go.yml
│       └── nightly.yml
├── .gitignore
├── .golangci.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── agent/
│   ├── agent.go
│   ├── agent_test.go
│   ├── context.go
│   ├── doc.go
│   ├── llmagent/
│   │   ├── doc.go
│   │   ├── llmagent.go
│   │   ├── llmagent_saveoutput_test.go
│   │   ├── llmagent_test.go
│   │   ├── state_agent_test.go
│   │   └── testdata/
│   │       ├── TestFunctionTool.httprr
│   │       ├── TestLLMAgentStreamingModeSSE.httprr
│   │       ├── TestLLMAgent_healthy_backend.httprr
│   │       ├── TestToolCallback_after_callback_response_used.httprr
│   │       ├── TestToolCallback_after_callback_returned_when_used_with_before_callback.httprr
│   │       ├── TestToolCallback_before_callback_response_used.httprr
│   │       ├── TestToolCallback_both_callbacks_return_nil_actual_tool_is_executed.httprr
│   │       ├── TestToolCallback_extra_after_callback_skipped.httprr
│   │       └── TestToolCallback_extra_before_callback_skipped.httprr
│   ├── loader.go
│   ├── loader_test.go
│   ├── remoteagent/
│   │   ├── a2a_agent.go
│   │   ├── a2a_agent_run_processor.go
│   │   ├── a2a_agent_run_processor_test.go
│   │   ├── a2a_agent_test.go
│   │   ├── a2a_e2e_test.go
│   │   ├── doc.go
│   │   ├── testdata/
│   │   │   ├── TestA2ARemoteAgentStreamingGeminiError.httprr
│   │   │   ├── TestA2ARemoteAgentStreamingGeminiSuccess.httprr
│   │   │   ├── TestA2ASingleHopFinalResponse_llm_mid-response_error.httprr
│   │   │   └── TestA2ASingleHopFinalResponse_llm_mid-response_error_response.httprr
│   │   ├── utils.go
│   │   └── utils_test.go
│   ├── run_config.go
│   └── workflowagents/
│       ├── loopagent/
│       │   ├── agent.go
│       │   └── agent_test.go
│       ├── parallelagent/
│       │   ├── agent.go
│       │   ├── agent_test.go
│       │   └── testdata/
│       │       ├── TestParallelAgentWithTools_agent1.httprr
│       │       └── TestParallelAgentWithTools_agent2.httprr
│       └── sequentialagent/
│           ├── agent.go
│           └── agent_test.go
├── artifact/
│   ├── artifact_key_test.go
│   ├── gcsartifact/
│   │   ├── gcs_client.go
│   │   ├── gcs_test.go
│   │   └── service.go
│   ├── inmemory.go
│   ├── inmemory_test.go
│   ├── request_validation_test.go
│   └── service.go
├── cmd/
│   ├── adkgo/
│   │   ├── adkgo.go
│   │   └── internal/
│   │       ├── deploy/
│   │       │   ├── cloudrun/
│   │       │   │   └── cloudrun.go
│   │       │   └── deploy.go
│   │       └── root/
│   │           └── root.go
│   ├── internal/
│   │   └── adkcli/
│   │       └── main.go
│   └── launcher/
│       ├── console/
│       │   └── console.go
│       ├── full/
│       │   └── full.go
│       ├── internal/
│       │   └── telemetry/
│       │       └── telemetry.go
│       ├── launcher.go
│       ├── prod/
│       │   └── prod.go
│       ├── universal/
│       │   └── universal.go
│       └── web/
│           ├── a2a/
│           │   ├── a2a.go
│           │   └── a2a_test.go
│           ├── api/
│           │   └── api.go
│           ├── web.go
│           └── webui/
│               ├── distr/
│               │   ├── assets/
│               │   │   ├── audio-processor.js
│               │   │   └── config/
│               │   │       └── runtime-config.json
│               │   ├── chunk-2FK4DXD6.js
│               │   ├── chunk-4ZK7FQPX.js
│               │   ├── chunk-7TJPJFPQ.js
│               │   ├── chunk-ABUNXR7C.js
│               │   ├── chunk-BWOBGCSA.js
│               │   ├── chunk-C7MGZAFQ.js
│               │   ├── chunk-CZPJTTNC.js
│               │   ├── chunk-GLGRLUIJ.js
│               │   ├── chunk-JFJZPIJV.js
│               │   ├── chunk-JOTH6MSK.js
│               │   ├── chunk-KPALJACC.js
│               │   ├── chunk-P66EZ4FO.js
│               │   ├── chunk-POBF2O3Z.js
│               │   ├── chunk-QWN7CXIU.js
│               │   ├── chunk-QZL3KUOO.js
│               │   ├── chunk-R2V2IE5A.js
│               │   ├── chunk-W7GRJBO5.js
│               │   ├── chunk-YQ6GIDJJ.js
│               │   ├── index.html
│               │   ├── main-ORIYWHAC.js
│               │   ├── polyfills-5CFQRCPP.js
│               │   └── styles-YY6V3TJU.css
│               └── webui.go
├── examples/
│   ├── README.md
│   ├── a2a/
│   │   └── main.go
│   ├── mcp/
│   │   └── main.go
│   ├── quickstart/
│   │   └── main.go
│   ├── rest/
│   │   └── main.go
│   ├── telemetry/
│   │   └── main.go
│   ├── toolconfirmation/
│   │   └── main.go
│   ├── tools/
│   │   ├── loadartifacts/
│   │   │   └── main.go
│   │   ├── loadmemory/
│   │   │   └── main.go
│   │   └── multipletools/
│   │       └── main.go
│   ├── vertexai/
│   │   ├── agent.go
│   │   ├── imagegenerator/
│   │   │   └── main.go
│   │   └── vertexengine/
│   │       └── create_engine.go
│   ├── web/
│   │   ├── agents/
│   │   │   ├── image_generator.go
│   │   │   └── llmauditor.go
│   │   └── main.go
│   └── workflowagents/
│       ├── loop/
│       │   └── main.go
│       ├── parallel/
│       │   └── main.go
│       ├── sequential/
│       │   └── main.go
│       └── sequentialCode/
│           └── main.go
├── go.mod
├── go.sum
├── internal/
│   ├── agent/
│   │   ├── parentmap/
│   │   │   ├── map.go
│   │   │   └── map_test.go
│   │   ├── remoteagent/
│   │   │   └── a2a_config.go
│   │   ├── runconfig/
│   │   │   └── run_config.go
│   │   └── state.go
│   ├── artifact/
│   │   ├── artifacts.go
│   │   ├── artifacts_test.go
│   │   └── tests/
│   │       └── service_suite.go
│   ├── cli/
│   │   └── util/
│   │       ├── doc.go
│   │       ├── flagset_helpers.go
│   │       ├── oscmd.go
│   │       └── text_helpers.go
│   ├── configurable/
│   │   ├── configurable.go
│   │   ├── configurable_utils.go
│   │   └── conformance/
│   │       ├── callbacks.go
│   │       ├── functions.go
│   │       ├── loader.go
│   │       └── replayplugin/
│   │           ├── invocation_replay_state.go
│   │           ├── recording/
│   │           │   └── recording.go
│   │           ├── replay_plugin.go
│   │           ├── replay_plugin_test.go
│   │           └── yaml_utils.go
│   ├── context/
│   │   ├── callback_context.go
│   │   ├── context_test.go
│   │   ├── invocation_context.go
│   │   └── readonly_context.go
│   ├── converters/
│   │   └── map_structure.go
│   ├── httprr/
│   │   ├── LICENSE
│   │   ├── rr.go
│   │   └── rr_test.go
│   ├── llminternal/
│   │   ├── agent.go
│   │   ├── agent_transfer.go
│   │   ├── agent_transfer_test.go
│   │   ├── base_flow.go
│   │   ├── base_flow_telemetry_test.go
│   │   ├── base_flow_test.go
│   │   ├── basic_processor.go
│   │   ├── clone_test.go
│   │   ├── contents_processor.go
│   │   ├── contents_processor_test.go
│   │   ├── converters/
│   │   │   └── converters.go
│   │   ├── file_uploads_processor.go
│   │   ├── functions.go
│   │   ├── functions_test.go
│   │   ├── googlellm/
│   │   │   ├── variant.go
│   │   │   └── variant_test.go
│   │   ├── handle_function_calls_async_test.go
│   │   ├── helpers_test.go
│   │   ├── identity_request_processor.go
│   │   ├── identity_request_processor_test.go
│   │   ├── instruction_processor.go
│   │   ├── instruction_processor_test.go
│   │   ├── other_processors.go
│   │   ├── outputschema_processor.go
│   │   ├── outputschema_processor_test.go
│   │   ├── parallel_function_call_test.go
│   │   ├── request_confirmation_processor.go
│   │   ├── request_confirmation_processor_test.go
│   │   ├── stream_aggregator.go
│   │   ├── stream_aggregator_test.go
│   │   ├── testdata/
│   │   │   ├── TestParallelFunctionCalls_test_parallel_function_calls_gemini-2.5-flash.httprr
│   │   │   ├── TestParallelFunctionCalls_test_parallel_function_calls_gemini-3-flash-preview.httprr
│   │   │   └── TestParallelFunctionCalls_test_parallel_function_calls_gemini-3.1-pro-preview.httprr
│   │   └── tools_processor.go
│   ├── memory/
│   │   ├── memory.go
│   │   └── memory_test.go
│   ├── plugininternal/
│   │   ├── plugin_manager.go
│   │   └── plugincontext/
│   │       └── context.go
│   ├── sessionutils/
│   │   └── utils.go
│   ├── style_test.go
│   ├── telemetry/
│   │   ├── converters.go
│   │   ├── converters_test.go
│   │   ├── logger.go
│   │   ├── logger_test.go
│   │   ├── telemetry.go
│   │   └── telemetry_test.go
│   ├── testutil/
│   │   ├── genai.go
│   │   └── test_agent_runner.go
│   ├── toolinternal/
│   │   ├── context.go
│   │   ├── context_test.go
│   │   ├── tool.go
│   │   └── toolutils/
│   │       └── toolutils.go
│   ├── typeutil/
│   │   └── convert.go
│   ├── utils/
│   │   ├── schema_test.go
│   │   ├── schema_utils.go
│   │   ├── utils.go
│   │   └── utils_test.go
│   └── version/
│       └── version.go
├── memory/
│   ├── inmemory.go
│   ├── inmemory_test.go
│   └── service.go
├── model/
│   ├── apigee/
│   │   ├── apigee.go
│   │   └── apigee_test.go
│   ├── gemini/
│   │   ├── gemini.go
│   │   ├── gemini_test.go
│   │   └── testdata/
│   │       ├── TestModel_GenerateStream_ok.httprr
│   │       ├── TestModel_Generate_ok.httprr
│   │       ├── TestModel_TrackingHeaders_verifies_headers_are_set_vertex_disabled.httprr
│   │       └── TestModel_TrackingHeaders_verifies_headers_are_set_vertex_enabled.httprr
│   ├── llm.go
│   └── llm_test.go
├── plugin/
│   ├── functioncallmodifier/
│   │   ├── integration_test.go
│   │   ├── plugin.go
│   │   ├── plugin_test.go
│   │   └── testdata/
│   │       ├── TestPluginCallbackIntegration_agent_tool_default_schema.httprr
│   │       ├── TestPluginCallbackIntegration_no_relevant_tools.httprr
│   │       └── TestPluginCallbackIntegration_transfer_to_agent_tool.httprr
│   ├── loggingplugin/
│   │   └── logging_plugin.go
│   ├── plugin.go
│   ├── plugin_manager_test.go
│   ├── plugin_test.go
│   └── retryandreflect/
│       ├── exceeded.md
│       ├── plugin.go
│       ├── plugin_test.go
│       └── reflection.md
├── runner/
│   ├── runner.go
│   └── runner_test.go
├── scripts/
│   └── adk-web/
│       ├── Dockerfile
│       └── update-adk-web.sh
├── server/
│   ├── adka2a/
│   │   ├── agent_card.go
│   │   ├── agent_card_test.go
│   │   ├── doc.go
│   │   ├── events.go
│   │   ├── events_test.go
│   │   ├── executor.go
│   │   ├── executor_context.go
│   │   ├── executor_plugin.go
│   │   ├── executor_test.go
│   │   ├── input_required.go
│   │   ├── metadata.go
│   │   ├── metadata_test.go
│   │   ├── parts.go
│   │   ├── parts_test.go
│   │   ├── processor.go
│   │   ├── processor_test.go
│   │   ├── task_artifact.go
│   │   └── utils.go
│   ├── adkrest/
│   │   ├── controllers/
│   │   │   ├── apps.go
│   │   │   ├── artifacts.go
│   │   │   ├── debug.go
│   │   │   ├── debug_test.go
│   │   │   ├── errors.go
│   │   │   ├── handlers.go
│   │   │   ├── runtime.go
│   │   │   ├── runtime_test.go
│   │   │   ├── sessions.go
│   │   │   └── sessions_test.go
│   │   ├── handler.go
│   │   └── internal/
│   │       ├── fakes/
│   │       │   └── testsessionservice.go
│   │       ├── models/
│   │       │   ├── event.go
│   │       │   ├── models.go
│   │       │   ├── runtime.go
│   │       │   └── session.go
│   │       ├── routers/
│   │       │   ├── apps.go
│   │       │   ├── artifacts.go
│   │       │   ├── debug.go
│   │       │   ├── eval.go
│   │       │   ├── routers.go
│   │       │   ├── runtime.go
│   │       │   └── sessions.go
│   │       └── services/
│   │           ├── agentgraphgenerator.go
│   │           ├── agentgraphgenerator_test.go
│   │           ├── debugtelemetry.go
│   │           ├── debugtelemetry_test.go
│   │           └── doc.go
│   └── doc.go
├── session/
│   ├── database/
│   │   ├── gorm_datatypes.go
│   │   ├── service.go
│   │   ├── service_test.go
│   │   ├── session.go
│   │   └── storage_session.go
│   ├── doc.go
│   ├── inmemory.go
│   ├── inmemory_test.go
│   ├── service.go
│   ├── session.go
│   └── vertexai/
│       ├── service_test.go
│       ├── session.go
│       ├── testdata/
│       │   ├── app_state_is_shared.replay
│       │   ├── append_event_to_the_session_and_overwrite_in_storage.replay
│       │   ├── append_event_to_the_session_with_events_and_overwrite_in_storage.replay
│       │   ├── append_event_when_session_not_found_should_fail.replay
│       │   ├── append_event_with_all_fields.replay
│       │   ├── append_event_with_bytes_content.replay
│       │   ├── empty_list_for_non-existent_user.replay
│       │   ├── error_when_not_found.replay
│       │   ├── full_key.replay
│       │   ├── generated_session_id.replay
│       │   ├── get_session_respects_user_id.replay
│       │   ├── list_all_users_for_app.replay
│       │   ├── list_for_user1.replay
│       │   ├── list_for_user2.replay
│       │   ├── missing_author.replay
│       │   ├── missing_invocation_id.replay
│       │   ├── missing_session_id.replay
│       │   ├── nil_event.replay
│       │   ├── ok.replay
│       │   ├── partial_events_are_not_persisted.replay
│       │   ├── session_state_is_not_shared.replay
│       │   ├── temp_state_is_not_persisted.replay
│       │   ├── user_state_is_user_specific.replay
│       │   ├── when_already_exists__it_fails.replay
│       │   ├── with_config_after_timestamp.replay
│       │   ├── with_config_combined_filters.replay
│       │   ├── with_config_no_config_returns_all_events.replay
│       │   └── with_config_num_recent_events.replay
│       ├── vertexai.go
│       ├── vertexai_client.go
│       └── vertexai_test.go
├── telemetry/
│   ├── config.go
│   ├── setup_otel.go
│   ├── telemetry.go
│   └── telemetry_test.go
├── tool/
│   ├── agenttool/
│   │   ├── agent_tool.go
│   │   └── agent_tool_test.go
│   ├── exampletool/
│   │   ├── tool.go
│   │   └── tool_test.go
│   ├── exitlooptool/
│   │   ├── tool.go
│   │   └── tool_test.go
│   ├── functiontool/
│   │   ├── function.go
│   │   ├── function_test.go
│   │   ├── long_running_function_test.go
│   │   └── testdata/
│   │       └── TestFunctionTool_Simple.httprr
│   ├── geminitool/
│   │   ├── google_search.go
│   │   ├── tool.go
│   │   └── tool_test.go
│   ├── loadartifactstool/
│   │   ├── load_artifacts_tool.go
│   │   └── load_artifacts_tool_test.go
│   ├── loadmemorytool/
│   │   ├── tool.go
│   │   └── tool_test.go
│   ├── mcptoolset/
│   │   ├── client.go
│   │   ├── set.go
│   │   ├── set_test.go
│   │   ├── testdata/
│   │   │   ├── TestMCPToolSet.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Conditional_Confirmation_Not_Required.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Conditional_Confirmation_Not_Required_For_This_Tool.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Conditional_Confirmation_Required.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Conditional_Confirmation_Required_For_This_Tool.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Conditional_Confirmation_Required_and_is_confirmed.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Conditional_Confirmation_Required_and_is_rejected.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Confirmation_Required.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Confirmation_Required_and_is_confirmed.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Confirmation_Required_and_is_rejected.httprr
│   │   │   └── TestMCPToolSetConfirmation_No_Confirmation_Required.httprr
│   │   └── tool.go
│   ├── preloadmemorytool/
│   │   ├── tool.go
│   │   └── tool_test.go
│   ├── tool.go
│   ├── tool_test.go
│   └── toolconfirmation/
│       ├── tool_confirmation.go
│       └── tool_confirmation_test.go
└── util/
    └── instructionutil/
        └── instruction.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''

---

** Please make sure you read the contribution guide and file the issues in the right place. **
[Contribution guide.](https://google.github.io/adk-docs/contributing-guide/)

## 🔴 Required Information
*Please ensure all items in this section are completed to allow for efficient
triaging. If an item is not applicable to you - please mark it as N/A*

**Describe the Bug:**
A clear and concise description of what the bug is.

**Steps to Reproduce:**
Please provide a numbered list of steps to reproduce the behavior:
1. Install '...'
2. Run '....'
3. Open '....'
4. Provide error or stacktrace

**Expected Behavior:**
A clear and concise description of what you expected to happen.

**Observed Behavior:**
What actually happened? Include error messages or crash stack traces here.

**Environment Details:**

 - ADK Library Version:
 - OS: [e.g., macOS, Linux, Windows]
 - Go Version:

**Model Information:**
 - Which model is being used: (e.g., gemini-2.5-pro)

---

## 🟡 Optional Information
*Providing this information greatly speeds up the resolution process.*

**Regression:**
Did this work in a previous version of ADK? (Yes/No) If so, which one?

**Logs:**
Please attach relevant logs. Wrap them in code blocks (```) or attach a
text file.
```text
// Paste logs here
```

**Screenshots / Video:**
If applicable, add screenshots or screen recordings to help explain
your problem.

**Additional Context:**
Add any other context about the problem here.

**Minimal Reproduction Code:**
Please provide a code snippet or a link to a Gist/repo that isolates the issue.
```go
// Code snippet here
```

**How often has this issue occurred?:**

 - Always (100%)
 - Often (50%+)
 - Intermittently (<50%)
 - Once / Rare


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''

---

** Please make sure you read the contribution guide and file the issues in the right place. **
[Contribution guide.](https://google.github.io/adk-docs/contributing-guide/)

## 🔴 Required Information
*Please ensure all items in this section are completed to allow for efficient
triaging. If an item is not applicable to you - please mark it as N/A*

### Is your feature request related to a specific problem?
Please describe the problem you are trying to solve. (Ex: "I'm always frustrated
when I have to manually handle X...")

### Proposed Solution
A clear and concise description of the feature or API change you want.
Be specific about input/outputs if this involves an API change.

### Impact on your work
How does this feature impact your work and what are you trying to achieve?
If this is critical for you, tell us if there is a timeline by when you need
this feature.

---

## 🟡 Recommended Information

### Alternatives Considered
A clear and concise description of any alternative solutions or workarounds
you've considered.

### Willingness to contribute
Are you interested in implementing this feature yourself or submitting a PR?

### Proposed API / Implementation
If you have ideas on how this should look in code, please share a
pseudo-code example.

### Additional Context
Add any other context or screenshots about the feature request.


================================================
FILE: .github/actions/setup/action.yml
================================================
name: Setup
description: Setup the environment

outputs:
  go-version:
    description: 'Go version'
    value: ${{ steps.setup-go.outputs.go-version }}

runs:
  using: 'composite'
  steps:
    - name: Set up Go
      id: setup-go
      uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
      with:
        go-version-file: 'go.mod'
        cache: false # wrapper for actions/cache that doesn't support all functionality

    - name: Load Go cache
      uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
      with:
        path: |
          ~/.cache/go-build
          ~/go/pkg/mod
        key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.mod', '**/go.sum') }}
        restore-keys: ${{ runner.os }}-go-build-


================================================
FILE: .github/pull_request_template.md
================================================
**Please ensure you have read the [contribution guide](./CONTRIBUTING.md) before creating a pull request.**

### Link to Issue or Description of Change

**1. Link to an existing issue (if applicable):**

- Closes: #_issue_number_
- Related: #_issue_number_

**2. Or, if no issue exists, describe the change:**

_If applicable, please follow the issue templates to provide as much detail as
possible._

**Problem:**
_A clear and concise description of what the problem is._

**Solution:**
_A clear and concise description of what you want to happen and why you choose
this solution._

### Testing Plan

_Please describe the tests that you ran to verify your changes. This is required
for all PRs that are not small documentation or typo fixes._

**Unit Tests:**

- [ ] I have added or updated unit tests for my change.
- [ ] All unit tests pass locally.

_Please include a summary of passed go test results._

**Manual End-to-End (E2E) Tests:**

_Please provide instructions on how to manually test your changes, including any
necessary setup or configuration. Please provide logs or screenshots to help
reviewers better understand the fix._

### Checklist

- [ ] I have read the [CONTRIBUTING.md](./CONTRIBUTING.md) document.
- [ ] I have performed a self-review of my own code.
- [ ] I have commented my code, particularly in hard-to-understand areas.
- [ ] I have added tests that prove my fix is effective or that my feature works.
- [ ] New and existing unit tests pass locally with my changes.
- [ ] I have manually tested my changes end-to-end.
- [ ] Any dependent changes have been merged and published in downstream modules.

### Additional context

_Add any other context or screenshots about the feature request here._



================================================
FILE: .github/workflows/go.yml
================================================
# This workflow will build a golang project
# For more information see: 
# - https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
# - https://golangci-lint.run/usage/configuration/

name: Go

on:
  push:
    branches: [ "main" ]

  pull_request:
    branches: [ "main" ]

  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
    
    - name: Setup
      uses: ./.github/actions/setup

    - name: Tidy
      run: go mod tidy -diff
      
    - name: Build
      run: go build -mod=readonly -v ./...

    - name: Test
      run: go test -race -mod=readonly -v -count=1 -shuffle=on ./...
  
  lint:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
    
    - name: Setup
      uses: ./.github/actions/setup
    
    - name: Lint
      uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20  # v9.2.0
      with:
        install-mode: goinstall
        version: 5256574b81bcedfbcae9099f745f6aee9335da10 # v2.3.1


================================================
FILE: .github/workflows/nightly.yml
================================================
name: Nightly

on:
  schedule:
    - cron: '0 2 * * *'  # 2 AM UTC daily

  workflow_dispatch:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
    
    - name: Setup
      uses: ./.github/actions/setup

    - name: Nightly Test
      run: go test -race -mod=readonly -v -count=1 -shuffle=on ./...

  vulncheck:
    runs-on: ubuntu-latest
    steps:
    - name: Run govulncheck
      uses: golang/govulncheck-action@b625fbe08f3bccbe446d94fbf87fcc875a4f50ee # v1.0.4
      with:
           go-version-file: go.mod
           repo-checkout: true

================================================
FILE: .gitignore
================================================
# .gitignore is restricted to the artifacts produced by go build and test.
# for personal setup you can use personal .gitignore: `git config --global core.excludesfile ~/.gitignore`

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Code coverage profiles and other test artifacts
*.out
coverage.*
*.coverprofile
profile.cov

# Go workspace file
go.work
go.work.sum


================================================
FILE: .golangci.yml
================================================
version: "2"

formatters:
  enable:
    - goimports
    - gofumpt

  settings:
    goimports:
      local-prefixes:
        - google.golang.org/adk
    gofumpt:
      extra-rules: true
      module-path: google.golang.org/adk

linters:
  enable:
    - goheader
  
  settings:
    
    goheader:
      values:
        const:
          COMPANY: Google LLC
        regexp:
          YEAR: 20\d\d
      template: |-
        Copyright {{ YEAR }} {{ COMPANY }}
        
        Licensed under the Apache License, Version 2.0 (the "License");
        you may not use this file except in compliance with the License.
        You may obtain a copy of the License at
        
            http://www.apache.org/licenses/LICENSE-2.0
        
        Unless required by applicable law or agreed to in writing, software
        distributed under the License is distributed on an "AS IS" BASIS,
        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        See the License for the specific language governing permissions and
        limitations under the License.
    
    staticcheck:
      checks:
        # The default config:
        - all
        - -ST1000
        - -ST1003
        - -ST1016 
        - -ST1020
        - -ST1021
        - -ST1022
        # Changes to the default config:
        - -QF1001 # Exclude "Apply De Morgan's law"
        - -QF1008 # Exclude "Omit embedded fields from selector expression"
  
  exclusions:
    rules:
      - path: 'internal/httprr/.*'
        linters:
          - goheader
          - errcheck
          - staticcheck


================================================
FILE: CONTRIBUTING.md
================================================
# How to contribute

We'd love to accept your patches and contributions to this project.

-   [How to contribute](#how-to-contribute)
-   [Before you begin](#before-you-begin)
    -   [Sign our Contributor License Agreement](#sign-our-contributor-license-agreement)
    -   [Review our community guidelines](#review-our-community-guidelines)
    -   [Code reviews](#code-reviews)
-   [Contribution workflow](#contribution-workflow)
    -   [Finding Issues to Work On](#finding-issues-to-work-on)
    -   [Requirement for PRs](#requirement-for-prs)
    -   [Large or Complex Changes](#large-or-complex-changes)
    -   [Testing Requirements](#testing-requirements)
    -   [Unit Tests](#unit-tests)
    -   [Manual End-to-End (E2E) Tests](#manual-end-to-end-e2e-tests)
    -   [Documentation](#documentation)
    -   [Alignment with adk-python](#alignment-with-adk-python)

## Before you begin

### Sign our Contributor License Agreement

All submissions to this project need to follow Google’s [Contributor
License Agreement (CLA)](https://cla.developers.google.com/about), which
covers any original work of authorship included in the submission. This
doesn't prohibit the use of coding assistance tools, including tool-,
AI-, or machine-generated code, as long as these submissions abide by the
CLA's requirements.

You (or your employer) retain the copyright to your contribution; this simply
gives us permission to use and redistribute your contributions as part of the
project.

If you or your current employer have already signed the Google CLA (even if it
was for a different project), you probably don't need to do it again.

Visit <https://cla.developers.google.com/> to see your current agreements or to
sign a new one.

### Review our community guidelines

This project follows
[Google's Open Source Community Guidelines](https://opensource.google/conduct/).

### Code reviews

All submissions, including submissions by project members, require review. We
use GitHub pull requests for this purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on using pull requests.

## Contribution workflow

### Finding Issues to Work On

-   Browse issues labeled **`good first issue`** (newcomer-friendly) or **`help
    wanted`** (general contributions).
-   For other issues, please kindly ask before contributing to avoid
    duplication.

### Requirement for PRs

-   Code must follow [Google Go Style Guide](https://google.github.io/styleguide/go/index).
-   All PRs, other than small documentation or typo fixes, should have an Issue
    associated. If a relevant issue doesn't exist, please create one first or
    you may instead describe the bug or feature directly within the PR
    description, following the structure of our issue templates.
-   Small, focused PRs. Keep changes minimal—one concern per PR.
-   For bug fixes or features, please provide logs or screenshots after the fix
    is applied to help reviewers better understand the fix.
-   Please include a `testing plan` section in your PR to talk about how you
    will test. This will save time for PR review. See `Testing Requirements`
    section for more details.

### Large or Complex Changes

For substantial features or architectural revisions:

-   Open an Issue First: Outline your proposal, including design considerations
    and impact.
-   Gather Feedback: Discuss with maintainers and the community to ensure
    alignment and avoid duplicate work.

### Testing Requirements

To maintain code quality and prevent regressions, all code changes must include
comprehensive tests and verifiable end-to-end (E2E) evidence.

#### Unit Tests

Please add or update unit tests for your change.

Requirements for unit tests:

-   Cover new features, edge cases, error conditions, and typical
    use cases.
-   Fast and isolated.
-   Written clearly with descriptive names.
-   Free of external dependencies (use mocks or fixtures as needed).
-   Aim for high readability and maintainability; include comments for complex
    scenarios.

#### Manual End-to-End (E2E) Tests

Manual E2E tests ensure integrated flows work as intended. Your tests should
cover all scenarios. Sometimes, it's also good to ensure relevant functionality
is not impacted.

Depending on your change:

-   **ADK Web:**

    -   Capture and attach relevant screenshots demonstrating the UI/UX changes
        or outputs.
    -   Label screenshots clearly in your PR description.

-   **Runner:**

    -   Provide testing setup. For example, the agent definition, and the
        runner setup.
    -   Include the command used and console output showing test results.
    -   Highlight sections of the log that directly relate to your change.

# ADK Web

## Updating ADK web version to latest

-   Run `./scripts/adk-web/update-adk-web.sh` to update the web UI to the latest version from [GitHub](https://github.com/google/adk-web).
-   Run `docker run -it adk-web-builder:latest sh -c "<COMMAND>"` to start the container and debug the build, e.g.:
    -   `docker run -it adk-web-builder:latest sh -c "ls -alh dist/agent_framework_web/browser"` to view the built files.
    -   `docker run -it adk-web-builder:latest sh -c "npm run build"` to debug the build output.

### Documentation

For any changes that impact user-facing documentation (guides, API reference,
tutorials), please open a PR in the
[adk-docs](https://github.com/google/adk-docs) repository to update the relevant
parts before or alongside your code PR.

### Alignment with adk-python
We lean on [adk-python](https://github.com/google/adk-python) for being the source of truth and one should refer to adk-python for validation.


================================================
FILE: LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2025 Google LLC

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
# Agent Development Kit (ADK) for Go

[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
[![Go Doc](https://img.shields.io/badge/Go%20Package-Doc-blue.svg)](https://pkg.go.dev/google.golang.org/adk)
[![Nightly Check](https://github.com/google/adk-go/actions/workflows/nightly.yml/badge.svg)](https://github.com/google/adk-go/actions/workflows/nightly.yml)
[![r/agentdevelopmentkit](https://img.shields.io/badge/Reddit-r%2Fagentdevelopmentkit-FF4500?style=flat&logo=reddit&logoColor=white)](https://www.reddit.com/r/agentdevelopmentkit/)
[![View Code Wiki](https://www.gstatic.com/_/boq-sdlc-agents-ui/_/r/YUi5dj2UWvE.svg)](https://codewiki.google/github.com/google/adk-go)

<html>
    <h2 align="center">
      <img src="https://raw.githubusercontent.com/google/adk-python/main/assets/agent-development-kit.png" width="256"/>
    </h2>
    <h3 align="center">
      An open-source, code-first Go toolkit for building, evaluating, and deploying sophisticated AI agents with flexibility and control.
    </h3>
    <h3 align="center">
      Important Links:
      <a href="https://google.github.io/adk-docs/">Docs</a> &
      <a href="https://github.com/google/adk-go/tree/main/examples">Samples</a> &
      <a href="https://github.com/google/adk-python">Python ADK</a> &
      <a href="https://github.com/google/adk-java">Java ADK</a> & 
      <a href="https://github.com/google/adk-web">ADK Web</a>.
    </h3>
</html>

Agent Development Kit (ADK) is a flexible and modular framework that applies software development principles to AI agent creation. It is designed to simplify building, deploying, and orchestrating agent workflows, from simple tasks to complex systems. While optimized for Gemini, ADK is model-agnostic, deployment-agnostic, and compatible with other frameworks.

This Go version of ADK is ideal for developers building cloud-native agent applications, leveraging Go's strengths in concurrency and performance.

---

## ✨ Key Features

*   **Idiomatic Go:** Designed to feel natural and leverage the power of Go.
*   **Rich Tool Ecosystem:** Utilize pre-built tools, custom functions, or integrate existing tools to give agents diverse capabilities.
*   **Code-First Development:** Define agent logic, tools, and orchestration directly in Go for ultimate flexibility, testability, and versioning.
*   **Modular Multi-Agent Systems:** Design scalable applications by composing multiple specialized agents.
*   **Deploy Anywhere:** Easily containerize and deploy agents, with strong support for cloud-native environments like Google Cloud Run.

## 🚀 Installation

To add ADK Go to your project, run:

```bash
go get google.golang.org/adk
```

## 📄 License

This project is licensed under the Apache 2.0 License - see the
[LICENSE](LICENSE) file for details.

The exception is internal/httprr - see its [LICENSE file](internal/httprr/LICENSE).


================================================
FILE: agent/agent.go
================================================
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"context"
	"fmt"
	"iter"

	"go.opentelemetry.io/otel/trace"
	"google.golang.org/genai"

	"google.golang.org/adk/artifact"
	agentinternal "google.golang.org/adk/internal/agent"
	"google.golang.org/adk/internal/plugininternal/plugincontext"
	"google.golang.org/adk/internal/telemetry"
	"google.golang.org/adk/memory"
	"google.golang.org/adk/model"
	"google.golang.org/adk/session"
)

// Agent is the base interface which all agents must implement.
//
// Agents are created with ADK constructors to ensure correct
// init & configuration.
// The constructors are available in this package and its subpackages.
// For example: llmagent.New, workflow agents, remote agent or
// agent.New.
// NOTE: in future releases we will allow just implementing this interface.
// For now agent.New is a correct solution to create custom agents.
type Agent interface {
	Name() string
	Description() string
	Run(InvocationContext) iter.Seq2[*session.Event, error]
	SubAgents() []Agent

	internal() *agent
}

// New creates an Agent with a custom logic defined by Run function.
func New(cfg Config) (Agent, error) {
	subAgentSet := make(map[Agent]bool)
	for _, subAgent := range cfg.SubAgents {
		if _, ok := subAgentSet[subAgent]; ok {
			return nil, fmt.Errorf("error creating agent: subagent %q appears multiple times in subAgents", subAgent.Name())
		}
		subAgentSet[subAgent] = true
	}
	return &agent{
		name:                 cfg.Name,
		description:          cfg.Description,
		subAgents:            cfg.SubAgents,
		beforeAgentCallbacks: cfg.BeforeAgentCallbacks,
		run:                  cfg.Run,
		afterAgentCallbacks:  cfg.AfterAgentCallbacks,
		State: agentinternal.State{
			AgentType: agentinternal.TypeCustomAgent,
		},
	}, nil
}

// Config is the configuration for creating a new Agent.
type Config struct {
	// Name must be a non-empty string, unique within the agent tree.
	// Agent name cannot be "user", since it's reserved for end-user's input.
	Name string
	// Description of the agent's capability.
	//
	// LLM uses this to determine whether to delegate control to the agent.
	// One-line description is enough and preferred.
	Description string
	// SubAgents are the child agents that this agent can delegate tasks to.
	// ADK will automatically set a parent of each sub-agent to this agent to
	// allow agent transferring across the tree.
	SubAgents []Agent

	// BeforeAgentCallbacks is a list of callbacks that are called sequentially
	// before the agent starts its run.
	//
	// If any callback returns non-nil content or error, then the agent run and
	// the remaining callbacks will be skipped, and a new event will be created
	// from the content or error of that callback.
	BeforeAgentCallbacks []BeforeAgentCallback
	// Run is the function that defines the agent's behavior.
	Run func(InvocationContext) iter.Seq2[*session.Event, error]
	// AfterAgentCallbacks is a list of callbacks that are called sequentially
	// after the agent has completed its run.
	//
	// If any callback returns non-nil content or error, then a new event will be
	// created from the content or error of that callback and the remaining
	// callbacks will be skipped.
	AfterAgentCallbacks []AfterAgentCallback
}

// Artifacts interface provides methods to work with artifacts of the current
// session.
type Artifacts interface {
	Save(ctx context.Context, name string, data *genai.Part) (*artifact.SaveResponse, error)
	List(context.Context) (*artifact.ListResponse, error)
	Load(ctx context.Context, name string) (*artifact.LoadResponse, error)
	LoadVersion(ctx context.Context, name string, version int) (*artifact.LoadResponse, error)
}

// Memory interface provides methods to access agent memory across the
// sessions of the current user_id.
type Memory interface {
	AddSessionToMemory(context.Context, session.Session) error
	SearchMemory(ctx context.Context, query string) (*memory.SearchResponse, error)
}

// BeforeAgentCallback is a function that is called before the agent starts
// its run.
// If it returns non-nil content or error, the agent run will be skipped and a
// new event will be created.
type BeforeAgentCallback func(CallbackContext) (*genai.Content, error)

// AfterAgentCallback is a function that is called after the agent has completed
// its run.
// If it returns non-nil content or error, a new event will be created.
//
// The callback will be skipped also if EndInvocation was called before or
// BeforeAgentCallbacks returned non-nil results.
type AfterAgentCallback func(CallbackContext) (*genai.Content, error)

type agent struct {
	agentinternal.State

	name, description string
	subAgents         []Agent

	beforeAgentCallbacks []BeforeAgentCallback
	run                  func(InvocationContext) iter.Seq2[*session.Event, error]
	afterAgentCallbacks  []AfterAgentCallback
}

func (a *agent) Name() string {
	return a.name
}

func (a *agent) Description() string {
	return a.description
}

func (a *agent) SubAgents() []Agent {
	return a.subAgents
}

func (a *agent) Run(ctx InvocationContext) iter.Seq2[*session.Event, error] {
	return func(yield func(*session.Event, error) bool) {
		spanCtx, span := telemetry.StartInvokeAgentSpan(ctx, a, ctx.Session().ID(), ctx.InvocationID())
		yield, endSpan := telemetry.WrapYield(span, yield, func(span trace.Span, event *session.Event, err error) {
			telemetry.TraceAgentResult(span, telemetry.TraceAgentResultParams{
				ResponseEvent: event,
				Error:         err,
			})
		})
		defer endSpan()
		// TODO: verify&update the setup here. Should we branch etc.
		ctx := &invocationContext{
			Context:   ctx.WithContext(spanCtx),
			agent:     a,
			artifacts: ctx.Artifacts(),
			memory:    ctx.Memory(),
			session:   ctx.Session(),

			invocationID:  ctx.InvocationID(),
			branch:        ctx.Branch(),
			userContent:   ctx.UserContent(),
			runConfig:     ctx.RunConfig(),
			endInvocation: ctx.Ended(),
		}
		event, err := runBeforeAgentCallbacks(ctx)
		if event != nil || err != nil {
			if !yield(event, err) {
				return
			}
		}

		if ctx.Ended() {
			return
		}

		for event, err := range a.run(ctx) {
			if event != nil && event.Author == "" {
				event.Author = getAuthorForEvent(ctx, event)
			}
			if !yield(event, err) {
				return
			}
		}

		if ctx.Ended() {
			return
		}

		event, err = runAfterAgentCallbacks(ctx)
		if event != nil || err != nil {
			yield(event, err)
		}
	}
}

func (a *agent) internal() *agent {
	return a
}

func getAuthorForEvent(ctx InvocationContext, event *session.Event) string {
	if event.LLMResponse.Content != nil && event.LLMResponse.Content.Role == genai.RoleUser {
		return genai.RoleUser
	}

	return ctx.Agent().Name()
}

// runBeforeAgentCallbacks checks if any beforeAgentCallback returns non-nil content
// then it skips agent run and returns callback result.
func runBeforeAgentCallbacks(ctx InvocationContext) (*session.Event, error) {
	agent := ctx.Agent()
	pluginManager := pluginManagerFromContext(ctx)

	callbackCtx := &callbackContext{
		Context:           ctx,
		invocationContext: ctx,
		actions:           &session.EventActions{StateDelta: make(map[string]any), ArtifactDelta: make(map[string]int64)},
	}

	if pluginManager != nil {
		content, err := pluginManager.RunBeforeAgentCallback(callbackCtx)
		if err != nil {
			return nil, fmt.Errorf("failed to run plugin before agent callback: %w", err)
		}
		if content != nil {
			event := session.NewEvent(ctx.InvocationID())
			event.LLMResponse = model.LLMResponse{
				Content: content,
			}
			event.Author = agent.Name()
			event.Branch = ctx.Branch()
			event.Actions = *callbackCtx.actions
			ctx.EndInvocation()
			return event, nil
		}
	}

	for _, callback := range ctx.Agent().internal().beforeAgentCallbacks {
		content, err := callback(callbackCtx)
		if err != nil {
			return nil, fmt.Errorf("failed to run before agent callback: %w", err)
		}
		if content == nil {
			continue
		}

		event := session.NewEvent(ctx.InvocationID())
		event.LLMResponse = model.LLMResponse{
			Content: content,
		}
		event.Author = agent.Name()
		event.Branch = ctx.Branch()
		event.Actions = *callbackCtx.actions
		ctx.EndInvocation()
		return event, nil
	}

	// check if has delta create event with it
	if len(callbackCtx.actions.StateDelta) > 0 {
		event := session.NewEvent(ctx.InvocationID())
		event.Author = agent.Name()
		event.Branch = ctx.Branch()
		event.Actions = *callbackCtx.actions
		return event, nil
	}

	return nil, nil
}

// runAfterAgentCallbacks checks if any afterAgentCallback returns non-nil content or a state modification
// then it create a new event with the new content and state delta.
func runAfterAgentCallbacks(ctx InvocationContext) (*session.Event, error) {
	agent := ctx.Agent()
	pluginManager := pluginManagerFromContext(ctx)

	callbackCtx := &callbackContext{
		Context:           ctx,
		invocationContext: ctx,
		actions:           &session.EventActions{StateDelta: make(map[string]any), ArtifactDelta: make(map[string]int64)},
	}

	if pluginManager != nil {
		content, err := pluginManager.RunAfterAgentCallback(callbackCtx)
		if err != nil {
			return nil, fmt.Errorf("failed to run plugin after agent callback: %w", err)
		}
		if content != nil {
			event := session.NewEvent(ctx.InvocationID())
			event.LLMResponse = model.LLMResponse{
				Content: content,
			}
			event.Author = agent.Name()
			event.Branch = ctx.Branch()
			event.Actions = *callbackCtx.actions
			return event, nil
		}
	}

	for _, callback := range agent.internal().afterAgentCallbacks {
		newContent, err := callback(callbackCtx)
		if err != nil {
			return nil, fmt.Errorf("failed to run after agent callback: %w", err)
		}
		if newContent == nil {
			continue
		}

		event := session.NewEvent(ctx.InvocationID())
		event.LLMResponse = model.LLMResponse{
			Content: newContent,
		}
		event.Author = agent.Name()
		event.Branch = ctx.Branch()
		event.Actions = *callbackCtx.actions
		// TODO set context invocation ended
		// ctx.invocationEnded = true
		return event, nil
	}

	// check if has delta create event with it
	if len(callbackCtx.actions.StateDelta) > 0 {
		event := session.NewEvent(ctx.InvocationID())
		event.Author = agent.Name()
		event.Branch = ctx.Branch()
		event.Actions = *callbackCtx.actions
		return event, nil
	}
	return nil, nil
}

// TODO: unify with internal/context.callbackContext

type callbackContext struct {
	context.Context
	invocationContext InvocationContext
	actions           *session.EventActions
}

func (c *callbackContext) AgentName() string {
	return c.invocationContext.Agent().Name()
}

func (c *callbackContext) ReadonlyState() session.ReadonlyState {
	return c.invocationContext.Session().State()
}

func (c *callbackContext) State() session.State {
	return &callbackContextState{ctx: c}
}

func (c *callbackContext) Artifacts() Artifacts {
	return c.invocationContext.Artifacts()
}

func (c *callbackContext) InvocationID() string {
	return c.invocationContext.InvocationID()
}

func (c *callbackContext) UserContent() *genai.Content {
	return c.invocationContext.UserContent()
}

// AppName implements CallbackContext.
func (c *callbackContext) AppName() string {
	return c.invocationContext.Session().AppName()
}

// Branch implements CallbackContext.
func (c *callbackContext) Branch() string {
	return c.invocationContext.Branch()
}

// SessionID implements CallbackContext.
func (c *callbackContext) SessionID() string {
	return c.invocationContext.Session().ID()
}

// UserID implements CallbackContext.
func (c *callbackContext) UserID() string {
	return c.invocationContext.Session().UserID()
}

var _ CallbackContext = (*callbackContext)(nil)

type callbackContextState struct {
	ctx *callbackContext
}

func (c *callbackContextState) Get(key string) (any, error) {
	if c.ctx.actions != nil && c.ctx.actions.StateDelta != nil {
		if val, ok := c.ctx.actions.StateDelta[key]; ok {
			return val, nil
		}
	}
	return c.ctx.invocationContext.Session().State().Get(key)
}

func (c *callbackContextState) Set(key string, val any) error {
	if c.ctx.actions != nil && c.ctx.actions.StateDelta != nil {
		c.ctx.actions.StateDelta[key] = val
	}
	return c.ctx.invocationContext.Session().State().Set(key, val)
}

func (c *callbackContextState) All() iter.Seq2[string, any] {
	return c.ctx.invocationContext.Session().State().All()
}

type invocationContext struct {
	context.Context

	agent     Agent
	artifacts Artifacts
	memory    Memory
	session   session.Session

	invocationID  string
	branch        string
	userContent   *genai.Content
	runConfig     *RunConfig
	endInvocation bool
}

func (c *invocationContext) Agent() Agent {
	return c.agent
}

func (c *invocationContext) Artifacts() Artifacts {
	return c.artifacts
}

func (c *invocationContext) Memory() Memory {
	return c.memory
}

func (c *invocationContext) Session() session.Session {
	return c.session
}

func (c *invocationContext) InvocationID() string {
	return c.invocationID
}

func (c *invocationContext) Branch() string {
	return c.branch
}

func (c *invocationContext) UserContent() *genai.Content {
	return c.userContent
}

func (c *invocationContext) RunConfig() *RunConfig {
	return c.runConfig
}

func (c *invocationContext) EndInvocation() {
	c.endInvocation = true
}

func (c *invocationContext) Ended() bool {
	return c.endInvocation
}

func (c *invocationContext) WithContext(ctx context.Context) InvocationContext {
	newCtx := *c
	newCtx.Context = ctx
	return &newCtx
}

func pluginManagerFromContext(ctx context.Context) pluginManager {
	a := ctx.Value(plugincontext.PluginManagerCtxKey)
	m, ok := a.(pluginManager)
	if !ok {
		return nil
	}
	return m
}

type pluginManager interface {
	RunBeforeAgentCallback(cctx CallbackContext) (*genai.Content, error)
	RunAfterAgentCallback(cctx CallbackContext) (*genai.Content, error)
}

var _ InvocationContext = (*invocationContext)(nil)


================================================
FILE: agent/agent_test.go
================================================
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"context"
	"iter"
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"google.golang.org/genai"

	"google.golang.org/adk/model"
	"google.golang.org/adk/session"
)

func TestAgentCallbacks(t *testing.T) {
	t.Parallel()

	tests := []struct {
		name         string
		beforeAgent  []BeforeAgentCallback
		afterAgent   []AfterAgentCallback
		wantLLMCalls int
		wantEvents   []*session.Event
	}{
		{
			name: "before agent callback runs, no llm calls",
			beforeAgent: []BeforeAgentCallback{
				func(ctx CallbackContext) (*genai.Content, error) {
					return genai.NewContentFromText("hello from before_agent_callback", genai.RoleModel), nil
				},
			},
			wantEvents: []*session.Event{
				{
					Author: "test",
					LLMResponse: model.LLMResponse{
						Content: genai.NewContentFromText("hello from before_agent_callback", genai.RoleModel),
					},
					Actions: session.EventActions{
						StateDelta:    map[string]any{},
						ArtifactDelta: map[string]int64{},
					},
				},
			},
		},
		{
			name: "no callback effect if callbacks return nil",
			beforeAgent: []BeforeAgentCallback{
				func(ctx CallbackContext) (*genai.Content, error) {
					return nil, nil
				},
			},
			afterAgent: []AfterAgentCallback{
				func(CallbackContext) (*genai.Content, error) {
					return nil, nil
				},
			},
			wantLLMCalls: 1,
			wantEvents: []*session.Event{
				{
					Author: "test",
					LLMResponse: model.LLMResponse{
						Content: genai.NewContentFromText("hello", genai.RoleModel),
					},
				},
			},
		},
		{
			name: "after agent callback create a new event with new content",
			afterAgent: []AfterAgentCallback{
				func(CallbackContext) (*genai.Content, error) {
					return genai.NewContentFromText("hello from after_agent_callback", genai.RoleModel), nil
				},
			},
			wantLLMCalls: 1,
			wantEvents: []*session.Event{
				{
					Author: "test",
					LLMResponse: model.LLMResponse{
						Content: genai.NewContentFromText("hello", genai.RoleModel),
					},
				},
				{
					Author: "test",
					LLMResponse: model.LLMResponse{
						Content: genai.NewContentFromText("hello from after_agent_callback", genai.RoleModel),
					},
					Actions: session.EventActions{
						StateDelta:    map[string]any{},
						ArtifactDelta: map[string]int64{},
					},
				},
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			custom := &customAgent{}

			testAgent, err := New(Config{
				Name:                 "test",
				BeforeAgentCallbacks: tt.beforeAgent,
				Run:                  custom.Run,
				AfterAgentCallbacks:  tt.afterAgent,
			})
			if err != nil {
				t.Fatalf("failed to create agent: %v", err)
			}

			ctx := &invocationContext{
				Context: t.Context(),
				agent:   testAgent,
				session: &mockSession{sessionID: "test-session"},
			}
			var gotEvents []*session.Event
			for event, err := range testAgent.Run(ctx) {
				if err != nil {
					t.Fatalf("unexpected error from the agent: %v", err)
				}

				gotEvents = append(gotEvents, event)
			}

			if tt.wantLLMCalls != custom.callCounter {
				t.Errorf("unexpected want_llm_calls, got: %v, want: %v", custom.callCounter, tt.wantLLMCalls)
			}

			if len(tt.wantEvents) != len(gotEvents) {
				t.Errorf("unexpected event lengths, got: %v, want: %v", len(gotEvents), len(tt.wantEvents))
			}

			for i, gotEvent := range gotEvents {
				if diff := cmp.Diff(tt.wantEvents[i], gotEvent, cmpopts.IgnoreFields(session.Event{}, "ID", "Timestamp", "InvocationID")); diff != "" {
					t.Errorf("diff in the events: got event[%d]: %v, want: %v, diff: %v", i, gotEvent, tt.wantEvents[i], diff)
				}
			}
		})
	}
}

func TestEndInvocation_EndsBeforeMainCall(t *testing.T) {
	custom := &customAgent{}

	testAgent, err := New(Config{
		Name: "test",
		BeforeAgentCallbacks: []BeforeAgentCallback{
			func(ctx CallbackContext) (*genai.Content, error) {
				return nil, nil
			},
		},
		Run: custom.Run,
	})
	if err != nil {
		t.Fatalf("failed to create agent: %v", err)
	}

	ctx := &invocationContext{
		Context:       t.Context(),
		agent:         testAgent,
		endInvocation: true,
		session:       &mockSession{sessionID: "test-session"},
	}
	for _, err := range testAgent.Run(ctx) {
		if err != nil {
			t.Fatalf("unexpected error from the agent: %v", err)
		}
	}

	// Even though beforeAgentCallback returns nil, it stil doesn't call llm because
	// endInvocation is true.
	if custom.callCounter != 0 {
		t.Errorf("unexpected want_llm_calls, got: %v, want: %v", custom.callCounter, 0)
	}
}

func TestEndInvocation_EndsAfterMainCall(t *testing.T) {
	custom := &customAgent{endInvocation: true}

	testAgent, err := New(Config{
		Name: "test",
		AfterAgentCallbacks: []AfterAgentCallback{
			func(CallbackContext) (*genai.Content, error) {
				return genai.NewContentFromText("hello from after_agent_callback", genai.RoleModel), nil
			},
		},
		Run: custom.Run,
	})
	if err != nil {
		t.Fatalf("failed to create agent: %v", err)
	}

	ctx := &invocationContext{
		Context: t.Context(),
		agent:   testAgent,
		session: &mockSession{sessionID: "test-session"},
	}
	var gotEvents []*session.Event
	for event, err := range testAgent.Run(ctx) {
		if err != nil {
			t.Fatalf("unexpected error from the agent: %v", err)
		}
		gotEvents = append(gotEvents, event)
	}

	if custom.callCounter != 1 {
		t.Errorf("unexpected want_llm_calls, got: %v, want: %v", custom.callCounter, 0)
	}
	// Even though AfterAgentCallbacks is present, it's not returned because EndInvocation is set to true
	wantEvent := &session.Event{
		Author: "test",
		LLMResponse: model.LLMResponse{
			Content: genai.NewContentFromText("hello", genai.RoleModel),
		},
	}
	if len(gotEvents) != 1 {
		t.Errorf("unexpected number of events, got: %v, want: %v", len(gotEvents), 1)
	}
	if diff := cmp.Diff(wantEvent, gotEvents[0], cmpopts.IgnoreFields(session.Event{}, "ID", "Timestamp", "InvocationID"),
		cmpopts.IgnoreFields(session.EventActions{}, "StateDelta")); diff != "" {
		t.Errorf("unexpected event, got: %v, want: %v, diff: %v", gotEvents[0], wantEvent, diff)
	}
}

// TODO: create test util allowing to create custom agents, agent trees for test etc.
type customAgent struct {
	callCounter   int
	endInvocation bool
}

func (a *customAgent) Run(ctx InvocationContext) iter.Seq2[*session.Event, error] {
	return func(yield func(*session.Event, error) bool) {
		a.callCounter++

		if a.endInvocation {
			ctx.EndInvocation()
		}

		yield(&session.Event{
			LLMResponse: model.LLMResponse{
				Content: genai.NewContentFromText("hello", genai.RoleModel),
			},
		}, nil)
	}
}

type testKey struct{}

func TestWithContext(t *testing.T) {
	baseCtx := t.Context()
	inv := &invocationContext{
		Context:      baseCtx,
		invocationID: "test",
		branch:       "branch",
	}

	key := testKey{}
	val := "val"
	got := inv.WithContext(context.WithValue(baseCtx, key, val))

	if got.Value(key) != val {
		t.Errorf("WithContext() did not update context")
	}
	if diff := cmp.Diff(inv, got, cmp.AllowUnexported(invocationContext{}), cmpopts.IgnoreFields(invocationContext{}, "Context")); diff != "" {
		t.Errorf("WithContext() params mismatch (-want +got):\n%s", diff)
	}
}

type mockSession struct {
	session.Session
	sessionID string
}

func (m *mockSession) ID() string { return m.sessionID }


================================================
FILE: agent/context.go
================================================
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"context"

	"google.golang.org/genai"

	"google.golang.org/adk/session"
)

/*
InvocationContext represents the context of an agent invocation.

An invocation:
 1. Starts with a user message and ends with a final response.
 2. Can contain one or multiple agent calls.
 3. Is handled by runner.Run().

An invocation runs an agent until it does not request to transfer to another
agent.

An agent call:
 1. Is handled by agent.Run().
 2. Ends when agent.Run() ends.

An agent call can contain one or multiple steps.
For example, LLM agent runs steps in a loop until:
 1. A final response is generated.
 2. The agent transfers to another agent.
 3. EndInvocation() was called by the invocation context.

A step:
 1. Calls the LLM only once and yields its response.
 2. Calls the tools and yields their responses if requested.

The summarization of the function response is considered another step, since
it is another LLM call.
A step ends when it's done calling LLM and tools, or if the EndInvocation() was
called by invocation context at any time.

	┌─────────────────────── invocation ──────────────────────────┐
	┌──────────── llm_agent_call_1 ────────────┐ ┌─ agent_call_2 ─┐
	┌──── step_1 ────────┐ ┌───── step_2 ──────┐
	[call_llm] [call_tool] [call_llm] [transfer]
*/
type InvocationContext interface {
	context.Context

	// Agent of this invocation context.
	Agent() Agent

	// Artifacts of the current session.
	Artifacts() Artifacts

	// Memory is scoped to sessions of the current user_id.
	Memory() Memory

	// Session of the current invocation context.
	Session() session.Session

	InvocationID() string

	// Branch of the invocation context.
	// The format is like agent_1.agent_2.agent_3, where agent_1 is the parent
	// of agent_2, and agent_2 is the parent of agent_3.
	//
	// Branch is used when multiple sub-agents shouldn't see their peer agents'
	// conversation history.
	//
	// Applicable to parallel agent because its sub-agents run concurrently.
	Branch() string

	// UserContent that started this invocation.
	UserContent() *genai.Content

	// RunConfig stores the runtime configuration used during this invocation.
	RunConfig() *RunConfig

	// EndInvocation ends the current invocation. This stops any planned agent
	// calls.
	EndInvocation()
	// Ended returns whether the invocation has ended.
	Ended() bool

	// WithContext returns a new instance of the context with overridden embedded context.
	// NOTE: This is a temporary solution and will be removed later. The proper solution
	// we plan is to stop embedding go context in adk context types and split it.
	WithContext(ctx context.Context) InvocationContext
}

// ReadonlyContext provides read-only access to invocation context data.
type ReadonlyContext interface {
	context.Context

	// UserContent that started this invocation.
	UserContent() *genai.Content
	InvocationID() string
	AgentName() string
	ReadonlyState() session.ReadonlyState

	UserID() string
	AppName() string
	SessionID() string
	// Branch of the current invocation.
	Branch() string
}

// CallbackContext is passed to user callbacks during agent execution.
type CallbackContext interface {
	ReadonlyContext

	Artifacts() Artifacts
	State() session.State
}


================================================
FILE: agent/doc.go
================================================
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package agent provides entities to build agents using ADK.
package agent


================================================
FILE: agent/llmagent/doc.go
================================================
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package llmagent provides an LLM-based agent.
// LLM agents use large language models to perform tasks based on instructions, user input,
// deciding on actions to take, and executing actions using available tools or
// delegating to sub agents.
package llmagent


================================================
FILE: agent/llmagent/llmagent.go
================================================
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package llmagent

import (
	"fmt"
	"iter"
	"strings"

	"google.golang.org/genai"

	"google.golang.org/adk/agent"
	agentinternal "google.golang.org/adk/internal/agent"
	icontext "google.golang.org/adk/internal/context"
	"google.golang.org/adk/internal/llminternal"
	"google.golang.org/adk/model"
	"google.golang.org/adk/session"
	"google.golang.org/adk/tool"
)

// New is a constructor for LLMAgent.
func New(cfg Config) (agent.Agent, error) {
	beforeModelCallbacks := make([]llminternal.BeforeModelCallback, 0, len(cfg.BeforeModelCallbacks))
	for _, c := range cfg.BeforeModelCallbacks {
		beforeModelCallbacks = append(beforeModelCallbacks, llminternal.BeforeModelCallback(c))
	}

	afterModelCallbacks := make([]llminternal.AfterModelCallback, 0, len(cfg.AfterModelCallbacks))
	for _, c := range cfg.AfterModelCallbacks {
		afterModelCallbacks = append(afterModelCallbacks, llminternal.AfterModelCallback(c))
	}

	onModelErrorCallbacks := make([]llminternal.OnModelErrorCallback, 0, len(cfg.OnModelErrorCallbacks))
	for _, c := range cfg.OnModelErrorCallbacks {
		onModelErrorCallbacks = append(onModelErrorCallbacks, llminternal.OnModelErrorCallback(c))
	}

	beforeToolCallbacks := make([]llminternal.BeforeToolCallback, 0, len(cfg.BeforeToolCallbacks))
	for _, c := range cfg.BeforeToolCallbacks {
		beforeToolCallbacks = append(beforeToolCallbacks, llminternal.BeforeToolCallback(c))
	}

	afterToolCallbacks := make([]llminternal.AfterToolCallback, 0, len(cfg.AfterToolCallbacks))
	for _, c := range cfg.AfterToolCallbacks {
		afterToolCallbacks = append(afterToolCallbacks, llminternal.AfterToolCallback(c))
	}

	onToolErrorCallback := make([]llminternal.OnToolErrorCallback, 0, len(cfg.OnToolErrorCallbacks))
	for _, c := range cfg.OnToolErrorCallbacks {
		onToolErrorCallback = append(onToolErrorCallback, llminternal.OnToolErrorCallback(c))
	}

	a := &llmAgent{
		model:                 cfg.Model,
		beforeModelCallbacks:  beforeModelCallbacks,
		afterModelCallbacks:   afterModelCallbacks,
		onModelErrorCallbacks: onModelErrorCallbacks,
		beforeToolCallbacks:   beforeToolCallbacks,
		afterToolCallbacks:    afterToolCallbacks,
		onToolErrorCallbacks:  onToolErrorCallback,
		instruction:           cfg.Instruction,
		inputSchema:           cfg.InputSchema,
		outputSchema:          cfg.OutputSchema,

		State: llminternal.State{
			Model:                    cfg.Model,
			GenerateContentConfig:    cfg.GenerateContentConfig,
			Tools:                    cfg.Tools,
			Toolsets:                 cfg.Toolsets,
			DisallowTransferToParent: cfg.DisallowTransferToParent,
			DisallowTransferToPeers:  cfg.DisallowTransferToPeers,
			InputSchema:              cfg.InputSchema,
			OutputSchema:             cfg.OutputSchema,
			// TODO: internal type for includeContents
			IncludeContents:           string(cfg.IncludeContents),
			Instruction:               cfg.Instruction,
			InstructionProvider:       llminternal.InstructionProvider(cfg.InstructionProvider),
			GlobalInstruction:         cfg.GlobalInstruction,
			GlobalInstructionProvider: llminternal.InstructionProvider(cfg.GlobalInstructionProvider),
			OutputKey:                 cfg.OutputKey,
		},
	}

	baseAgent, err := agent.New(agent.Config{
		Name:                 cfg.Name,
		Description:          cfg.Description,
		SubAgents:            cfg.SubAgents,
		BeforeAgentCallbacks: cfg.BeforeAgentCallbacks,
		Run:                  a.run,
		AfterAgentCallbacks:  cfg.AfterAgentCallbacks,
	})
	if err != nil {
		return nil, fmt.Errorf("failed to create agent: %w", err)
	}

	// TODO: remove this in favor of the state reveal below.
	a.Agent = baseAgent
	a.AgentType = agentinternal.TypeLLMAgent
	a.Config = cfg

	// TODO: temporary hack to set the LLMAgent type field correctly. Currently, beforeAgentCallback for LLMAgent only
	// sees basic *agent.agent type: http://google3/third_party/golang/adk/agent/agent.go;l=177-201;rcl=869633263
	// So in BeforeAgentCallback, we cannot access llmAgent.State fields.
	// We should remote llminternal.State in favor of agentinternal.State.

	internalAgent, ok := baseAgent.(agentinternal.Agent)
	if !ok {
		return nil, fmt.Errorf("internal error: failed to convert to internal agent")
	}
	state := agentinternal.Reveal(internalAgent)
	state.AgentType = agentinternal.TypeLLMAgent
	state.Config = cfg

	return a, nil
}

// Config of the LLMAgent.
type Config struct {
	// Name must be a non-empty string, unique within the agent tree.
	// Agent name cannot be "user", since it's reserved for end-user's input.
	Name string
	// Description of the agent's capability.
	//
	// LLM uses this to determine whether to delegate control to the agent.
	// One-line description is enough and preferred.
	Description string
	// SubAgents are the child agents that this agent can delegate tasks to.
	// ADK will automatically set a parent of each sub-agent to this agent to
	// allow agent transferring across the tree.
	SubAgents []agent.Agent

	// BeforeAgentCallbacks is a list of callbacks that are called sequentially
	// before the agent starts its run.
	//
	// If any callback returns non-nil content or error, then the agent run and
	// the remaining callbacks will be skipped, and a new event will be created
	// from the content or error of that callback.
	BeforeAgentCallbacks []agent.BeforeAgentCallback
	// AfterAgentCallbacks is a list of callbacks that are called sequentially
	// after the agent has completed its run.
	//
	// If any callback returns non-nil content or error, then a new event will be
	// created from the content or error of that callback and the remaining
	// callbacks will be skipped.
	AfterAgentCallbacks []agent.AfterAgentCallback

	// GenerateContentConfig is for the additional content generation
	// configuration.
	//
	// NOTE: not all fields are usable, e.g. tools must be configured via
	// `tools`.
	//
	// For example: use this config to adjust model temperature, configure
	// safety settings, etc.
	GenerateContentConfig *genai.GenerateContentConfig

	// BeforeModelCallbacks will be called in the order they are provided until
	// there's a callback that returns a non-nil LLMResponse or error. Then
	// actual LLM call is skipped, and the returned response/error is used.
	//
	// This provides an opportunity to inspect, log, or modify the `LLMRequest`
	// object. It can also be used to implement caching by returning a cached
	// `LLMResponse`, which would skip the actual model call.
	BeforeModelCallbacks []BeforeModelCallback
	// Model that is used by the agent.
	Model model.LLM
	// AfterModelCallbacks will be called in the order they are provided until
	// there's a callback that returns a non-nil LLMResponse or error. Then
	// actual LLM response is replaced with the returned response/error.
	//
	// This is the ideal place to log model responses, collect metrics on token
	// usage, or perform post-processing on the raw `LLMResponse`.
	AfterModelCallbacks []AfterModelCallback

	OnModelErrorCallbacks []OnModelErrorCallback

	// Instruction is set for the LLM model guiding the agent's behavior.
	//
	// The string is treated as a template:
	//  - There can be placeholders like {key_name} that will be resolved by ADK
	//    at runtime using session state and context.
	//  - key_name must match "^[a-zA-Z_][a-zA-Z0-9_]*$", otherwise it will be
	//    treated as a literal.
	//  - {artifact.key_name} can be used to insert the text content of the
	//    artifact named key_name.
	//
	// If the state variable or artifact does not exist, the agent will raise an
	// error. If you want to ignore the error, you can append a ? to the
	// variable name as in {var?} to make it optional.
	//
	// If templating logic for {} chars is not desired, then InstructionProvider
	// should be used.
	Instruction string
	// InstructionProvider allows to create instructions dynamically based on
	// the agent context.
	//
	// It takes over the Instruction field if both are set.
	//
	// InstructionProvider does not automatically substitute values to {} and
	// treats them as just a raw char.
	// If you need to inject session state variables, use
	// util/instructionutil.InjectSessionState helper.
	InstructionProvider InstructionProvider

	// GlobalInstruction is the instruction for all agents in the entire
	// agent tree.
	//
	// The string is treated as a template:
	//  - There can be placeholders like {key_name} that will be resolved by ADK
	//    at runtime using session state and context.
	//  - key_name must match "^[a-zA-Z_][a-zA-Z0-9_]*$", otherwise it will be
	//    treated as a literal.
	//  - {artifact.key_name} can be used to insert the text content of the
	//    artifact named key_name.
	//
	// If the state variable or artifact does not exist, the agent will raise an
	// error. If you want to ignore the error, you can append a ? to the
	// variable name as in {var?} to make it optional.
	//
	// ONLY the GlobalInstruction in the root agent will take effect.
	//
	// For example: GlobalInstruction can make all agents have a stable identity
	// or personality.
	GlobalInstruction string
	// GlobalInstructionProvider allows to create global instructions
	// dynamically based on the agent context.
	//
	// It takes over the GlobalInstruction field if both are set.
	GlobalInstructionProvider InstructionProvider

	// DisallowTransferToParent prevents transferring to parent agent if LLM
	// decides to.
	DisallowTransferToParent bool
	// DisallowTransferToPeers prevents transferring to peer agents.
	DisallowTransferToPeers bool

	// Whether to include contents (conversation history) in the model request.
	IncludeContents IncludeContents

	// TODO(ngeorgy): consider to switch to jsonschema for input and output schema.
	// The input schema when agent is used as a tool.
	InputSchema *genai.Schema
	// The output schema when agent replies.
	//
	// NOTE: when this is set, agent can only reply and cannot use any tools,
	// such as function tools, RAGs, agent transfer, etc.
	OutputSchema *genai.Schema

	// Callbacks are executed in the order they are provided.
	// If a callback returns result/error, then the execution of the callback
	// list stops AND the actual tool call is skipped.
	BeforeToolCallbacks []BeforeToolCallback
	// Tools available to the agent.
	Tools []tool.Tool
	// Callbacks are executed in the order they are provided.
	// If a callback returns result/error, then the execution of the callback
	// list stops and this result/error is returned instead.
	AfterToolCallbacks []AfterToolCallback
	// Toolsets will be used by llmagent to extract tools and pass to the
	// underlying LLM.
	Toolsets []tool.Toolset

	OnToolErrorCallbacks []OnToolErrorCallback

	// OutputKey is an optional parameter to specify the key in session state for the agent output.
	//
	// Typical uses cases are:
	// - Extracts agent reply for later use, such as in tools, callbacks, etc.
	// - Connects agents to coordinate with each other.
	OutputKey string
}

// BeforeModelCallback that is called before sending a request to the model.
//
// If it returns non-nil LLMResponse or error, the actual model call is skipped
// and the returned response/error is used.
type BeforeModelCallback func(ctx agent.CallbackContext, llmRequest *model.LLMRequest) (*model.LLMResponse, error)

// AfterModelCallback that is called after receiving a response from the model.
//
// If it returns non-nil LLMResponse or error, the actual model response/error
// is replaced with the returned response/error.
type AfterModelCallback func(ctx agent.CallbackContext, llmResponse *model.LLMResponse, llmResponseError error) (*model.LLMResponse, error)

// OnModelErrorCallback that is called when receiving an error response from the llm model.
//
// If it returns non-nil LLMResponse or error, the actual model response/error
// is replaced with the returned response/error.
type OnModelErrorCallback func(ctx agent.CallbackContext, llmRequest *model.LLMRequest, llmResponseError error) (*model.LLMResponse, error)

// BeforeToolCallback is executed before a tool's Run method.
//
// Callbacks are executed in the order they are provided.
// If a callback returns a non-nil result or an error:
// - execution of remaining callbacks stops
// - the actual tool call is skipped
// - the returned result is used as the tool result
//
// To modify tool arguments and still run the tool,
// update args in place and return (nil, nil).
type BeforeToolCallback func(ctx tool.Context, tool tool.Tool, args map[string]any) (map[string]any, error)

// AfterToolCallback is a function type executed after a tool's Run method has completed,
// regardless of whether the tool returned a result or an error.
//
// Callbacks are executed in the order they are provided.
// If a callback returns a non-nil result or an error:
//   - execution of remaining callbacks stops
//   - the returned result and/or error is used as the final tool output
type AfterToolCallback func(ctx tool.Context, tool tool.Tool, args, result map[string]any, err error) (map[string]any, error)

// OnToolErrorCallback that is called when receiving an error response from tool execution.
//
// If it returns non-nil LLMResponse or error, the actual model response/error
// is replaced with the returned response/error.
type OnToolErrorCallback func(ctx tool.Context, tool tool.Tool, args map[string]any, err error) (map[string]any, error)

// IncludeContents controls what parts of prior conversation history is received by llmagent.
type IncludeContents string

const (
	// IncludeContentsNone makes the llmagent operate solely on its current turn (latest user input + any following agent events).
	IncludeContentsNone IncludeContents = "none"
	// IncludeContentsDefault is enabled by default. The llmagent receives the relevant conversation history.
	IncludeContentsDefault IncludeContents = "default"
)

type llmAgent struct {
	agent.Agent
	llminternal.State
	agentState

	beforeModelCallbacks  []llminternal.BeforeModelCallback
	model                 model.LLM
	afterModelCallbacks   []llminternal.AfterModelCallback
	instruction           string
	onModelErrorCallbacks []llminternal.OnModelErrorCallback

	beforeToolCallbacks  []llminternal.BeforeToolCallback
	afterToolCallbacks   []llminternal.AfterToolCallback
	onToolErrorCallbacks []llminternal.OnToolErrorCallback

	inputSchema  *genai.Schema
	outputSchema *genai.Schema
}

type agentState = agentinternal.State

func (a *llmAgent) run(ctx agent.InvocationContext) iter.Seq2[*session.Event, error] {
	// TODO: branch context?
	ctx = icontext.NewInvocationContext(ctx, icontext.InvocationContextParams{
		Artifacts:    ctx.Artifacts(),
		Memory:       ctx.Memory(),
		Session:      ctx.Session(),
		Branch:       ctx.Branch(),
		Agent:        a,
		UserContent:  ctx.UserContent(),
		RunConfig:    ctx.RunConfig(),
		InvocationID: ctx.InvocationID(),
	})

	f := &llminternal.Flow{
		Model:                 a.model,
		RequestProcessors:     llminternal.DefaultRequestProcessors,
		ResponseProcessors:    llminternal.DefaultResponseProcessors,
		BeforeModelCallbacks:  a.beforeModelCallbacks,
		AfterModelCallbacks:   a.afterModelCallbacks,
		OnModelErrorCallbacks: a.onModelErrorCallbacks,
		BeforeToolCallbacks:   a.beforeToolCallbacks,
		AfterToolCallbacks:    a.afterToolCallbacks,
		OnToolErrorCallbacks:  a.onToolErrorCallbacks,
	}

	return func(yield func(*session.Event, error) bool) {
		for ev, err := range f.Run(ctx) {
			a.maybeSaveOutputToState(ev)
			if !yield(ev, err) {
				return
			}
		}
	}
}

// maybeSaveOutputToState saves the model output to state if needed. skip if the event
// was authored by some other agent (e.g. current agent transferred to another agent)
func (a *llmAgent) maybeSaveOutputToState(event *session.Event) {
	if event == nil {
		return
	}
	if event.Author != a.Name() {
		// TODO: log "Skipping output save for agent %s: event authored by %s"
		return
	}
	if a.OutputKey != "" && !event.Partial && event.Content != nil && len(event.Content.Parts) > 0 {
		var sb strings.Builder
		for _, part := range event.Content.Parts {
			if part.Text != "" && !part.Thought {
				sb.WriteString(part.Text)
			}
		}
		result := sb.String()

		// TODO: add output schema validation and unmarshalling
		if a.OutputSchema != nil {
			// If the result from the final chunk is just whitespace or empty,
			// it means this is an empty final chunk of a stream.
			// Do not attempt to parse it as JSON.
			if strings.TrimSpace(result) == "" {
				return
			}
		}

		if event.Actions.StateDelta == nil {
			event.Actions.StateDelta = make(map[string]any)
		}

		event.Actions.StateDelta[a.OutputKey] = result
	}
}

// InstructionProvider allows to create instructions dynamically. It is called
// on each agent invocation.
//
// NOTE: when InstructionProvider is used, ADK will NOT inject session state
// placeholders into the instruction. You can use
// util/instructionutil.InjectSessionState() helper if this functionality is needed.
type InstructionProvider func(ctx agent.ReadonlyContext) (string, error)


================================================
FILE: agent/llmagent/llmagent_saveoutput_test.go
================================================
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package llmagent

import (
	"reflect"
	"testing"

	"google.golang.org/genai"

	"google.golang.org/adk/model"
	"google.golang.org/adk/session"
)

type MockOutputSchema struct {
	Message    string  `json:"message"`
	Confidence float64 `json:"confidence"`
}

// createTestEvent is a helper to build events for tests.
func createTestEvent(author, contentText string, isFinal bool) *session.Event {
	var parts []*genai.Part
	if contentText != "" {
		parts = append(parts, &genai.Part{Text: contentText})
	}

	var content *genai.Content
	if len(parts) > 0 {
		content = &genai.Content{Role: "model", Parts: parts}
	}

	return &session.Event{
		InvocationID: "test_invocation",
		Author:       author,
		LLMResponse:  model.LLMResponse{Content: content, Partial: !isFinal},
		Actions:      session.EventActions{StateDelta: make(map[string]any)},
	}
}

func TestLlmAgent_MaybeSaveOutputToState(t *testing.T) {
	// Define the structure for our test cases
	testCases := []struct {
		name             string
		agentConfig      Config
		event            *session.Event
		wantStateDelta   map[string]any
		customEventParts []*genai.Part // For multi-part test
	}{
		{
			name:           "skips when event author differs from agentConfig name",
			agentConfig:    Config{Name: "agent_a", OutputKey: "result"},
			event:          createTestEvent("agent_b", "Response from B", true),
			wantStateDelta: map[string]any{},
		},
		{
			name:           "saves when event author matches agentConfig name",
			agentConfig:    Config{Name: "test_agent", OutputKey: "result"},
			event:          createTestEvent("test_agent", "Test response", true),
			wantStateDelta: map[string]any{"result": "Test response"},
		},
		{
			name:           "skips when output_key is not set",
			agentConfig:    Config{Name: "test_agent"}, // No OutputKey
			event:          createTestEvent("test_agent", "Test response", true),
			wantStateDelta: map[string]any{},
		},
		{
			name:           "skips for non-final responses",
			agentConfig:    Config{Name: "test_agent", OutputKey: "result"},
			event:          createTestEvent("test_agent", "*genai.Partial response", false),
			wantStateDelta: map[string]any{},
		},
		{
			name:           "skips when event has no content text",
			agentConfig:    Config{Name: "test_agent", OutputKey: "result"},
			event:          createTestEvent("test_agent", "", true),
			wantStateDelta: map[string]any{},
		},
		{
			name:        "concatenates multiple text parts",
			agentConfig: Config{Name: "test_agent", OutputKey: "result"},
			event:       createTestEvent("test_agent", "", true), // Base event
			customEventParts: []*genai.Part{
				{Text: "Hello "},
				{Text: "world"},
				{Text: "!"},
			},
			wantStateDelta: map[string]any{"result": "Hello world!"},
		},
		{
			name:           "skips on case-sensitive name mismatch",
			agentConfig:    Config{Name: "TestAgent", OutputKey: "result"},
			event:          createTestEvent("testagent", "Test response", true),
			wantStateDelta: map[string]any{},
		},
		// TODO tests with OutputSchema
	}

	// Iterate over the test cases
	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			// --- Setup for specific cases ---
			if tc.customEventParts != nil {
				tc.event.Content = &genai.Content{Role: "model", Parts: tc.customEventParts}
			}

			// --- Execution ---
			// The method modifies the event in-place, just like the Python version.
			createdAgent, err := New(tc.agentConfig)
			if err != nil {
				t.Fatalf("failed to create agent: %v", err)
			}
			createdLlmAgent, ok := createdAgent.(*llmAgent)
			if !ok {
				t.Fatalf("failed to convert to llmagent")
			}
			createdLlmAgent.maybeSaveOutputToState(tc.event)

			// --- Assertion ---
			gotStateDelta := tc.event.Actions.StateDelta
			if !reflect.DeepEqual(gotStateDelta, tc.wantStateDelta) {
				t.Errorf("stateDelta mismatch:\ngot = %v\nwant = %v", gotStateDelta, tc.wantStateDelta)
			}
		})
	}
}


================================================
FILE: agent/llmagent/llmagent_test.go
================================================
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package llmagent_test

import (
	"errors"
	"fmt"
	"iter"
	"net/http"
	"path/filepath"
	"strings"
	"testing"

	"github.com/google/go-cmp/cmp"
	"google.golang.org/genai"

	"google.golang.org/adk/agent"
	"google.golang.org/adk/agent/llmagent"
	"google.golang.org/adk/internal/testutil"
	"google.golang.org/adk/model"
	"google.golang.org/adk/model/gemini"
	"google.golang.org/adk/session"
	"google.golang.org/adk/tool"
	"google.golang.org/adk/tool/functiontool"
)

const modelName = "gemini-2.5-flash"

//go:generate go test -httprecord=Test

func TestLLMAgent(t *testing.T) {
	errNoNetwork := errors.New("no network")

	for _, tc := range []struct {
		name      string
		transport http.RoundTripper
		wantErr   error
	}{
		{
			name:      "healthy_backend",
			transport: nil, // httprr + http.DefaultTransport
		},
		{
			name:      "broken_backend",
			transport: roundTripperFunc(func(*http.Request) (*http.Response, error) { return nil, errNoNetwork }),
			wantErr:   errNoNetwork,
		},
	} {
		t.Run(tc.name, func(t *testing.T) {
			model := newGeminiModel(t, modelName, tc.transport)
			a, err := llmagent.New(llmagent.Config{
				Name:                     "hello_world_agent",
				Description:              "hello world agent",
				Model:                    model,
				Instruction:              "Roll the dice and report only the result.",
				GlobalInstruction:        "Answer as precisely as possible.",
				DisallowTransferToParent: true,
				DisallowTransferToPeers:  true,
			})
			if err != nil {
				t.Fatalf("NewLLMAgent failed: %v", err)
			}
			// TODO: set tools, planner.
			runner := testutil.NewTestAgentRunner(t, a)
			stream := runner.Run(t, "test_session", "")
			texts, err := testutil.CollectTextParts(stream)
			if tc.wantErr != nil && !errors.Is(err, tc.wantErr) {
				t.Fatalf("stream = (%q, %v), want (_, %v)", texts, err, tc.wantErr)
			}
			if tc.wantErr == nil && (err != nil || len(texts) != 1) {
				t.Fatalf("stream = (%q, %v), want exactly one text response", texts, err)
			}
		})
	}
}

func TestLLMAgentStreamingModeSSE(t *testing.T) {
	model := newGeminiModel(t, "gemini-2.5-flash", nil)
	a, err := llmagent.New(llmagent.Config{
		Name:                     "calculator",
		Description:              "calculating agent",
		Model:                    model,
		Instruction:              "Think deep. Always double check the answer before making the conclusion.",
		DisallowTransferToParent: true,
		DisallowTransferToPeers:  true,
		GenerateContentConfig: &genai.GenerateContentConfig{
			ThinkingConfig: &genai.ThinkingConfig{
				IncludeThoughts: true, // can trigger multiple message.
			},
		},
	})
	if err != nil {
		t.Fatalf("NewLLMAgent failed: %v", err)
	}
	testRunner := testutil.NewTestAgentRunner(t, a)
	stream := testRunner.RunContentWithConfig(t, "test_session", genai.NewContentFromText("What is the sum of the first 50 prime numbers?", "user"), agent.RunConfig{StreamingMode: agent.StreamingModeSSE})
	events, err := testutil.CollectEvents(stream)
	gotThought := false
	numContents := 0
	for _, e := range events {
		t.Logf("event: %v", e)
		if e.LLMResponse.Content == nil {
			continue
		}
		numContents++
		for _, p := range e.LLMResponse.Content.Parts {
			if p.Thought {
				gotThought = true
			}
		}
	}
	if err != nil {
		t.Fatalf("stream = (_, %v), want (_, nil)", err)
	}
	if numContents <= 1 {
		t.Errorf("stream returned %d events with content, want more than 1 event", numContents)
	}
	if !gotThought {
		t.Error("stream returned no thought, want thought")
	}
}

func TestModelCallbacks(t *testing.T) {
	t.Parallel()

	for _, tc := range []struct {
		name                 string
		llmResponses         []*genai.Content
		beforeModelCallbacks []llmagent.BeforeModelCallback
		afterModelCallbacks  []llmagent.AfterModelCallback
		onModelErrorCallback []llmagent.OnModelErrorCallback
		wantTexts            []string
		wantErr              error
	}{
		{
			name: "before model callback doesn't modify anything",
			beforeModelCallbacks: []llmagent.BeforeModelCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest) (*model.LLMResponse, error) {
					return nil, nil
				},
			},
			llmResponses: []*genai.Content{
				genai.NewContentFromText("hello from model", genai.RoleModel),
			},
			wantTexts: []string{
				"hello from model",
			},
		},
		{
			name: "before model callback returns an error",
			beforeModelCallbacks: []llmagent.BeforeModelCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest) (*model.LLMResponse, error) {
					return nil, fmt.Errorf("before_model_callback_error: %w", http.ErrNoCookie)
				},
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest) (*model.LLMResponse, error) {
					return nil, fmt.Errorf("before_model_callback_error: %w", http.ErrHijacked)
				},
			},
			llmResponses: []*genai.Content{
				genai.NewContentFromText("hello from model", genai.RoleModel),
			},
			wantErr: http.ErrNoCookie,
		},
		{
			name: "before model callback returns new LLMResponse",
			beforeModelCallbacks: []llmagent.BeforeModelCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from before_model_callback", genai.RoleModel),
					}, nil
				},
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("unexpected text", genai.RoleModel),
					}, nil
				},
			},
			llmResponses: []*genai.Content{
				genai.NewContentFromText("hello from model", genai.RoleModel),
			},
			wantTexts: []string{
				"hello from before_model_callback",
			},
		},
		{
			name: "before model callback returns both new LLMResponse and error",
			beforeModelCallbacks: []llmagent.BeforeModelCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from before_model_callback", genai.RoleModel),
					}, fmt.Errorf("before_model_callback_error: %w", http.ErrNoCookie)
				},
			},
			llmResponses: []*genai.Content{
				genai.NewContentFromText("hello from model", genai.RoleModel),
			},
			wantErr: http.ErrNoCookie,
		},
		{
			name: "after model callback doesn't modify anything",
			afterModelCallbacks: []llmagent.AfterModelCallback{
				func(ctx agent.CallbackContext, llmResponse *model.LLMResponse, llmResponseError error) (*model.LLMResponse, error) {
					return nil, nil
				},
			},
			llmResponses: []*genai.Content{
				genai.NewContentFromText("hello from model", genai.RoleModel),
			},
			wantTexts: []string{
				"hello from model",
			},
		},
		{
			name: "after model callback returns new LLMResponse",
			afterModelCallbacks: []llmagent.AfterModelCallback{
				func(ctx agent.CallbackContext, llmResponse *model.LLMResponse, llmResponseError error) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from after_model_callback", genai.RoleModel),
					}, nil
				},
				func(ctx agent.CallbackContext, llmResponse *model.LLMResponse, llmResponseError error) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("unexpected text", genai.RoleModel),
					}, nil
				},
			},
			llmResponses: []*genai.Content{
				genai.NewContentFromText("hello from model", genai.RoleModel),
			},
			wantTexts: []string{
				"hello from after_model_callback",
			},
		},
		{
			name: "after model callback returns error",
			afterModelCallbacks: []llmagent.AfterModelCallback{
				func(ctx agent.CallbackContext, llmResponse *model.LLMResponse, llmResponseError error) (*model.LLMResponse, error) {
					return nil, fmt.Errorf("error from after_model_callback: %w", http.ErrNoCookie)
				},
				func(ctx agent.CallbackContext, llmResponse *model.LLMResponse, llmResponseError error) (*model.LLMResponse, error) {
					return nil, fmt.Errorf("error from after_model_callback: %w", http.ErrHijacked)
				},
			},
			llmResponses: []*genai.Content{
				genai.NewContentFromText("hello from model", genai.RoleModel),
			},
			wantErr: http.ErrNoCookie,
		},
		{
			name: "after model callback returns both new LLMResponse and error",
			afterModelCallbacks: []llmagent.AfterModelCallback{
				func(ctx agent.CallbackContext, llmResponse *model.LLMResponse, llmResponseError error) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from after_model_callback", genai.RoleModel),
					}, fmt.Errorf("error from after_model_callback: %w", http.ErrNoCookie)
				},
			},
			llmResponses: []*genai.Content{
				genai.NewContentFromText("hello from model", genai.RoleModel),
			},
			wantErr: http.ErrNoCookie,
		},
		{
			name: "on model error callback is not called",
			onModelErrorCallback: []llmagent.OnModelErrorCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest, llmError error) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from on_model_error_callback", genai.RoleModel),
					}, fmt.Errorf("on_model_error_callback: %w", http.ErrNoCookie)
				},
			},
			llmResponses: []*genai.Content{
				genai.NewContentFromText("hello from model", genai.RoleModel),
			},
			wantTexts: []string{
				"hello from model",
			},
		},
		{
			name: "on model error callback changes message",
			onModelErrorCallback: []llmagent.OnModelErrorCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest, llmError error) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from on_model_error_callback", genai.RoleModel),
					}, nil
				},
			},
			llmResponses: []*genai.Content{},
			wantTexts: []string{
				"hello from on_model_error_callback",
			},
		},
		{
			name: "on model error callback changes err",
			onModelErrorCallback: []llmagent.OnModelErrorCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest, llmError error) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from on_model_error_callback", genai.RoleModel),
					}, fmt.Errorf("error from on_model_error_callback: %w", http.ErrNoCookie)
				},
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest, llmError error) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from on_model_error_callback", genai.RoleModel),
					}, fmt.Errorf("error from on_model_error_callback: %w", http.ErrHijacked)
				},
			},
			llmResponses: []*genai.Content{},
			wantErr:      http.ErrNoCookie,
		},
		{
			name: "on model error callback returns both new LLMResponse and error",
			onModelErrorCallback: []llmagent.OnModelErrorCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest, llmError error) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from on_model_error_callback", genai.RoleModel),
					}, fmt.Errorf("error from on_model_error_callback: %w", http.ErrNoCookie)
				},
			},
			llmResponses: []*genai.Content{},
			wantErr:      http.ErrNoCookie,
		},
		{
			name: "on model error callback does not process before model callback error",
			beforeModelCallbacks: []llmagent.BeforeModelCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest) (*model.LLMResponse, error) {
					return nil, fmt.Errorf("before_model_callback_error: %w", http.ErrNoCookie)
				},
			},
			onModelErrorCallback: []llmagent.OnModelErrorCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest, llmError error) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from on_model_error_callback", genai.RoleModel),
					}, fmt.Errorf("error from on_model_error_callback: %w", http.ErrHijacked)
				},
			},
			llmResponses: []*genai.Content{
				genai.NewContentFromText("hello from model", genai.RoleModel),
			},
			wantErr: http.ErrNoCookie,
		},
		{
			name: "on model error callback does not process before model callback message",
			beforeModelCallbacks: []llmagent.BeforeModelCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from before_model_callback", genai.RoleModel),
					}, nil
				},
			},
			onModelErrorCallback: []llmagent.OnModelErrorCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest, llmError error) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from on_model_error_callback", genai.RoleModel),
					}, fmt.Errorf("error from on_model_error_callback: %w", http.ErrHijacked)
				},
			},
			llmResponses: []*genai.Content{
				genai.NewContentFromText("hello from model", genai.RoleModel),
			},
			wantTexts: []string{
				"hello from before_model_callback",
			},
		},
		{
			name: "after error callback process on model error callback message",
			onModelErrorCallback: []llmagent.OnModelErrorCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest, llmError error) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from on_model_error_callback", genai.RoleModel),
					}, nil
				},
			},
			afterModelCallbacks: []llmagent.AfterModelCallback{
				func(ctx agent.CallbackContext, llmResponse *model.LLMResponse, llmResponseError error) (*model.LLMResponse, error) {
					return &model.LLMResponse{
						Content: genai.NewContentFromText("hello from after_model_callback", genai.RoleModel),
					}, nil
				},
			},
			llmResponses: []*genai.Content{},
			wantTexts: []string{
				"hello from after_model_callback",
			},
		},
		{
			name: "after error callback does not process on model error callback error",
			onModelErrorCallback: []llmagent.OnModelErrorCallback{
				func(ctx agent.CallbackContext, llmRequest *model.LLMRequest, llmError error) (*model.LLMResponse, error) {
					return nil, fmt.Errorf("error from on_model_error_callback: %w", http.ErrNoCookie)
				},
			},
			afterModelCallbacks: []llmagent.AfterModelCallback{
				func(ctx agent.CallbackContext, llmResponse *model.LLMResponse, llmResponseError error) (*model.LLMResponse, error) {
					return nil, fmt.Errorf("error from after_model_callback: %w", http.ErrHijacked)
				},
			},
			llmResponses: []*genai.Content{},
			wantErr:      http.ErrNoCookie,
		},
	} {
		t.Run(tc.name, func(t *testing.T) {
			testLLM := &testutil.MockModel{
				Responses: tc.llmResponses,
			}
			a, err := llmagent.New(llmagent.Config{
				Name:                  "hello_world_agent",
				Model:                 testLLM,
				BeforeModelCallbacks:  tc.beforeModelCallbacks,
				AfterModelCallbacks:   tc.afterModelCallbacks,
				OnModelErrorCallbacks: tc.onModelErrorCallback,
			})
			if err != nil {
				t.Fatalf("failed to create llm agent: %v", err)
			}
			runner := testutil.NewTestAgentRunner(t, a)
			stream := runner.Run(t, "test_session", "")
			texts, err := testutil.CollectTextParts(stream)
			if tc.wantErr != nil && !errors.Is(err, tc.wantErr) {
				t.Fatalf("stream = (%q, %v), want (_, %v)", texts, err, tc.wantErr)
			}
			if (err != nil) != (tc.wantErr != nil) {
				t.Fatalf("unexpected result from agent, got error: %v, want error: %v", err, tc.wantErr)
			}

			if diff := cmp.Diff(tc.wantTexts, texts); diff != "" {
				t.Fatalf("unexpected result from agent, want: %v, got: %v, diff: %v", tc.wantTexts, texts, diff)
			}
		})
	}
}

func TestToolCallback(t *testing.T) {
	type Args struct {
		Seed int `json:"seed"`
	}
	type Result struct {
		Number int `json:"number"`
	}

	handler := func(_ tool.Context, input Args) (Result, error) {
		return Result{Number: 1}, nil
	}
	rand, _ := functiontool.New(functiontool.Config{
		Name:        "rand_number",
		Description: "returns random number",
	}, handler)

	t.Run("before_callback_response_used", func(t *testing.T) {
		model := newGeminiModel(t, modelName, nil)
		agent, err := llmagent.New(llmagent.Config{
			Name:                     "agent",
			Description:              "random agent",
			Model:                    model,
			Instruction:              "IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42",
			DisallowTransferToParent: true,
			DisallowTransferToPeers:  true,
			Tools:                    []tool.Tool{rand},
			BeforeToolCallbacks: []llmagent.BeforeToolCallback{
				func(ctx tool.Context, tool tool.Tool, args map[string]any) (map[string]any, error) {
					return nil, nil
				},
				func(ctx tool.Context, tool tool.Tool, args map[string]any) (map[string]any, error) {
					return map[string]any{"number": "7"}, nil
				},
			},
		})
		if err != nil {
			t.Fatalf("failed to create LLM Agent: %v", err)
		}

		runner := testutil.NewTestAgentRunner(t, agent)
		stream := runner.Run(t, "session1", "Generate random number with 5 as a seed.")

		ans, err := testutil.CollectTextParts(stream)
		if err != nil || len(ans) == 0 {
			t.Fatalf("agent returned (%v, %v), want result", ans, err)
		}
		if got, want := strings.TrimSpace(ans[len(ans)-1]), "7"; got != want {
			t.Errorf("unexpected result from agent = (%v, %v), want ([%q], nil)", ans, err, want)
		}
	})

	t.Run("extra_before_callback_skipped", func(t *testing.T) {
		model := newGeminiModel(t, modelName, nil)
		agent, err := llmagent.New(llmagent.Config{
			Name:                     "agent",
			Description:              "random agent",
			Model:                    model,
			Instruction:              "IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42",
			DisallowTransferToParent: true,
			DisallowTransferToPeers:  true,
			Tools:                    []tool.Tool{rand},
			BeforeToolCallbacks: []llmagent.BeforeToolCallback{
				// Since it retursn non nil, the next callback won't be executed.
				func(ctx tool.Context, tool tool.Tool, args map[string]any) (map[string]any, error) {
					return map[string]any{"number": "3"}, nil
				},
				func(ctx tool.Context, tool tool.Tool, args map[string]any) (map[string]any, error) {
					return map[string]any{"number": "7"}, nil
				},
			},
		})
		if err != nil {
			t.Fatalf("failed to create LLM Agent: %v", err)
		}

		runner := testutil.NewTestAgentRunner(t, agent)
		stream := runner.Run(t, "session1", "Generate random number with 5 as a seed.")

		ans, err := testutil.CollectTextParts(stream)
		if err != nil || len(ans) == 0 {
			t.Fatalf("agent returned (%v, %v), want result", ans, err)
		}
		if got, want := strings.TrimSpace(ans[len(ans)-1]), "3"; got != want {
			t.Errorf("unexpected result from agent = (%v, %v), want ([%q], nil)", ans, err, want)
		}
	})

	t.Run("after_callback_response_used", func(t *testing.T) {
		model := newGeminiModel(t, modelName, nil)
		agent, err := llmagent.New(llmagent.Config{
			Name:                     "agent",
			Description:              "random agent",
			Model:                    model,
			Instruction:              "IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42",
			DisallowTransferToParent: true,
			DisallowTransferToPeers:  true,
			Tools:                    []tool.Tool{rand},
			AfterToolCallbacks: []llmagent.AfterToolCallback{
				func(ctx tool.Context, tool tool.Tool, args, result map[string]any, err error) (map[string]any, error) {
					return nil, nil
				},
				func(ctx tool.Context, tool tool.Tool, args, result map[string]any, err error) (map[string]any, error) {
					return map[string]any{"number": "7"}, nil
				},
			},
		})
		if err != nil {
			t.Fatalf("failed to create LLM Agent: %v", err)
		}

		runner := testutil.NewTestAgentRunner(t, agent)
		stream := runner.Run(t, "session1", "Generate random number with 5 as a seed.")

		ans, err := testutil.CollectTextParts(stream)
		if err != nil || len(ans) == 0 {
			t.Fatalf("agent returned (%v, %v), want result", ans, err)
		}
		if got, want := strings.TrimSpace(ans[len(ans)-1]), "7"; got != want {
			t.Errorf("unexpected result from agent = (%v, %v), want ([%q], nil)", ans, err, want)
		}
	})

	t.Run("extra_after_callback_skipped", func(t *testing.T) {
		model := newGeminiModel(t, modelName, nil)
		agent, err := llmagent.New(llmagent.Config{
			Name:                     "agent",
			Description:              "random agent",
			Model:                    model,
			Instruction:              "IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42",
			DisallowTransferToParent: true,
			DisallowTransferToPeers:  true,
			Tools:                    []tool.Tool{rand},
			AfterToolCallbacks: []llmagent.AfterToolCallback{
				// Since it retursn non nil, the next callback won't be executed.
				func(ctx tool.Context, tool tool.Tool, args, result map[string]any, err error) (map[string]any, error) {
					return map[string]any{"number": "3"}, nil
				},
				func(ctx tool.Context, tool tool.Tool, args, result map[string]any, err error) (map[string]any, error) {
					return map[string]any{"number": "7"}, nil
				},
			},
		})
		if err != nil {
			t.Fatalf("failed to create LLM Agent: %v", err)
		}

		runner := testutil.NewTestAgentRunner(t, agent)
		stream := runner.Run(t, "session1", "Generate random number with 5 as a seed.")

		ans, err := testutil.CollectTextParts(stream)
		if err != nil || len(ans) == 0 {
			t.Fatalf("agent returned (%v, %v), want result", ans, err)
		}
		if got, want := strings.TrimSpace(ans[len(ans)-1]), "3"; got != want {
			t.Errorf("unexpected result from agent = (%v, %v), want ([%q], nil)", ans, err, want)
		}
	})

	t.Run("after_callback_returned_when_used_with_before_callback", func(t *testing.T) {
		model := newGeminiModel(t, modelName, nil)
		agent, err := llmagent.New(llmagent.Config{
			Name:                     "agent",
			Description:              "random agent",
			Model:                    model,
			Instruction:              "IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42",
			DisallowTransferToParent: true,
			DisallowTransferToPeers:  true,
			Tools:                    []tool.Tool{rand},
			BeforeToolCallbacks: []llmagent.BeforeToolCallback{
				func(ctx tool.Context, tool tool.Tool, args map[string]any) (map[string]any, error) {
					return map[string]any{"number": "3"}, nil
				},
			},
			AfterToolCallbacks: []llmagent.AfterToolCallback{
				func(ctx tool.Context, tool tool.Tool, args, result map[string]any, err error) (map[string]any, error) {
					return map[string]any{"number": "7"}, nil
				},
			},
		})
		if err != nil {
			t.Fatalf("failed to create LLM Agent: %v", err)
		}

		runner := testutil.NewTestAgentRunner(t, agent)
		stream := runner.Run(t, "session1", "Generate random number with 5 as a seed.")

		ans, err := testutil.CollectTextParts(stream)
		if err != nil || len(ans) == 0 {
			t.Fatalf("agent returned (%v, %v), want result", ans, err)
		}
		if got, want := strings.TrimSpace(ans[len(ans)-1]), "7"; got != want {
			t.Errorf("unexpected result from agent = (%v, %v), want ([%q], nil)", ans, err, want)
		}
	})

	t.Run("both_callbacks_return_nil_actual_tool_is_executed", func(t *testing.T) {
		model := newGeminiModel(t, modelName, nil)
		agent, err := llmagent.New(llmagent.Config{
			Name:                     "agent",
			Description:              "random agent",
			Model:                    model,
			Instruction:              "IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42",
			DisallowTransferToParent: true,
			DisallowTransferToPeers:  true,
			Tools:                    []tool.Tool{rand},
			BeforeToolCallbacks: []llmagent.BeforeToolCallback{
				func(ctx tool.Context, tool tool.Tool, args map[string]any) (map[string]any, error) {
					return nil, nil
				},
			},
			AfterToolCallbacks: []llmagent.AfterToolCallback{
				func(ctx tool.Context, tool tool.Tool, args, result map[string]any, err error) (map[string]any, error) {
					return nil, nil
				},
			},
		})
		if err != nil {
			t.Fatalf("failed to create LLM Agent: %v", err)
		}

		runner := testutil.NewTestAgentRunner(t, agent)
		stream := runner.Run(t, "session1", "Generate random number with 5 as a seed.")

		ans, err := testutil.CollectTextParts(stream)
		if err != nil || len(ans) == 0 {
			t.Fatalf("agent returned (%v, %v), want result", ans, err)
		}
		if got, want := strings.TrimSpace(ans[len(ans)-1]), "1"; got != want {
			t.Errorf("unexpected result from agent = (%v, %v), want ([%q], nil)", ans, err, want)
		}
	})
}

func TestInstructionProvider(t *testing.T) {
	t.Parallel()

	for _, tc := range []struct {
		name              string
		llmagentFunc      func(model.LLM) (agent.Agent, error)
		wantLLMRequests   []*model.LLMRequest
		wantAgentResponse []string
		wantErr           error
	}{
		{
			name: "instruction is evaluated",
			llmagentFunc: func(model model.LLM) (agent.Agent, error) {
				return llmagent.New(llmagent.Config{
					Name:        "test_agent",
					Model:       model,
					Instruction: "instruction {var} test",
				})
			},
			wantLLMRequests: []*model.LLMRequest{
				{
					Model: "mock",
					Contents: []*genai.Content{
						genai.NewContentFromText("user input", genai.RoleUser),
					},
					Config: &genai.GenerateContentConfig{
						SystemInstruction: &genai.Content{
							Parts: []*genai.Part{
								genai.NewPartFromText("instruction custom_value test\n\nYou are an agent. Your internal name is \"test_agent\"."),
							},
							Role: genai.RoleUser,
						},
					},
				},
			},
			wantAgentResponse: []string{
				"llm resp stub",
			},
		},
		{
			name: "instruction provider overrides instruction",
			llmagentFunc: func(model model.LLM) (agent.Agent, error) {
				return llmagent.New(llmagent.Config{
					Name:        "test_agent",
					Model:       model,
					Instruction: "instruction",
					InstructionProvider: func(ctx agent.ReadonlyContext) (string, error) {
						return "instruction provider template {var} not evaluated", nil
					},
				})
			},
			wantLLMRequests: []*model.LLMRequest{
				{
					Model: "mock",
					Contents: []*genai.Content{
						genai.NewContentFromText("user input", genai.RoleUser),
					},
					Config: &genai.GenerateContentConfig{
						SystemInstruction: &genai.Content{
							Parts: []*genai.Part{
								genai.NewPartFromText("instruction provider template {var} not evaluated\n\nYou are an agent. Your internal name is \"test_agent\"."),
							},
							Role: genai.RoleUser,
						},
					},
				},
			},
			wantAgentResponse: []string{
				"llm resp stub",
			},
		},
		{
			name: "global instruction provider overrides global instruction",
			llmagentFunc: func(model model.LLM) (agent.Agent, error) {
				return llmagent.New(llmagent.Config{
					Name:              "test_agent",
					Model:             model,
					GlobalInstruction: "instruction",
					GlobalInstructionProvider: func(ctx agent.ReadonlyContext) (string, error) {
						return "global instruction provider template {var} not evaluated", nil
					},
				})
			},
			wantLLMRequests: []*model.LLMRequest{
				{
					Model: "mock",
					Contents: []*genai.Content{
						genai.NewContentFromText("user input", genai.RoleUser),
					},
					Config: &genai.GenerateContentConfig{
						SystemInstruction: &genai.Content{
							Parts: []*genai.Part{
								genai.NewPartFromText("global instruction provider template {var} not evaluated\n\nYou are an agent. Your internal name is \"test_agent\"."),
							},
							Role: genai.RoleUser,
						},
					},
				},
			},
			wantAgentResponse: []string{
				"llm resp stub",
			},
		},
		{
			name: "global instruction provider merged with instruction provider",
			llmagentFunc: func(model model.LLM) (agent.Agent, error) {
				return llmagent.New(llmagent.Config{
					Name:  "test_agent",
					Model: model,
					InstructionProvider: func(ctx agent.ReadonlyContext) (string, error) {
						return "instruction provider {var}", nil
					},
					GlobalInstructionProvider: func(ctx agent.ReadonlyContext) (string, error) {
						return "global instruction provider {var}", nil
					},
				})
			},
			wantLLMRequests: []*model.LLMRequest{
				{
					Model: "mock",
					Contents: []*genai.Content{
						genai.NewContentFromText("user input", genai.RoleUser),
					},
					Config: &genai.GenerateContentConfig{
						SystemInstruction: &genai.Content{
							Parts: []*genai.Part{
								genai.NewPartFromText("global instruction provider {var}\n\ninstruction provider {var}\n\nYou are an agent. Your internal name is \"test_agent\"."),
							},
							Role: genai.RoleUser,
						},
					},
				},
			},
			wantAgentResponse: []string{
				"llm resp stub",
			},
		},
	} {
		t.Run(tc.name, func(t *testing.T) {
			model := &testutil.MockModel{
				Responses: []*genai.Content{
					genai.NewContentFromText("llm resp stub", genai.RoleModel),
				},
			}

			agent, err := tc.llmagentFunc(model)
			if err != nil {
				t.Fatalf("failed to create LLM Agent: %v", err)
			}

			testRunner := testutil.NewTestAgentRunner(t, agent)
			testRunner.SetInitSessionState(map[string]any{"var": "custom_value"})

			stream := testRunner.Run(t, "session", "user input")

			gotResp, err := testutil.CollectTextParts(stream)
			if err != nil {
				t.Fatalf("agent returned (%v, %v), want result", gotResp, err)
			}

			if diff := cmp.Diff(tc.wantLLMRequests, model.Requests); diff != "" {
				t.Errorf("unexpected LLM requests, want: %v, got: %v, diff: %v", tc.wantLLMRequests, model.Requests, diff)
			}

			if diff := cmp.Diff(tc.wantAgentResponse, gotResp); diff != "" {
				t.Errorf("unexpected agent response, want: %v, got: %v, diff: %v", tc.wantAgentResponse, gotResp, diff)
			}
		})
	}
}

func TestFunctionTool(t *testing.T) {
	model := newGeminiModel(t, modelName, nil)

	type Args struct {
		A int `json:"a"`
		B int `json:"b"`
	}
	type Result struct {
		Sum int `json:"sum"`
	}

	prompt := "what is the sum of 1 + 2?"
	handler := func(_ tool.Context, input Args) (Result, error) {
		if input.A != 1 || input.B != 2 {
			t.Errorf("handler received %+v, want {a: 1, b: 2}", input)
		}
		return Result{Sum: input.A + input.B}, nil
	}
	rand, _ := functiontool.New(functiontool.Config{
		Name:        "sum",
		Description: "computes the sum of two numbers",
	}, handler)

	agent, err := llmagent.New(llmagent.Config{
		Name:        "agent",
		Description: "math agent",
		Model:       model,
		Instruction: "IMPORTANT: output ONLY the result computed by the provided function, if the result of 10 + 32 is 42 print only 42",
		// TODO(hakim): set to false when autoflow is implemented.
		DisallowTransferToParent: true,
		DisallowTransferToPeers:  true,
		Tools:                    []tool.Tool{rand},
	})
	if err != nil {
		t.Fatalf("failed to create LLM Agent: %v", err)
	}

	runner := testutil.NewTestAgentRunner(t, agent)
	stream := runner.Run(t, "session1", prompt)

	ans, err := testutil.CollectTextParts(stream)
	if err != nil || len(ans) == 0 {
		t.Fatalf("agent returned (%v, %v), want result", ans, err)
	}
	if got, want := strings.TrimSpace(ans[len(ans)-1]), "3"; got != want {
		t.Errorf("unexpected result from agent = (%v, %v), want ([%q], nil)", ans, err, want)
	}
}

func TestAgentTransfer(t *testing.T) {
	// Helpers to create genai.Content conveniently.
	transferCall := func(agentName string) *genai.Content {
		return genai.NewContentFromFunctionCall(
			"transfer_to_agent",
			map[string]any{"agent_name": agentName},
			"model",
		)
	}
	transferResponse := func() *genai.Content {
		return genai.NewContentFromFunctionResponse(
			"transfer_to_agent", map[string]any{}, "user")
	}
	text := func(text string) *genai.Content {
		return genai.NewContentFromText(
			text,
			"model",
		)
	}
	// returns a model that returns the prepopulated resp one by one.
	testModel := func(resp ...*genai.Content) model.LLM {
		return &testutil.MockModel{Responses: resp}
	}

	type content struct {
		Author string
		Parts  []*genai.Part
	}
	// contents returns (Author, Parts) stream extracted from the event stream.
	contents := func(stream iter.Seq2[*session.Event, error]) ([]content, error) {
		var ret []content
		for ev, err := range stream {
			if err != nil {
				return nil, err
			}
			if ev.LLMResponse.Content == nil {
				return nil, fmt.Errorf("unexpected event: %v", ev)
			}
			for _, p := range ev.LLMResponse.Content.Parts {
				if p.FunctionCall != nil {
					p.FunctionCall.ID = ""
				}
				if p.FunctionResponse != nil {
					p.FunctionResponse.ID = ""
				}
			}
			ret = append(ret, content{Author: ev.Author, Parts: ev.LLMResponse.Content.Parts})
		}
		return ret, nil
	}

	check := func(t *testing.T, rootAgent agent.Agent, wants [][]content) {
		runner := testutil.NewTestAgentRunner(t, rootAgent)
		for i := range len(wants) {
			got, err := contents(runner.Run(t, "session_id", fmt.Sprintf("round %d", i)))
			if err != nil {
				t.Fatalf("[round $d]: stream ended with an error: %v", err)
			}
			if diff := cmp.Diff(wants[i], got); diff != "" {
				t.Errorf("[round %d] events diff (-want, +got) = %v", i, diff)
			}
		}
	}

	t.Run("auto_to_auto", func(t *testing.T) {
		// root_agent -- sub_agent_1
		model := testModel(
			transferCall("sub_agent_1"),
			text("response1"),
			text("response2"))

		subAgent1, err := llmagent.New(llmagent.Config{
			Name:  "sub_agent_1",
			Model: model,
		})
		if err != nil {
			t.Fatalf("failed to create subAgent1: %v", err)
		}

		rootAgent, err := llmagent.New(llmagent.Config{
			Name:      "root_agent",
			Model:     model,
			SubAgents: []agent.Agent{subAgent1},
		})
		if err != nil {
			t.Fatalf("failed to create rootAgent: %v", err)
		}

		check(t, rootAgent, [][]content{
			0: {
				{"root_agent", transferCall("sub_agent_1").Parts},
				{"root_agent", transferResponse().Parts},
				{"sub_agent_1", text("response1").Parts},
			},
			1: { // rootAgent should still be the current agent.
				{"sub_agent_1", text("response2").Parts},
			},
		})
	})

	t.Run("auto_to_single", func(t *testing.T) {
		// root_agent -- sub_agent_1 (single)
		model := testModel(
			transferCall("sub_agent_1"),
			text("response1"),
			text("response2"))

		subAgent1, err := llmagent.New(llmagent.Config{
			Name:                     "sub_agent_1",
			Model:                    model,
			DisallowTransferToParent: true,
			DisallowTransferToPeers:  true,
		})
		if err != nil {
			t.Fatalf("failed to create subAgent1: %v", err)
		}

		rootAgent, err := llmagent.New(llmagent.Config{
			Name:      "root_agent",
			Model:     model,
			SubAgents: []agent.Agent{subAgent1},
		})
		if err != nil {
			t.Fatalf("failed to create rootAgent: %v", err)
		}

		check(t, rootAgent, [][]content{
			0: {
				{"root_agent", transferCall("sub_agent_1").Parts},
				{"root_agent", transferResponse().Parts},
				{"sub_agent_1", text("response1").Parts},
			},
			1: { // rootAgent should still be the current agent.
				{"root_agent", text("response2").Parts},
			},
		})
	})

	t.Run("auto_to_auto_to_single", func(t *testing.T) {
		// root_agent -- sub_agent_1 -- sub_agent_1_1
		model := testModel(
			transferCall("sub_agent_1"),
			transferCall("sub_agent_1_1"),
			text("response1"),
			text("response2"))

		subAgent1_1, err := llmagent.New(llmagent.Config{
			Name:                     "sub_agent_1_1",
			Model:                    model,
			DisallowTransferToParent: true,
			DisallowTransferToPeers:  true,
		})
		if err != nil {
			t.Fatalf("failed to create subAgent1_1: %v", err)
		}

		subAgent1, err := llmagent.New(llmagent.Config{
			Name:      "sub_agent_1",
			Model:     model,
			SubAgents: []agent.Agent{subAgent1_1},
		})
		if err != nil {
			t.Fatalf("failed to create subAgent1: %v", err)
		}

		rootAgent, err := llmagent.New(llmagent.Config{
			Name:      "root_agent",
			Model:     model,
			SubAgents: []agent.Agent{subAgent1},
		})
		if err != nil {
			t.Fatalf("failed to create rootAgent: %v", err)
		}

		check(t, rootAgent, [][]content{
			0: {
				{"root_agent", transferCall("sub_agent_1").Parts},
				{"root_agent", transferResponse().Parts},
				{"sub_agent_1", transferCall("sub_agent_1_1").Parts},
				{"sub_agent_1", transferResponse().Parts},
				{"sub_agent_1_1", text("response1").Parts},
			},
			1: {
				// sub_agent_1 should still be the current agent.
				// sub_agent_1_1 is single, so it should not be the current agent.
				// Otherwise, the conversation will be tied to sub_agent_1_1 forever.
				{"sub_agent_1", text("response2").Parts},
			},
		})
	})

	// TODO: cover cases similar to adk-python's
	// tests/unittests/flows/llm_flows/test_agent_transfer.py
	//   - test_auto_to_sequential
	//   - test_auto_to_sequential_to_auto
	//   - test_auto_to_loop
}

func newGeminiModel(t *testing.T, modelName string, transport http.RoundTripper) model.LLM {
	cfg := &genai.ClientConfig{
		HTTPClient: &http.Client{Transport: transport},
		APIKey:     "fakeKey",
	}
	if transport == nil { // use httprr
		trace := filepath.Join("testdata", strings.ReplaceAll(t.Name()+".httprr", "/", "_"))
		cfg = testutil.NewGeminiTestClientConfig(t, trace)
	}
	model, err := gemini.NewModel(t.Context(), modelName, cfg)
	if err != nil {
		t.Fatalf("failed to create model: %v", err)
	}
	return model
}

type roundTripperFunc func(*http.Request) (*http.Response, error)

// RoundTrip implements http.RoundTripper.
func (fn roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {
	return fn(req)
}


================================================
FILE: agent/llmagent/state_agent_test.go
================================================
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package llmagent_test

import (
	"context"
	"fmt"
	"iter"
	"maps"
	"math"
	"math/rand"
	"strings"
	"testing"
	"time"

	"google.golang.org/genai"

	"google.golang.org/adk/agent"
	"google.golang.org/adk/agent/llmagent"
	"google.golang.org/adk/model"
	"google.golang.org/adk/runner"
	"google.golang.org/adk/session"
	"google.golang.org/adk/tool"
	"google.golang.org/adk/tool/functiontool"
)

// FakeLLM is a mock implementation of model.LLM for testing.
type FakeLLM struct {
	GenerateContentFunc func(ctx context.Context, req *model.LLMRequest, stream bool) (model.LLMResponse, error)
}

func (f *FakeLLM) Name() string {
	return "fake-llm"
}

func (f *FakeLLM) GenerateContent(ctx context.Context, req *model.LLMRequest, stream bool) iter.Seq2[*model.LLMResponse, error] {
	return func(yield func(*model.LLMResponse, error) bool) {
		if f.GenerateContentFunc != nil {
			resp, err := f.GenerateContentFunc(ctx, req, stream)
			yield(&resp, err)
		} else {
			// Default response
			yield(&model.LLMResponse{
				Content: genai.NewContentFromText("fake model response", genai.RoleModel),
			}, nil)
		}
	}
}

var testSessionService session.Service

type assertSessionParams struct {
	title                   string
	keysInCtxSession        []string
	keysInServiceSession    []string
	keysNotInServiceSession []string
}

func assertSessionValues(
	t *testing.T,
	cctx agent.CallbackContext,
	params *assertSessionParams,
) {
	t.Helper()

	getRequest := &session.GetRequest{
		AppName:   cctx.AppName(),
		UserID:    cctx.UserID(),
		SessionID: cctx.SessionID(),
	}
	getResponse, err := testSessionService.Get(cctx, getRequest)
	if err != nil {
		t.Fatalf("[%s] Failed to get session from service: %v", params.title, err)
	}
	sessionInService := getResponse.Session

	for _, key := range params.keysInCtxSession {
		if _, err := cctx.State().Get(key); err != nil {
			t.Errorf("[%s] Key %s not found in context session state: %v", params.title, key, err)
		}
	}

	for _, key := range params.keysInServiceSession {
		if _, err := sessionInService.State().Get(key); err != nil {
			t.Errorf("[%s] Key %s not found in service session state: %v", params.title, key, err)
		}
	}

	for _, key := range params.keysNotInServiceSession {
		if val, err := sessionInService.State().Get(key); err == nil {
			t.Errorf("[%s] Key %s unexpectedly found in service session state with value: %v", params.title, key, val)
		}
	}
}

// --- Callbacks (Modified to use *testing.T) ---
func beforeAgentCallback(t *testing.T) agent.BeforeAgentCallback {
	return func(cctx agent.CallbackContext) (*genai.Content, error) {
		if _, err := cctx.State().Get("before_agent_callback_state_key"); err == nil {
			return genai.NewContentFromText("Sorry, I can only reply once.", genai.RoleModel), nil
		}
		if err := cctx.State().Set("before_agent_callback_state_key", "before_agent_callback_state_value"); err != nil {
			return nil, fmt.Errorf("failed to set state: %w", err)
		}
		assertSessionValues(t, cctx, &assertSessionParams{
			title:                   "In before_agent_callback",
			keysInCtxSession:        []string{"before_agent_callback_state_key"},
			keysInServiceSession:    []string{},
			keysNotInServiceSession: []string{"before_agent_callback_state_key"},
		},
		)
		return nil, nil
	}
}

func beforeModelCallback(t *testing.T) func(ctx agent.CallbackContext, llmRequest *model.LLMRequest) (*model.LLMResponse, error) {
	return func(cctx agent.CallbackContext, llmRequest *model.LLMRequest) (*model.LLMResponse, error) {
		if err := cctx.State().Set("before_model_callback_state_key", "before_model_callback_state_value"); err != nil {
			return nil, fmt.Errorf("failed to set state: %w", err)
		}
		assertSessionValues(t, cctx, &assertSessionParams{
			title:                   "In before_model_callback",
			keysInCtxSession:        []string{"before_agent_callback_state_key", "before_model_callback_state_key"},
			keysInServiceSession:    []string{"before_agent_callback_state_key"},
			keysNotInServiceSession: []string{"before_model_callback_state_key"},
		},
		)
		return nil, nil
	}
}

func afterModelCallback(t *testing.T) func(ctx agent.CallbackContext, llmResponse *model.LLMResponse, llmResponseError error) (*model.LLMResponse, error) {
	return func(cctx agent.CallbackContext, llmResponse *model.LLMResponse, err error) (*model.LLMResponse, error) {
		if err := cctx.State().Set("after_model_callback_state_key", "after_model_callback_state_value"); err != nil {
			return nil, fmt.Errorf("failed to set state: %w", err)
		}
		assertSessionValues(t, cctx, &assertSessionParams{
			title:                   "In after_model_callback",
			keysInCtxSession:        []string{"before_agent_callback_state_key", "before_model_callback_state_key", "after_model_callback_state_key"},
			keysInServiceSession:    []string{"before_agent_callback_state_key"},
			keysNotInServiceSession: []string{"before_model_callback_state_key", "after_model_callback_state_key"},
		},
		)
		return nil, nil
	}
}

func afterAgentCallback(t *testing.T) agent.AfterAgentCallback {
	return func(cctx agent.CallbackContext) (*genai.Content, error) {
		if err := cctx.State().Set("after_agent_callback_state_key", "after_agent_callback_state_value"); err != nil {
			return nil, fmt.Errorf("failed to set state: %w", err)
		}
		assertSessionValues(t, cctx, &assertSessionParams{
			title:                   "In after_agent_callback",
			keysInCtxSession:        []string{"before_agent_callback_state_key", "before_model_callback_state_key", "after_model_callback_state_key", "after_agent_callback_state_key"},
			keysInServiceSession:    []string{"before_agent_callback_state_key", "before_model_callback_state_key", "after_model_callback_state_key"},
			keysNotInServiceSession: []string{"after_agent_callback_state_key"},
		},
		)
		return nil, nil
	}
}

func TestAgentSessionLifecycle(t *testing.T) {
	ctx := context.Background()
	testSessionService = session.InMemoryService()

	// Setup Fake LLM
	fakeLLM := &FakeLLM{
		GenerateContentFunc: func(ctx context.Context, req *model.LLMRequest, stream bool) (model.LLMResponse, error) {
			return model.LLMResponse{
				Content: genai.NewContentFromText("test model response", genai.RoleModel),
			}, nil
		},
	}

	// Define Agent
	rootAgent, err := llmagent.New(llmagent.Config{
		Name:                 "root_agent",
		Description:          "a verification agent.",
		Instruction:          "Test instruction",
		Model:                fakeLLM,
		BeforeAgentCallbacks: []agent.BeforeAgentCallback{beforeAgentCallback(t)},
		BeforeModelCallbacks: []llmagent.BeforeModelCallback{beforeModelCallback(t)},
		AfterModelCallbacks:  []llmagent.AfterModelCallback{afterModelCallback(t)},
		AfterAgentCallbacks:  []agent.AfterAgentCallback{afterAgentCallback(t)},
	})
	if err != nil {
		t.Fatalf("Failed to create agent: %v", err)
	}

	// Setup Runner
	// Note: This Runner setup is a simplified guess. Actual implementation might need more services.
	r, err := runner.New(runner.Config{
		AppName:        "test_app",
		Agent:          rootAgent,
		SessionService: testSessionService,
	})
	if err != nil {
		t.Fatalf("Failed to create runner: %v", err)
	}

	// Create a session
	createReq := &session.CreateRequest{AppName: "test_app", UserID: "test_user"}
	createResp, err := testSessionService.Create(ctx, createReq)
	if err != nil {
		t.Fatalf("Failed to create session: %v", err)
	}
	sessionID := createResp.Session.ID()

	// Run the agent
	userContent := genai.NewContentFromText("Hello agent", genai.RoleUser)

	eventStream := r.Run(ctx, "test_user", sessionID, userContent, agent.RunConfig{})

	// Iterate through events to trigger agent execution
	for _, err := range eventStream {
		if err != nil {
			t.Fatalf("Error during agent run: %v", err)
		}
	}

	// Final check of persisted state
	finalSession, _ := testSessionService.Get(ctx, &session.GetRequest{AppName: "test_app", UserID: "test_user", SessionID: sessionID})
	finalState := finalSession.Session.State()
	expectedKeys := []string{
		"before_agent_callback_state_key",
		"before_model_callback_state_key",
		"after_model_callback_state_key",
		"after_agent_callback_state_key",
	}
	for _, key := range expectedKeys {
		if _, err := finalState.Get(key); err != nil {
			t.Errorf("Key %s not found in final session state: %v", key, err)
		}
	}
}

// --- Tool Implementations ---

type WeatherArgs struct {
	Location string `json:"location"`
}

type WeatherResult struct {
	Location    string    `json:"location"`
	Temperature int       `json:"temperature"`
	Condition   string    `json:"condition"`
	Humidity    int       `json:"humidity"`
	Timestamp   time.Time `json:"timestamp"`
}

func GetWeather(ctx tool.Context, args WeatherArgs) (WeatherResult, error) {
	// Simulate weather data
	temperatures := []int{-10, -5, 0, 5, 10, 15, 20, 25, 30, 35}
	conditions := []string{"sunny", "cloudy", "rainy", "snowy", "windy"}

	return WeatherResult{
		Location:    args.Location,
		Temperature: temperatures[rand.Intn(len(temperatures))],
		Condition:   conditions[rand.Intn(len(conditions))],
		Humidity:    rand.Intn(61) + 30, // 30-90
		Timestamp:   time.Now(),
	}, nil
}

type CalculationArgs struct {
	Operation string  `json:"operation"`
	X         float64 `json:"x"`
	Y         float64 `json:"y"`
}

type CalculationResult struct {
	Operation string    `json:"operation"`
	X         float64   `json:"x"`
	Y         float64   `json:"y"`
	Result    any       `json:"result"`
	Timestamp time.Time `json:"timestamp"`
}

func Calculate(ctx tool.Context, args CalculationArgs) (CalculationResult, error) {
	operations := map[string]float64{
		"add":      args.X + args.Y,
		"subtract": args.X - args.Y,
		"multiply": args.X * args.Y,
	}
	if args.Operation == "divide" {
		if args.Y != 0 {
			operations["divide"] = args.X / args.Y
		} else {
			operations["divide"] = math.Inf(int(args.X))
		}
	}

	result, ok := operations[strings.ToLower(args.Operation)]
	if !ok {
		return CalculationResult{
			Operation: args.Operation,
			X:         args.X,
			Y:         args.Y,
			Result:    "Unknown operation",
			Timestamp: time.Now(),
		}, nil
	}

	return CalculationResult{
		Operation: args.Operation,
		X:         args.X,
		Y:         args.Y,
		Result:    result,
		Timestamp: time.Now(),
	}, nil
}

type LogActivityParams struct {
	Message string `json:"message"`
}

type LogEntry struct {
	Timestamp time.Time `json:"timestamp"`
	Message   string    `json:"message"`
}

type LogActivityResult struct {
	Status       string   `json:"status"`
	Entry        LogEntry `json:"entry"`
	TotalEntries int      `json:"total_entries"`
	err          error
}

func LogActivity(ctx tool.Context, params LogActivityParams) (LogActivityResult, error) {
	var activityLog []LogEntry
	val, err := ctx.State().Get("activity_log")
	if err == nil {
		activityLog, _ = val.([]LogEntry)
	}

	logEntry := LogEntry{Timestamp: time.Now(), Message: params.Message}
	activityLog = append(activityLog, logEntry)
	if err := ctx.State().Set("activity_log", activityLog); err != nil {
		return LogActivityResult{
			err: err,
		}, err
	}

	return LogActivityResult{
		Status:       "logged",
		Entry:        logEntry,
		TotalEntries: len(activityLog),
		err:          nil,
	}, nil
}

// --- Before Tool Callbacks ---

func beforeToolAuditCallback(ctx tool.Context, t tool.Tool, args map[string]any) (map[string]any, error) {
	fmt.Printf("🔍 AUDIT: About to call tool '%s' with args: %v\n", t.Name(), args)

	var auditLog []map[string]any
	val, err := ctx.State().Get("audit_log")
	if err == nil {
		auditLog, _ = val.([]map[string]any)
	}

	auditLog = append(auditLog, map[string]any{
		"type":      "before_call",
		"tool_name": t.Name(),
		"args":      args,
		"timestamp": time.Now(),
	})
	if err := ctx.State().Set("audit_log", auditLog); err != nil {
		return nil, err
	}
	return nil, nil // Continue execution
}

func beforeToolSecurityCallback(ctx tool.Context, t tool.Tool, args map[string]any) (map[string]any, error) {
	if t.Name() == "get_weather" {
		location := ""
		if loc, ok := args["location"].(string); ok {
			location = loc
		}
		restricted := []string{"classified", "secret"}
		for _, r := range restricted {
			if strings.ToLower(location) == r {
				fmt.Printf("🚫 SECURITY: Blocked weather request for restricted location: %s\n", location)
				if err := ctx.State().Set("security_log", "example"); err != nil {
					return nil, err
				}
				return map[string]any{
					"error":              "Access denied",
					"reason":             "Location access is restricted",
					"requested_location": location,
				}, nil // Block execution
			}
		}
	}
	return nil, nil // Continue execution
}

func beforeToolValidationCallback(ctx tool.Context, t tool.Tool, args map[string]any) (map[string]any, error) {
	if t.Name() == "calculate" {
		operation, _ := args["operation"].(string)
		y, yOK := args["y"].(float64)
		if strings.ToLower(operation) == "divide" && yOK && y == 0 {
			fmt.Println("🚫 VALIDATION: Prevented division by zero")
			return map[string]any{
				"error":     "Division by zero",
				"operation": operation,
				"x":         args["x"],
				"y":         args["y"],
			}, nil // Block execution
		}
	}
	return nil, nil // Continue execution
}

// --- After Tool Callbacks ---

func afterToolEnhancementCallback(ctx tool.Context, t tool.Tool, args, result map[string]any, err error) (map[string]any, error) {
	if err != nil {
		return result, err // Don't enhance if there was an error
	}
	fmt.Printf("✨ ENHANCE: Adding metadata to response from '%s'\n", t.Name())
	enhancedResponse := make(map[string]any)
	maps.Copy(enhancedResponse, result)
	enhancedResponse["enhanced"] = true
	enhancedResponse["enhancement_timestamp"] = time.Now()
	enhancedResponse["tool_name"] = t.Name()
	enhancedResponse["execution_context"] = "live_streaming"
	return enhancedResponse, nil
}

func afterToolAsyncCallback(ctx tool.Context, t tool.Tool, args, result map[string]any, err error) (map[string]any, error) {
	if err != nil {
		return result, err
	}
	fmt.Printf("🔄 ASYNC AFTER: Post-processing response from '%s'\n", t.Name())
	processedResponse := make(map[string]any)
	maps.Copy(processedResponse, result)
	processedResponse["async_processed"] = true
	processedResponse["processor"] = "async_after_callback"
	return processedResponse, nil
}

// --- Test Function ---

// --- Helper function to collect tool results ---
func collectToolResults(t *testing.T, stream iter.Seq2[*session.Event, error]) []map[string]any {
	t.Helper()
	var results []map[string]any
	for event, err := range stream {
		if err != nil {
			t.Fatalf("Error iterating through event stream: %v", err)
		}
		if event == nil || event.Content == nil {
			continue
		}

		for _, part := range event.Content.Parts {
			if part.FunctionResponse != nil {
				if part.FunctionResponse.Response != nil {
					results = append(results, part.FunctionResponse.Response)
				}
			}
		}
	}
	return results
}

func TestToolCallbacksAgent(t *testing.T) {
	// Fake LLM to control tool calls
	ctx := t.Context()
	service := session.InMemoryService()

	fakeLLM := &FakeLLM{
		GenerateContentFunc: func(ctx context.Context, req *model.LLMRequest, stream bool) (model.LLMResponse, error) {
			var userText string
			if len(req.Contents) == 1 && len(req.Contents[0].Parts) > 0 {
				userText = string(req.Contents[0].Parts[0].Text)
			} else if len(req.Contents) > 1 {
				userText = "after func"
			}

			var name string
			var args map[string]any
			switch userText {
			case "weather in London":
				name, args = "get_weather", map[string]any{"location": "London"}
			case "weather in secret":
				name, args = "get_weather", map[string]any{"location": "secret"}
			case "calculate 5 plus 3":
				name, args = "calculate", map[string]any{"operation": "add", "x": 5.0, "y": 3.0}
			case "calculate 5 divide by 0":
				name, args = "calculate", map[string]any{"operation": "divide", "x": 5.0, "y": 0.0}
			case "log this message":
				name, args = "log_activity", map[string]any{"message": "test log"}
			case "after func":
				return model.LLMResponse{
					Content: genai.NewContentFromText("Function Ended", genai.RoleModel),
				}, nil
			default:
				return model.LLMResponse{
					Content: genai.NewContentFromText("I'm not sure how to respond to that.", genai.RoleModel),
				}, nil
			}

			return model.LLMResponse{
				Content: genai.NewContentFromFunctionCall(name, args, genai.RoleModel),
			}, nil
		},
	}

	// Create tools
	getWeatherTool, _ := functiontool.New(functiontool.Config{Name: "get_weather", Description: "Get weather information"}, GetWeather)
	calculateTool, _ := functiontool.New(functiontool.Config{Name: "calculate", Description: "Perform mathematical calculations"}, Calculate)
	logActivityTool, _ := functiontool.New(functiontool.Config{Name: "log_activity", Description: "Log an activity message"}, LogActivity)

	agentConfig := llmagent.Config{
		Name:        "tool_callbacks_agent",
		Description: "Agent to test tool callbacks",
		Model:       fakeLLM,
		Instruction: "Follow user instructions to call tools.",
		Tools:       []tool.Tool{getWeatherTool, calculateTool, logActivityTool},
		BeforeToolCallbacks: []llmagent.BeforeToolCallback{
			beforeToolAuditCallback,
			beforeToolSecurityCallback,
			beforeToolValidationCallback,
		},
		AfterToolCallbacks: []llmagent.AfterToolCallback{
			afterToolEnhancementCallback,
			afterToolAsyncCallback,
		},
	}
	rootAgent, err := llmagent.New(agentConfig)
	if err != nil {
		t.Fatalf("Failed to create LLM Agent: %v", err)
	}

	// Setup Runner
	// Note: This Runner setup is a simplified guess. Actual implementation might need more services.
	r, err := runner.New(runner.Config{
		AppName:        "test_app",
		Agent:          rootAgent,
		SessionService: service,
	})
	if err != nil {
		t.Fatalf("Failed to create runner: %v", err)
	}

	tests := []struct {
		name            string
		query           string
		wantContent     []string // Substrings to check in the final response
		dontWantContent []string
		wantStateKeys   []string
	}{
		{
			name:            "Weather London - success",
			query:           "weather in London",
			wantContent:     []string{"London", "temperature", "enhanced:true"},
			dontWantContent: []string{"async_processed"},
		},
		{
			name:          "Weather Secret - blocked",
			query:         "weather in secret",
			wantContent:   []string{"Access denied", "Location access is restricted", "enhanced:true"}, // Callbacks still run on the error result
			wantStateKeys: []string{"security_log"},
		},
		{
			name:        "Calculate Add - success",
			query:       "calculate 5 plus 3",
			wantContent: []string{"operation:add", "result:8", "enhanced:true"},
		},
		{
			name:        "Calculate Divide by Zero - blocked",
			query:       "calculate 5 divide by 0",
			wantContent: []string{"Division by zero", "enhanced:true"}, // Callbacks still run
		},
		{
			name:          "Log Activity - success",
			query:         "log this message",
			wantContent:   []string{"status:logged", "total_entries:1", "enhanced:true"},
			wantStateKeys: []string{"activity_log"},
		},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			// Create a session
			createReq := &session.CreateRequest{AppName: "test_app", UserID: "test_user"}
			createResp, err := service.Create(ctx, createReq)
			if err != nil {
				t.Fatalf("Failed to create session: %v", err)
			}
			sessionID := createResp.Session.ID()

			userContent := genai.NewContentFromText(tc.query, genai.RoleUser) // Session ID based on test name
			eventStream := r.Run(ctx, "test_user", sessionID, userContent, agent.RunConfig{})

			toolResults := collectToolResults(t, eventStream)

			if len(toolResults) == 0 {
				t.Fatalf("Expected tool results, got none")
			}
			lastResult := toolResults[len(toolResults)-1]

			// Check for expected content in the string representation of the result
			resultStr := fmt.Sprintf("%v", lastResult)
			for _, want := range tc.wantContent {
				if !strings.Contains(resultStr, want) {
					t.Errorf("Expected content %q not found in tool result: %s", want, resultStr)
				}
			}
			for _, dontWant := range tc.dontWantContent {
				if strings.Contains(resultStr, dontWant) {
					t.Errorf("Unexpected content %q found in tool result: %s", dontWant, resultStr)
				}
			}

			// Check state for log activity
			if len(tc.wantStateKeys) > 0 {
				currentSession, err := service.Get(context.Background(), &session.GetRequest{
					AppName:   "test_app",
					UserID:    "test_user",
					SessionID: sessionID,
				})
				if err != nil {
					t.Fatalf("Failed to get session: %v", err)
				}
				for _, key := range tc.wantStateKeys {
					if _, err := currentSession.Session.State().Get(key); err != nil {
						t.Errorf("Expected key %q not found in session state", key)
					}
				}
			}
		})
	}
}


================================================
FILE: agent/llmagent/testdata/TestFunctionTool.httprr
================================================
httprr trace v1
980 1354
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 748
Content-Type: application/json

{"contents":[{"parts":[{"text":"what is the sum of 1 + 2?"}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result of 10 + 32 is 42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"math agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"computes the sum of two numbers","name":"sum","parametersJsonSchema":{"additionalProperties":false,"properties":{"a":{"type":"integer"},"b":{"type":"integer"}},"required":["a","b"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"sum":{"type":"integer"}},"required":["sum"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:57:34 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=922
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "functionCall": {
              "name": "sum",
              "args": {
                "a": 1,
                "b": 2
              }
            },
            "thoughtSignature": "CssBAb4+9vtA0YNySGDhNbWUekpgT0C4JzfoLAMCUxxSlERpI2LVij53p/T9qWJSHxNvQmxdYycF8yf/oRMZ0cnD1wKxww2tYiJpDtgJXwJRLKNaB6YpvNLH7gbW/3Sd2qNzdOlcbbenmh6gYBvjrngYKV8PYSoGj58y7BmJ7bpdwar93Q+wTGQNaeJLQeAJM+KqpF1IB6fZWk4EtotwxKnePkkMgFtwFGYXOZQjhnCudMJprOkORFhhoF4mujrSVU9uqWAIpkhahJn6d2I="
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0,
      "finishMessage": "Model generated function call(s)."
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 155,
    "candidatesTokenCount": 18,
    "totalTokenCount": 223,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 155
      }
    ],
    "thoughtsTokenCount": 50
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "XTGwabD8KpaxkdUP3MTwoAk"
}
1442 815
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 1209
Content-Type: application/json

{"contents":[{"parts":[{"text":"what is the sum of 1 + 2?"}],"role":"user"},{"parts":[{"functionCall":{"args":{"a":1,"b":2},"name":"sum"},"thoughtSignature":"CssBAb4+9vtA0YNySGDhNbWUekpgT0C4JzfoLAMCUxxSlERpI2LVij53p/T9qWJSHxNvQmxdYycF8yf/oRMZ0cnD1wKxww2tYiJpDtgJXwJRLKNaB6YpvNLH7gbW/3Sd2qNzdOlcbbenmh6gYBvjrngYKV8PYSoGj58y7BmJ7bpdwar93Q+wTGQNaeJLQeAJM+KqpF1IB6fZWk4EtotwxKnePkkMgFtwFGYXOZQjhnCudMJprOkORFhhoF4mujrSVU9uqWAIpkhahJn6d2I="}],"role":"model"},{"parts":[{"functionResponse":{"name":"sum","response":{"sum":3}}}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result of 10 + 32 is 42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"math agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"computes the sum of two numbers","name":"sum","parametersJsonSchema":{"additionalProperties":false,"properties":{"a":{"type":"integer"},"b":{"type":"integer"}},"required":["a","b"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"sum":{"type":"integer"}},"required":["sum"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:57:35 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=571
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "3"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 186,
    "candidatesTokenCount": 1,
    "totalTokenCount": 187,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 186
      }
    ]
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "XjGwaaPEI_H3nsEP2v-88AQ"
}


================================================
FILE: agent/llmagent/testdata/TestLLMAgentStreamingModeSSE.httprr
================================================
httprr trace v1
648 8944
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 402
Content-Type: application/json

{"contents":[{"parts":[{"text":"What is the sum of the first 50 prime numbers?"}],"role":"user"}],"generationConfig":{"thinkingConfig":{"includeThoughts":true}},"systemInstruction":{"parts":[{"text":"Think deep. Always double check the answer before making the conclusion.\n\nYou are an agent. Your internal name is \"calculator\". The description about you is \"calculating agent\"."}],"role":"user"}}HTTP/2.0 200 OK
Connection: close
Content-Disposition: attachment
Content-Type: text/event-stream
Date: Tue, 10 Mar 2026 14:57:56 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=1828
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

data: {"candidates": [{"content": {"parts": [{"text": "**Calculating Prime Sum**\n\nI've begun working on this problem by identifying the need to sum the first 50 prime numbers. I've started listing them and have got through the first 16. The next step is to compute the rest of the list, verify the number of entries, and then calculate the sum.\n\n\n","thought": true}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"totalTokenCount": 165,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 114},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": "**Summing Prime Numbers**\n\nI've completed the list of the first 50 prime numbers and meticulously summed them in groups of ten. After verifying each subtotal, I've calculated the final sum, which I believe is 5117. I'll double-check everything, including the list and the sums.\n\n\n","thought": true}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"totalTokenCount": 896,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 845},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": "**Verifying Prime Sum**\n\nI've meticulously recalculated the sum of the first 50 prime numbers to confirm my previous total. After a careful re-evaluation of the list and individual group sums, I can confidently confirm that the total is indeed 5117. The analysis has concluded, and I stand by my answer.\n\n\n","thought": true}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"totalTokenCount": 1285,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": "To find the sum of the first 50 prime numbers, I first need to list them and then add them up.\n\nThe first 50 prime numbers are:\n1.  2\n2.  3\n3"}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 44,"totalTokenCount": 1329,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": ".  5\n4.  7\n5.  11\n6.  13\n7.  17\n8.  19\n9.  23\n10. 29\n11"}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 92,"totalTokenCount": 1377,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": ". 31\n12. 37\n13. 41\n14. 43\n15. 47\n16. 53\n17. 59\n1"}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 140,"totalTokenCount": 1425,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": "8. 61\n19. 67\n20. 71\n21. 73\n22. 79\n23. 83\n24. 89\n"}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 187,"totalTokenCount": 1472,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": "25. 97\n26. 101\n27. 103\n28. 107\n29. 109\n30. 113\n3"}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 235,"totalTokenCount": 1520,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": "1. 127\n32. 131\n33. 137\n34. 139\n35. 149\n36. 151\n3"}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 283,"totalTokenCount": 1568,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": "7. 157\n38. 163\n39. 167\n40. 173\n41. 179\n42. 181\n4"}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 331,"totalTokenCount": 1616,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": "3. 191\n44. 193\n45. 197\n46. 199\n47. 211\n48. 223\n4"}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 379,"totalTokenCount": 1664,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": "9. 227\n50. 229\n\nNow, let's sum them:\nSum (1-10) = 2 + 3 + 5 + 7 + 11 + 13"}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 430,"totalTokenCount": 1715,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": " + 17 + 19 + 23 + 29 = 129\nSum (11-20) = 31 + 37 + 41 + 43 + "}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 477,"totalTokenCount": 1762,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": "47 + 53 + 59 + 61 + 67 + 71 = 510\nSum (21-30) = 73 + 79 + 83"}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 525,"totalTokenCount": 1810,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": " + 89 + 97 + 101 + 103 + 107 + 109 + 113 = 954\nSum (31-40) ="}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 573,"totalTokenCount": 1858,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": " 127 + 131 + 137 + 139 + 149 + 151 + 157 + 163 + 167 + 17"}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 620,"totalTokenCount": 1905,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": "3 = 1494\nSum (41-50) = 179 + 181 + 191 + 193 + 197 + 199 + "}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 667,"totalTokenCount": 1952,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": "211 + 223 + 227 + 229 = 2030\n\nTotal Sum = 129 + 510 + 954 + 1494"}],"role": "model"},"index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 715,"totalTokenCount": 2000,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}

data: {"candidates": [{"content": {"parts": [{"text": " + 2030 = 5117\n\nThe sum of the first 50 prime numbers is 5117."}],"role": "model"},"finishReason": "STOP","index": 0}],"usageMetadata": {"promptTokenCount": 51,"candidatesTokenCount": 745,"totalTokenCount": 2030,"promptTokensDetails": [{"modality": "TEXT","tokenCount": 51}],"thoughtsTokenCount": 1234},"modelVersion": "gemini-2.5-flash","responseId": "cjGwadCGE7yvnsEP3tfsiQk"}



================================================
FILE: agent/llmagent/testdata/TestLLMAgent_healthy_backend.httprr
================================================
httprr trace v1
618 845
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 386
Content-Type: application/json

{"contents":[{"parts":[{"text":"Handle the requests as specified in the System Instruction."}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"Answer as precisely as possible.\n\nRoll the dice and report only the result.\n\nYou are an agent. Your internal name is \"hello_world_agent\". The description about you is \"hello world agent\"."}],"role":"user"}}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:58:30 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=1591
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "4"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 55,
    "candidatesTokenCount": 1,
    "totalTokenCount": 307,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 55
      }
    ],
    "thoughtsTokenCount": 251
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "lDGwaarTJd-unsEP-NWk0QU"
}


================================================
FILE: agent/llmagent/testdata/TestToolCallback_after_callback_response_used.httprr
================================================
httprr trace v1
976 1549
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 744
Content-Type: application/json

{"contents":[{"parts":[{"text":"Generate random number with 5 as a seed."}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"random agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"returns random number","name":"rand_number","parametersJsonSchema":{"additionalProperties":false,"properties":{"seed":{"type":"integer"}},"required":["seed"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"number":{"type":"integer"}},"required":["number"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:52:41 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=718
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "functionCall": {
              "name": "rand_number",
              "args": {
                "seed": 5
              }
            },
            "thoughtSignature": "CugCAb4+9vvc6qwu6MEzNuTOUy3EF0pFEtUyVr37qpYQ8/yuGK1RAiRRUl86Myw+fwxbjZ1tY0w2LBDFZxmUZlUStf8C0ccspZu9BQ1qi1C4NQEMQ1JyVTMoeR+T+rCmc9i6/VNR8MC2Yz4cU+o9pKP8wxDJejRGLvrXCjN4JSbhDf97qFRrtAoYtU834NexLmcQJG6RCSPLc0TL8AYVbwrKyiH5qgItuLnpbnbUlrwHzBZeZeyYigBqXbR2nQRCGeflVJ1Hi0n75B1hSbbdDKu6CkzDIWcNBzU9y7xJjv5Kt4J0EhzqZys4e2NZUKFfFhxGssQ5h/1GX+vtAlG0AJ9KzRg6yr5tsMW1RhibbVfMa8J/HkMouTz1pUMbbd9zTIBiEM1GGjIGTPjeMKeVSNyYRgYuHguwMbhy6lnB8xG0XI+MCPKyxAHLMJ47Fx+o3wvT3iRaDbzoAEnBxIEa+los8uM9QSAHAsJ6"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0,
      "finishMessage": "Model generated function call(s)."
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 136,
    "candidatesTokenCount": 15,
    "totalTokenCount": 227,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 136
      }
    ],
    "thoughtsTokenCount": 76
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "ODCwaZyQMcuXkdUP28zB2As"
}
1664 815
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 1431
Content-Type: application/json

{"contents":[{"parts":[{"text":"Generate random number with 5 as a seed."}],"role":"user"},{"parts":[{"functionCall":{"args":{"seed":5},"name":"rand_number"},"thoughtSignature":"CugCAb4+9vvc6qwu6MEzNuTOUy3EF0pFEtUyVr37qpYQ8/yuGK1RAiRRUl86Myw+fwxbjZ1tY0w2LBDFZxmUZlUStf8C0ccspZu9BQ1qi1C4NQEMQ1JyVTMoeR+T+rCmc9i6/VNR8MC2Yz4cU+o9pKP8wxDJejRGLvrXCjN4JSbhDf97qFRrtAoYtU834NexLmcQJG6RCSPLc0TL8AYVbwrKyiH5qgItuLnpbnbUlrwHzBZeZeyYigBqXbR2nQRCGeflVJ1Hi0n75B1hSbbdDKu6CkzDIWcNBzU9y7xJjv5Kt4J0EhzqZys4e2NZUKFfFhxGssQ5h/1GX+vtAlG0AJ9KzRg6yr5tsMW1RhibbVfMa8J/HkMouTz1pUMbbd9zTIBiEM1GGjIGTPjeMKeVSNyYRgYuHguwMbhy6lnB8xG0XI+MCPKyxAHLMJ47Fx+o3wvT3iRaDbzoAEnBxIEa+los8uM9QSAHAsJ6"}],"role":"model"},{"parts":[{"functionResponse":{"name":"rand_number","response":{"number":"7"}}}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"random agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"returns random number","name":"rand_number","parametersJsonSchema":{"additionalProperties":false,"properties":{"seed":{"type":"integer"}},"required":["seed"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"number":{"type":"integer"}},"required":["number"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:52:41 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=424
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "7"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 166,
    "candidatesTokenCount": 1,
    "totalTokenCount": 167,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 166
      }
    ]
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "OTCwaZKPIPetkdUPqpmhqAo"
}


================================================
FILE: agent/llmagent/testdata/TestToolCallback_after_callback_returned_when_used_with_before_callback.httprr
================================================
httprr trace v1
976 1421
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 744
Content-Type: application/json

{"contents":[{"parts":[{"text":"Generate random number with 5 as a seed."}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"random agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"returns random number","name":"rand_number","parametersJsonSchema":{"additionalProperties":false,"properties":{"seed":{"type":"integer"}},"required":["seed"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"number":{"type":"integer"}},"required":["number"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:52:43 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=892
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "functionCall": {
              "name": "rand_number",
              "args": {
                "seed": 5
              }
            },
            "thoughtSignature": "CocCAb4+9vv9wlY80xSDfuzL9q9YBrF9gdbHJPZHEXYbFB0XmIsbwvlhcgZTx2xURUhbbR+iWGuRdMDEWnRUchz2tDC5kpM+JbGVrjWjgagjIIiQCtrlMGaTlHGXCVFUc4uRWsEUev+dT+nlBuqsZNtfhPXfcYzk4/3eQ2Z9zCWc5H7Gca5YHfPTyYpNzJFGWtuubZsGx5/QGbmYefWo5eMf5DJOsz199Qc9rWKk/esbeKMkITuHSditSKP/+vNfbXQ+XRvvtCgJ2z+9r3veipFmUXOYTmzT+HJoMKSwFyFSQ/PuKTN3irHIrYJnHq+riKyRSkcVCFRDrFt2lAsDDptJck4dZFZuMKk="
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0,
      "finishMessage": "Model generated function call(s)."
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 136,
    "candidatesTokenCount": 15,
    "totalTokenCount": 211,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 136
      }
    ],
    "thoughtsTokenCount": 60
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "OzCwaZDsA9aCkdUP0bmRyAU"
}
1536 815
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 1303
Content-Type: application/json

{"contents":[{"parts":[{"text":"Generate random number with 5 as a seed."}],"role":"user"},{"parts":[{"functionCall":{"args":{"seed":5},"name":"rand_number"},"thoughtSignature":"CocCAb4+9vv9wlY80xSDfuzL9q9YBrF9gdbHJPZHEXYbFB0XmIsbwvlhcgZTx2xURUhbbR+iWGuRdMDEWnRUchz2tDC5kpM+JbGVrjWjgagjIIiQCtrlMGaTlHGXCVFUc4uRWsEUev+dT+nlBuqsZNtfhPXfcYzk4/3eQ2Z9zCWc5H7Gca5YHfPTyYpNzJFGWtuubZsGx5/QGbmYefWo5eMf5DJOsz199Qc9rWKk/esbeKMkITuHSditSKP/+vNfbXQ+XRvvtCgJ2z+9r3veipFmUXOYTmzT+HJoMKSwFyFSQ/PuKTN3irHIrYJnHq+riKyRSkcVCFRDrFt2lAsDDptJck4dZFZuMKk="}],"role":"model"},{"parts":[{"functionResponse":{"name":"rand_number","response":{"number":"7"}}}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"random agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"returns random number","name":"rand_number","parametersJsonSchema":{"additionalProperties":false,"properties":{"seed":{"type":"integer"}},"required":["seed"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"number":{"type":"integer"}},"required":["number"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:52:44 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=293
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "7"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 166,
    "candidatesTokenCount": 1,
    "totalTokenCount": 167,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 166
      }
    ]
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "OzCwacXGOoaSkdUP-9_n2AY"
}


================================================
FILE: agent/llmagent/testdata/TestToolCallback_before_callback_response_used.httprr
================================================
httprr trace v1
976 1409
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 744
Content-Type: application/json

{"contents":[{"parts":[{"text":"Generate random number with 5 as a seed."}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"random agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"returns random number","name":"rand_number","parametersJsonSchema":{"additionalProperties":false,"properties":{"seed":{"type":"integer"}},"required":["seed"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"number":{"type":"integer"}},"required":["number"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:52:38 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=748
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "functionCall": {
              "name": "rand_number",
              "args": {
                "seed": 5
              }
            },
            "thoughtSignature": "Cv8BAb4+9vuiCXHA/S86tz6TiLryf5JZFA9pTP3tL02lJv+TF5DWLOtEaJpS8P0rvuk2jZWguCVmx+Z3PIFjeIa7RYJ4AuD3a4smR+uR3YAvVwCllB5kEKRx/d/g8kmv4tF/jPs6hO+gmBt90w35pXK9POe6+Upau7SuZtxksrflBCOTU19sibNANn39YhfptRt+t1edh9IJkV1llXya00beEMLgm+54shIz27aZ1vPnVazcrYgvvyukU/ayo4jZJDts8Of63PVVG8dgFKXMJEUHiN9Z708mC/5WMhAsJqqVqs4BWddausRNVcnLPH9d6oCXkwT095HXzUQlY/srI1tY"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0,
      "finishMessage": "Model generated function call(s)."
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 136,
    "candidatesTokenCount": 15,
    "totalTokenCount": 207,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 136
      }
    ],
    "thoughtsTokenCount": 56
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "NTCwaeWwNp7tkdUPt6evsAU"
}
1524 815
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 1291
Content-Type: application/json

{"contents":[{"parts":[{"text":"Generate random number with 5 as a seed."}],"role":"user"},{"parts":[{"functionCall":{"args":{"seed":5},"name":"rand_number"},"thoughtSignature":"Cv8BAb4+9vuiCXHA/S86tz6TiLryf5JZFA9pTP3tL02lJv+TF5DWLOtEaJpS8P0rvuk2jZWguCVmx+Z3PIFjeIa7RYJ4AuD3a4smR+uR3YAvVwCllB5kEKRx/d/g8kmv4tF/jPs6hO+gmBt90w35pXK9POe6+Upau7SuZtxksrflBCOTU19sibNANn39YhfptRt+t1edh9IJkV1llXya00beEMLgm+54shIz27aZ1vPnVazcrYgvvyukU/ayo4jZJDts8Of63PVVG8dgFKXMJEUHiN9Z708mC/5WMhAsJqqVqs4BWddausRNVcnLPH9d6oCXkwT095HXzUQlY/srI1tY"}],"role":"model"},{"parts":[{"functionResponse":{"name":"rand_number","response":{"number":"7"}}}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"random agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"returns random number","name":"rand_number","parametersJsonSchema":{"additionalProperties":false,"properties":{"seed":{"type":"integer"}},"required":["seed"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"number":{"type":"integer"}},"required":["number"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:52:39 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=394
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "7"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 166,
    "candidatesTokenCount": 1,
    "totalTokenCount": 167,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 166
      }
    ]
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "NjCwafbaJ4enkdUP4qubqAk"
}


================================================
FILE: agent/llmagent/testdata/TestToolCallback_both_callbacks_return_nil_actual_tool_is_executed.httprr
================================================
httprr trace v1
976 1566
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 744
Content-Type: application/json

{"contents":[{"parts":[{"text":"Generate random number with 5 as a seed."}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"random agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"returns random number","name":"rand_number","parametersJsonSchema":{"additionalProperties":false,"properties":{"seed":{"type":"integer"}},"required":["seed"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"number":{"type":"integer"}},"required":["number"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:52:45 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=1149
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "functionCall": {
              "name": "rand_number",
              "args": {
                "seed": 5
              }
            },
            "thoughtSignature": "CvMCAb4+9vtDyZ0KEU3lK5jCnDCmza+fQGGG58b0oH1H6KFTPZI3iFo+hEV6hE+4Cnh5PzvDFg/YgfWQwXylYTILTu/9Yw0HAwxgN53cGm/ayTbTPFxnukDNmDS/K6rsGFtBoD29uTNTeXG4Xuvy4z+zwSSDV0PE4RBV6CaAxh7xR9KOSPg/5Ym63pKFS9LG7+rkqzhBm6QQS3wyxlsyRK9MHP/xlse+/WrADE3UDgoOEL/zd89vg2+mTr8E72NddFvruTo+r23XFabVnKlb/iLoh+TmLpIuwroi75o5cKnNuiZ/PXxo7P+Zr30ogwbltMzcKL/DEA1c1x+Z49UBtnU7+knzuGjPqCVR4qchfJWydI+FgBBbS+lbtNEBIwkM3Z24Dg9Q8kBY8/a3t5FR7PqFkvJ7Fx0kRPTtAGX0R42m/PVeYzrUSCp4aVReYDZh3FPPNqEWGxz2f2aBBMR5LaW8ABXO2kD6ZJnHv8+s0cvxjIyNg2Q="
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0,
      "finishMessage": "Model generated function call(s)."
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 136,
    "candidatesTokenCount": 15,
    "totalTokenCount": 229,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 136
      }
    ],
    "thoughtsTokenCount": 78
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "PDCwafCwD6GF7M8Pn7bJqAE"
}
1678 815
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 1445
Content-Type: application/json

{"contents":[{"parts":[{"text":"Generate random number with 5 as a seed."}],"role":"user"},{"parts":[{"functionCall":{"args":{"seed":5},"name":"rand_number"},"thoughtSignature":"CvMCAb4+9vtDyZ0KEU3lK5jCnDCmza+fQGGG58b0oH1H6KFTPZI3iFo+hEV6hE+4Cnh5PzvDFg/YgfWQwXylYTILTu/9Yw0HAwxgN53cGm/ayTbTPFxnukDNmDS/K6rsGFtBoD29uTNTeXG4Xuvy4z+zwSSDV0PE4RBV6CaAxh7xR9KOSPg/5Ym63pKFS9LG7+rkqzhBm6QQS3wyxlsyRK9MHP/xlse+/WrADE3UDgoOEL/zd89vg2+mTr8E72NddFvruTo+r23XFabVnKlb/iLoh+TmLpIuwroi75o5cKnNuiZ/PXxo7P+Zr30ogwbltMzcKL/DEA1c1x+Z49UBtnU7+knzuGjPqCVR4qchfJWydI+FgBBbS+lbtNEBIwkM3Z24Dg9Q8kBY8/a3t5FR7PqFkvJ7Fx0kRPTtAGX0R42m/PVeYzrUSCp4aVReYDZh3FPPNqEWGxz2f2aBBMR5LaW8ABXO2kD6ZJnHv8+s0cvxjIyNg2Q="}],"role":"model"},{"parts":[{"functionResponse":{"name":"rand_number","response":{"number":1}}}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"random agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"returns random number","name":"rand_number","parametersJsonSchema":{"additionalProperties":false,"properties":{"seed":{"type":"integer"}},"required":["seed"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"number":{"type":"integer"}},"required":["number"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:52:45 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=439
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "1"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 166,
    "candidatesTokenCount": 1,
    "totalTokenCount": 167,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 166
      }
    ]
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "PTCwab7MGOWD7M8PnPC9yQU"
}


================================================
FILE: agent/llmagent/testdata/TestToolCallback_extra_after_callback_skipped.httprr
================================================
httprr trace v1
976 1493
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 744
Content-Type: application/json

{"contents":[{"parts":[{"text":"Generate random number with 5 as a seed."}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"random agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"returns random number","name":"rand_number","parametersJsonSchema":{"additionalProperties":false,"properties":{"seed":{"type":"integer"}},"required":["seed"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"number":{"type":"integer"}},"required":["number"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:52:42 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=751
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "functionCall": {
              "name": "rand_number",
              "args": {
                "seed": 5
              }
            },
            "thoughtSignature": "CrwCAb4+9vuoZscYmNHbFm6Hl7XwmBgLRDVOpvS6zwLx57uGGzYrodnHDrseIc4rAjrQZB+65AWSRUl9FyYBsJyHYwuirfz8kMG2egbXP8/Y43wmWQeoRuOIwHxd3tOWb9ePoAUEU0HVrStulV9e4n7+Pr9mhWBSwTeWmeu+ji4H2ul6yjnMCZhuQsOe3+qLWekyuh23lq1AGtDnbLBM0SM4tHZcjry+MmRHsIwuXjrD21e397R7ui3Y9d8WmMlhuNymoGP/8EC7vFhwBaM+OPTTOKeMIGOgtMfj9jNVRy5pbaqM7+kmUxZs6ooTdaMJMWe6oZ1co+KalClngQbfIysU22ncyko4AtuDlPlseZnvjBjX0+Y9qlNP9Q4l0lhpUgrGnx6vyJo9YKHzCfWF0bOkqRME3KMjOFwvSK6vuA=="
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0,
      "finishMessage": "Model generated function call(s)."
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 136,
    "candidatesTokenCount": 15,
    "totalTokenCount": 219,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 136
      }
    ],
    "thoughtsTokenCount": 68
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "OTCwabPEOprf7M8P8_738Ag"
}
1608 815
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 1375
Content-Type: application/json

{"contents":[{"parts":[{"text":"Generate random number with 5 as a seed."}],"role":"user"},{"parts":[{"functionCall":{"args":{"seed":5},"name":"rand_number"},"thoughtSignature":"CrwCAb4+9vuoZscYmNHbFm6Hl7XwmBgLRDVOpvS6zwLx57uGGzYrodnHDrseIc4rAjrQZB+65AWSRUl9FyYBsJyHYwuirfz8kMG2egbXP8/Y43wmWQeoRuOIwHxd3tOWb9ePoAUEU0HVrStulV9e4n7+Pr9mhWBSwTeWmeu+ji4H2ul6yjnMCZhuQsOe3+qLWekyuh23lq1AGtDnbLBM0SM4tHZcjry+MmRHsIwuXjrD21e397R7ui3Y9d8WmMlhuNymoGP/8EC7vFhwBaM+OPTTOKeMIGOgtMfj9jNVRy5pbaqM7+kmUxZs6ooTdaMJMWe6oZ1co+KalClngQbfIysU22ncyko4AtuDlPlseZnvjBjX0+Y9qlNP9Q4l0lhpUgrGnx6vyJo9YKHzCfWF0bOkqRME3KMjOFwvSK6vuA=="}],"role":"model"},{"parts":[{"functionResponse":{"name":"rand_number","response":{"number":"3"}}}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"random agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"returns random number","name":"rand_number","parametersJsonSchema":{"additionalProperties":false,"properties":{"seed":{"type":"integer"}},"required":["seed"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"number":{"type":"integer"}},"required":["number"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:52:43 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=349
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "3"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 166,
    "candidatesTokenCount": 1,
    "totalTokenCount": 167,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 166
      }
    ]
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "OjCwaa7hK5vZ7M8PpLbA6Qs"
}


================================================
FILE: agent/llmagent/testdata/TestToolCallback_extra_before_callback_skipped.httprr
================================================
httprr trace v1
976 1430
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 744
Content-Type: application/json

{"contents":[{"parts":[{"text":"Generate random number with 5 as a seed."}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"random agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"returns random number","name":"rand_number","parametersJsonSchema":{"additionalProperties":false,"properties":{"seed":{"type":"integer"}},"required":["seed"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"number":{"type":"integer"}},"required":["number"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:52:40 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=1359
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "functionCall": {
              "name": "rand_number",
              "args": {
                "seed": 5
              }
            },
            "thoughtSignature": "Co4CAb4+9vshp23q730zmpKZA44y18kH57i34mjTjHqu63zEHBWY7uvTVnM/ct8OnEACaGkPS1ns8seAUWXuxgHXkmWRzzFFveogyu8/m8CbLxzfYaalGxiriSPCN9pLcIq6WfzwCIobgZh5szHcYKM4zOipgtV7f1eUX/wrGmuaNYBx7OurtouFK6x11rBjafcIaKp1PNrXHkxHwtQ7TEl0QegcsN4vVol82qyw4Pp+bl6PhzkjWvgqnNsnuPmJN8Emm6Ajf5ovW1GuPR9iTuAz6f1ncwyKlhZuLQMZKla7MsV7kcx+fUfFvJIF69A/FqH020HABFpD+CWaUzR0KaTWTcE3MvlZkmUy6sTx9a4R"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0,
      "finishMessage": "Model generated function call(s)."
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 136,
    "candidatesTokenCount": 15,
    "totalTokenCount": 211,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 136
      }
    ],
    "thoughtsTokenCount": 60
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "NzCwaf7JAvrikdUPuqqn8QU"
}
1544 815
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1
Host: generativelanguage.googleapis.com
User-Agent: Go-http-client/1.1
Content-Length: 1311
Content-Type: application/json

{"contents":[{"parts":[{"text":"Generate random number with 5 as a seed."}],"role":"user"},{"parts":[{"functionCall":{"args":{"seed":5},"name":"rand_number"},"thoughtSignature":"Co4CAb4+9vshp23q730zmpKZA44y18kH57i34mjTjHqu63zEHBWY7uvTVnM/ct8OnEACaGkPS1ns8seAUWXuxgHXkmWRzzFFveogyu8/m8CbLxzfYaalGxiriSPCN9pLcIq6WfzwCIobgZh5szHcYKM4zOipgtV7f1eUX/wrGmuaNYBx7OurtouFK6x11rBjafcIaKp1PNrXHkxHwtQ7TEl0QegcsN4vVol82qyw4Pp+bl6PhzkjWvgqnNsnuPmJN8Emm6Ajf5ovW1GuPR9iTuAz6f1ncwyKlhZuLQMZKla7MsV7kcx+fUfFvJIF69A/FqH020HABFpD+CWaUzR0KaTWTcE3MvlZkmUy6sTx9a4R"}],"role":"model"},{"parts":[{"functionResponse":{"name":"rand_number","response":{"number":"3"}}}],"role":"user"}],"generationConfig":{},"systemInstruction":{"parts":[{"text":"IMPORTANT: output ONLY the result computed by the provided function, if the result is number:42 print only 42\n\nYou are an agent. Your internal name is \"agent\". The description about you is \"random agent\"."}],"role":"user"},"tools":[{"functionDeclarations":[{"description":"returns random number","name":"rand_number","parametersJsonSchema":{"additionalProperties":false,"properties":{"seed":{"type":"integer"}},"required":["seed"],"type":"object"},"responseJsonSchema":{"additionalProperties":false,"properties":{"number":{"type":"integer"}},"required":["number"],"type":"object"}}]}]}HTTP/2.0 200 OK
Content-Type: application/json; charset=UTF-8
Date: Tue, 10 Mar 2026 14:52:40 GMT
Server: scaffolding on HTTPServer2
Server-Timing: gfet4t7; dur=402
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "3"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 166,
    "candidatesTokenCount": 1,
    "totalTokenCount": 167,
    "promptTokensDetails": [
      {
        "modality": "TEXT",
        "tokenCount": 166
      }
    ]
  },
  "modelVersion": "gemini-2.5-flash",
  "responseId": "ODCwaevWGfH3nsEP2v-88AQ"
}


================================================
FILE: agent/loader.go
================================================
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"fmt"
)

// Loader allows to load a particular agent by name and get the root agent
type Loader interface {
	// ListAgents returns a list of names of all agents
	ListAgents() []string
	// LoadAgent returns an agent by its name. Returns error if there is no agent with such a name.
	LoadAgent(name string) (Agent, error)
	// RootAgent returns the root agent
	RootAgent() Agent
}

// multiLoader should be used when you have multiple agents
type multiLoader struct {
	agentMap map[string]Agent
	root     Agent
}

// singleLoader should be used when you have only one agent
type singleLoader struct {
	root Agent
}

// NewSingleLoader returns a loader with only one agent, which becomes the root agent
func NewSingleLoader(a Agent) Loader {
	return &singleLoader{root: a}
}

// singleAgentLoader implements AgentLoader. Returns root agent's name
func (s *singleLoader) ListAgents() []string {
	return []string{s.root.Name()}
}

// singleAgentLoader implements AgentLoader. Returns root for empty name and for root.Name(), error otherwise.
func (s *singleLoader) LoadAgent(name string) (Agent, error) {
	if name == "" {
		return s.root, nil
	}
	if name == s.root.Name() {
		return s.root, nil
	}
	return nil, fmt.Errorf("cannot load agent '%s' - provide an empty string or use '%s'", name, s.root.Name())
}

// singleAgentLoader implements AgentLoader. Returns the root agent.
func (s *singleLoader) RootAgent() Agent {
	return s.root
}

// NewMultiLoader returns a new AgentLoader with the given root Agent and other agents.
// Returns an error if more than one agent (including root) shares the same name
func NewMultiLoader(root Agent, agents ...Agent) (Loader, error) {
	m := make(map[string]Agent)
	m[root.Name()] = root
	for _, a := range agents {
		if _, ok := m[a.Name()]; ok {
			// duplicate name
			return nil, fmt.Errorf("duplicate agent name: %s", a.Name())
		}
		m[a.Name()] = a
	}
	return &multiLoader{
		agentMap: m,
		root:     root,
	}, nil
}

// multiAgentLoader implements AgentLoader. Returns the list of all agents' names (including root agent)
func (m *multiLoader) ListAgents() []string {
	agents := make([]string, 0, len(m.agentMap))
	for name := range m.agentMap {
		agents = append(agents, name)
	}
	return agents
}

// multiAgentLoader implements LoadAgent. Returns an agent with given name or error if no such an agent is found
func (m *multiLoader) LoadAgent(name string) (Agent, error) {
	agent, ok := m.agentMap[name]
	if !ok {
		return nil, fmt.Errorf("agent %s not found. Please specify one of those: %v", name, m.ListAgents())
	}
	return agent, nil
}

// multiAgentLoader implements LoadAgent.
func (m *multiLoader) RootAgent() Agent {
	return m.root
}


================================================
FILE: agent/loader_test.go
================================================
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"iter"
	"testing"

	"google.golang.org/adk/session"
)

var _ Agent = (*testAgent)(nil)

type testAgent struct {
	name string
}

func (a *testAgent) Name() string {
	return a.name
}

func (a *testAgent) Description() string {
	panic("not implemented")
}

func (a *testAgent) Run(InvocationContext) iter.Seq2[*session.Event, error] {
	panic("not implemented")
}

func (a *testAgent) SubAgents() []Agent {
	panic("not implemented")
}

func (a *testAgent) internal() *agent {
	panic("not implemented")
}

func TestDuplicateName(t *testing.T) {
	agent1 := &testAgent{name: "weather_time_agent"}
	// duplicate name
	agent2 := &testAgent{name: "weather_time_agent"}
	agent3 := &testAgent{name: "unique"}

	tests := []struct {
		name    string
		root    Agent
		agents  []Agent
		wantErr bool
	}{
		{
			name:    "root only",
			root:    agent1,
			agents:  []Agent{},
			wantErr: false,
		},
		{
			name:    "root duplicate object",
			root:    agent1,
			agents:  []Agent{agent1},
			wantErr: true,
		},
		{
			name:    "root duplicate name",
			root:    agent1,
			agents:  []Agent{agent2},
			wantErr: true,
		},
		{
			name:    "non-root duplicate name",
			root:    agent3,
			agents:  []Agent{agent1, agent2},
			wantErr: true,
		},
		{
			name:    "non-root duplicate object",
			root:    agent3,
			agents:  []Agent{agent1, agent1},
			wantErr: true,
		},
		{
			name:    "no duplicates",
			root:    agent1,
			agents:  []Agent{agent3},
			wantErr: false,
		},
	}
	for _, tt := range tests {
		_, err := NewMultiLoader(tt.root, tt.agents...)
		if (err != nil) != tt.wantErr {
			t.Errorf("NewMultiLoader() name=%v, error = %v, wantErr %v", tt.name, err, tt.wantErr)
		}
	}
}


================================================
FILE: agent/remoteagent/a2a_agent.go
================================================
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package remoteagent

import (
	"context"
	"fmt"
	"iter"
	"log"
	"time"

	"github.com/a2aproject/a2a-go/a2a"
	"github.com/a2aproject/a2a-go/a2aclient"
	"github.com/a2aproject/a2a-go/a2aclient/agentcard"

	"google.golang.org/adk/agent"
	agentinternal "google.golang.org/adk/internal/agent"
	iremoteagent "google.golang.org/adk/internal/agent/remoteagent"
	"google.golang.org/adk/server/adka2a"
	"google.golang.org/adk/session"
)

// BeforeA2ARequestCallback is called before sending a request to the remote agent.
//
// If it returns non-nil result or error, the actual call is skipped and the returned value is used
// as the agent invocation result.
type BeforeA2ARequestCallback func(ctx agent.CallbackContext, req *a2a.MessageSendParams) (*session.Event, error)

// A2AEventConverter can be used to provide a custom implementation of A2A event transformation logic.
type A2AEventConverter func(ctx agent.InvocationContext, req *a2a.MessageSendParams, event a2a.Event, err error) (*session.Event, error)

// AfterA2ARequestCallback is called after receiving a response from the remote agent and converting it to a session.Event.
// In streaming responses the callback is invoked for every request. Session event parameter might be nil if conversion logic
// decides to not emit an A2A event.
//
// If it returns non-nil result or error, it gets emitted instead of the original result.
type AfterA2ARequestCallback func(ctx agent.CallbackContext, req *a2a.MessageSendParams, resp *session.Event, err error) (*session.Event, error)

// A2ARemoteTaskCleanupCallback is called if Run exited before a terminal event was received from the remote A2A server.
type A2ARemoteTaskCleanupCallback func(ctx context.Context, card *a2a.AgentCard, client *a2aclient.Client, taskInfo a2a.TaskInfo, cause error)

// A2AConfig is used to describe and configure a remote agent.
type A2AConfig struct {
	Name        string
	Description string

	// AgentCardSource can be either an http(s) URL or a local file path. If a2a.AgentCard
	// is not provided, the source is used to resolve the card during the first agent invocation.
	AgentCard       *a2a.AgentCard
	AgentCardSource string
	// CardResolveOptions can be used to provide a set of agencard.Resolver configurations.
	CardResolveOptions []agentcard.ResolveOption

	// BeforeAgentCallbacks is a list of callbacks that are called sequentially
	// before the agent starts its run.
	//
	// If any callback returns non-nil content or error, then the agent run and
	// the remaining callbacks will be skipped, and a new event will be created
	// from the content or error of that callback.
	BeforeAgentCallbacks []agent.BeforeAgentCallback
	// BeforeRequestCallbacks will be called in the order they are provided until
	// there's a callback that returns a non-nil result or error. Then the
	// actual request is skipped, and the returned response/error is used.
	//
	// This provides an opportunity to inspect, log, or modify the request object.
	// It can also be used to implement caching by returning a cached
	// response, which would skip the actual remote agent call.
	BeforeRequestCallbacks []BeforeA2ARequestCallback
	// Converter is used to convert a2a.Event to session.Event. If not provided, adka2a.ToSessionEvent
	// is used as the default implementation and errors are converted to events with error payload.
	Converter A2AEventConverter
	// AfterRequestCallbacks will be called in the order they are provided until
	// there's a callback that returns a non-nil result or error. Then
	// the actual remote agent event is replaced with the returned result/error.
	//
	// This is the ideal place to log agent responses, collect metrics on token or perform
	// pre-processing of events before a mapper is invoked.
	AfterRequestCallbacks []AfterA2ARequestCallback
	// AfterAgentCallbacks is a list of callbacks that are called sequentially
	// after the agent has completed its run.
	//
	// If any callback returns non-nil content or error, then a new event will be
	// created from the content or error of that callback and the remaining
	// callbacks will be skipped.
	AfterAgentCallbacks []agent.AfterAgentCallback

	// A2APartConverter is a custom converter for converting A2A parts to GenAI parts.
	// Implementations should generally remember to leverage adka2a.ToGenAiPart for default conversions
	// nil returns are considered intentionally dropped parts.
	A2APartConverter adka2a.A2APartConverter

	// GenAIPartConverter is a custom converter for converting GenAI parts to A2A parts.
	// Implementations should generally remember to leverage adka2a.ToA2APart for default conversions
	// nil returns are considered intentionally dropped parts.
	GenAIPartConverter adka2a.GenAIPartConverter

	// ClientFactory can be used to provide a set of a2aclient.Client configurations.
	ClientFactory *a2aclient.Factory
	// MessageSendConfig is attached 
Download .txt
gitextract_gssbqr3a/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── actions/
│   │   └── setup/
│   │       └── action.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── go.yml
│       └── nightly.yml
├── .gitignore
├── .golangci.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── agent/
│   ├── agent.go
│   ├── agent_test.go
│   ├── context.go
│   ├── doc.go
│   ├── llmagent/
│   │   ├── doc.go
│   │   ├── llmagent.go
│   │   ├── llmagent_saveoutput_test.go
│   │   ├── llmagent_test.go
│   │   ├── state_agent_test.go
│   │   └── testdata/
│   │       ├── TestFunctionTool.httprr
│   │       ├── TestLLMAgentStreamingModeSSE.httprr
│   │       ├── TestLLMAgent_healthy_backend.httprr
│   │       ├── TestToolCallback_after_callback_response_used.httprr
│   │       ├── TestToolCallback_after_callback_returned_when_used_with_before_callback.httprr
│   │       ├── TestToolCallback_before_callback_response_used.httprr
│   │       ├── TestToolCallback_both_callbacks_return_nil_actual_tool_is_executed.httprr
│   │       ├── TestToolCallback_extra_after_callback_skipped.httprr
│   │       └── TestToolCallback_extra_before_callback_skipped.httprr
│   ├── loader.go
│   ├── loader_test.go
│   ├── remoteagent/
│   │   ├── a2a_agent.go
│   │   ├── a2a_agent_run_processor.go
│   │   ├── a2a_agent_run_processor_test.go
│   │   ├── a2a_agent_test.go
│   │   ├── a2a_e2e_test.go
│   │   ├── doc.go
│   │   ├── testdata/
│   │   │   ├── TestA2ARemoteAgentStreamingGeminiError.httprr
│   │   │   ├── TestA2ARemoteAgentStreamingGeminiSuccess.httprr
│   │   │   ├── TestA2ASingleHopFinalResponse_llm_mid-response_error.httprr
│   │   │   └── TestA2ASingleHopFinalResponse_llm_mid-response_error_response.httprr
│   │   ├── utils.go
│   │   └── utils_test.go
│   ├── run_config.go
│   └── workflowagents/
│       ├── loopagent/
│       │   ├── agent.go
│       │   └── agent_test.go
│       ├── parallelagent/
│       │   ├── agent.go
│       │   ├── agent_test.go
│       │   └── testdata/
│       │       ├── TestParallelAgentWithTools_agent1.httprr
│       │       └── TestParallelAgentWithTools_agent2.httprr
│       └── sequentialagent/
│           ├── agent.go
│           └── agent_test.go
├── artifact/
│   ├── artifact_key_test.go
│   ├── gcsartifact/
│   │   ├── gcs_client.go
│   │   ├── gcs_test.go
│   │   └── service.go
│   ├── inmemory.go
│   ├── inmemory_test.go
│   ├── request_validation_test.go
│   └── service.go
├── cmd/
│   ├── adkgo/
│   │   ├── adkgo.go
│   │   └── internal/
│   │       ├── deploy/
│   │       │   ├── cloudrun/
│   │       │   │   └── cloudrun.go
│   │       │   └── deploy.go
│   │       └── root/
│   │           └── root.go
│   ├── internal/
│   │   └── adkcli/
│   │       └── main.go
│   └── launcher/
│       ├── console/
│       │   └── console.go
│       ├── full/
│       │   └── full.go
│       ├── internal/
│       │   └── telemetry/
│       │       └── telemetry.go
│       ├── launcher.go
│       ├── prod/
│       │   └── prod.go
│       ├── universal/
│       │   └── universal.go
│       └── web/
│           ├── a2a/
│           │   ├── a2a.go
│           │   └── a2a_test.go
│           ├── api/
│           │   └── api.go
│           ├── web.go
│           └── webui/
│               ├── distr/
│               │   ├── assets/
│               │   │   ├── audio-processor.js
│               │   │   └── config/
│               │   │       └── runtime-config.json
│               │   ├── chunk-2FK4DXD6.js
│               │   ├── chunk-4ZK7FQPX.js
│               │   ├── chunk-7TJPJFPQ.js
│               │   ├── chunk-ABUNXR7C.js
│               │   ├── chunk-BWOBGCSA.js
│               │   ├── chunk-C7MGZAFQ.js
│               │   ├── chunk-CZPJTTNC.js
│               │   ├── chunk-GLGRLUIJ.js
│               │   ├── chunk-JFJZPIJV.js
│               │   ├── chunk-JOTH6MSK.js
│               │   ├── chunk-KPALJACC.js
│               │   ├── chunk-P66EZ4FO.js
│               │   ├── chunk-POBF2O3Z.js
│               │   ├── chunk-QWN7CXIU.js
│               │   ├── chunk-QZL3KUOO.js
│               │   ├── chunk-R2V2IE5A.js
│               │   ├── chunk-W7GRJBO5.js
│               │   ├── chunk-YQ6GIDJJ.js
│               │   ├── index.html
│               │   ├── main-ORIYWHAC.js
│               │   ├── polyfills-5CFQRCPP.js
│               │   └── styles-YY6V3TJU.css
│               └── webui.go
├── examples/
│   ├── README.md
│   ├── a2a/
│   │   └── main.go
│   ├── mcp/
│   │   └── main.go
│   ├── quickstart/
│   │   └── main.go
│   ├── rest/
│   │   └── main.go
│   ├── telemetry/
│   │   └── main.go
│   ├── toolconfirmation/
│   │   └── main.go
│   ├── tools/
│   │   ├── loadartifacts/
│   │   │   └── main.go
│   │   ├── loadmemory/
│   │   │   └── main.go
│   │   └── multipletools/
│   │       └── main.go
│   ├── vertexai/
│   │   ├── agent.go
│   │   ├── imagegenerator/
│   │   │   └── main.go
│   │   └── vertexengine/
│   │       └── create_engine.go
│   ├── web/
│   │   ├── agents/
│   │   │   ├── image_generator.go
│   │   │   └── llmauditor.go
│   │   └── main.go
│   └── workflowagents/
│       ├── loop/
│       │   └── main.go
│       ├── parallel/
│       │   └── main.go
│       ├── sequential/
│       │   └── main.go
│       └── sequentialCode/
│           └── main.go
├── go.mod
├── go.sum
├── internal/
│   ├── agent/
│   │   ├── parentmap/
│   │   │   ├── map.go
│   │   │   └── map_test.go
│   │   ├── remoteagent/
│   │   │   └── a2a_config.go
│   │   ├── runconfig/
│   │   │   └── run_config.go
│   │   └── state.go
│   ├── artifact/
│   │   ├── artifacts.go
│   │   ├── artifacts_test.go
│   │   └── tests/
│   │       └── service_suite.go
│   ├── cli/
│   │   └── util/
│   │       ├── doc.go
│   │       ├── flagset_helpers.go
│   │       ├── oscmd.go
│   │       └── text_helpers.go
│   ├── configurable/
│   │   ├── configurable.go
│   │   ├── configurable_utils.go
│   │   └── conformance/
│   │       ├── callbacks.go
│   │       ├── functions.go
│   │       ├── loader.go
│   │       └── replayplugin/
│   │           ├── invocation_replay_state.go
│   │           ├── recording/
│   │           │   └── recording.go
│   │           ├── replay_plugin.go
│   │           ├── replay_plugin_test.go
│   │           └── yaml_utils.go
│   ├── context/
│   │   ├── callback_context.go
│   │   ├── context_test.go
│   │   ├── invocation_context.go
│   │   └── readonly_context.go
│   ├── converters/
│   │   └── map_structure.go
│   ├── httprr/
│   │   ├── LICENSE
│   │   ├── rr.go
│   │   └── rr_test.go
│   ├── llminternal/
│   │   ├── agent.go
│   │   ├── agent_transfer.go
│   │   ├── agent_transfer_test.go
│   │   ├── base_flow.go
│   │   ├── base_flow_telemetry_test.go
│   │   ├── base_flow_test.go
│   │   ├── basic_processor.go
│   │   ├── clone_test.go
│   │   ├── contents_processor.go
│   │   ├── contents_processor_test.go
│   │   ├── converters/
│   │   │   └── converters.go
│   │   ├── file_uploads_processor.go
│   │   ├── functions.go
│   │   ├── functions_test.go
│   │   ├── googlellm/
│   │   │   ├── variant.go
│   │   │   └── variant_test.go
│   │   ├── handle_function_calls_async_test.go
│   │   ├── helpers_test.go
│   │   ├── identity_request_processor.go
│   │   ├── identity_request_processor_test.go
│   │   ├── instruction_processor.go
│   │   ├── instruction_processor_test.go
│   │   ├── other_processors.go
│   │   ├── outputschema_processor.go
│   │   ├── outputschema_processor_test.go
│   │   ├── parallel_function_call_test.go
│   │   ├── request_confirmation_processor.go
│   │   ├── request_confirmation_processor_test.go
│   │   ├── stream_aggregator.go
│   │   ├── stream_aggregator_test.go
│   │   ├── testdata/
│   │   │   ├── TestParallelFunctionCalls_test_parallel_function_calls_gemini-2.5-flash.httprr
│   │   │   ├── TestParallelFunctionCalls_test_parallel_function_calls_gemini-3-flash-preview.httprr
│   │   │   └── TestParallelFunctionCalls_test_parallel_function_calls_gemini-3.1-pro-preview.httprr
│   │   └── tools_processor.go
│   ├── memory/
│   │   ├── memory.go
│   │   └── memory_test.go
│   ├── plugininternal/
│   │   ├── plugin_manager.go
│   │   └── plugincontext/
│   │       └── context.go
│   ├── sessionutils/
│   │   └── utils.go
│   ├── style_test.go
│   ├── telemetry/
│   │   ├── converters.go
│   │   ├── converters_test.go
│   │   ├── logger.go
│   │   ├── logger_test.go
│   │   ├── telemetry.go
│   │   └── telemetry_test.go
│   ├── testutil/
│   │   ├── genai.go
│   │   └── test_agent_runner.go
│   ├── toolinternal/
│   │   ├── context.go
│   │   ├── context_test.go
│   │   ├── tool.go
│   │   └── toolutils/
│   │       └── toolutils.go
│   ├── typeutil/
│   │   └── convert.go
│   ├── utils/
│   │   ├── schema_test.go
│   │   ├── schema_utils.go
│   │   ├── utils.go
│   │   └── utils_test.go
│   └── version/
│       └── version.go
├── memory/
│   ├── inmemory.go
│   ├── inmemory_test.go
│   └── service.go
├── model/
│   ├── apigee/
│   │   ├── apigee.go
│   │   └── apigee_test.go
│   ├── gemini/
│   │   ├── gemini.go
│   │   ├── gemini_test.go
│   │   └── testdata/
│   │       ├── TestModel_GenerateStream_ok.httprr
│   │       ├── TestModel_Generate_ok.httprr
│   │       ├── TestModel_TrackingHeaders_verifies_headers_are_set_vertex_disabled.httprr
│   │       └── TestModel_TrackingHeaders_verifies_headers_are_set_vertex_enabled.httprr
│   ├── llm.go
│   └── llm_test.go
├── plugin/
│   ├── functioncallmodifier/
│   │   ├── integration_test.go
│   │   ├── plugin.go
│   │   ├── plugin_test.go
│   │   └── testdata/
│   │       ├── TestPluginCallbackIntegration_agent_tool_default_schema.httprr
│   │       ├── TestPluginCallbackIntegration_no_relevant_tools.httprr
│   │       └── TestPluginCallbackIntegration_transfer_to_agent_tool.httprr
│   ├── loggingplugin/
│   │   └── logging_plugin.go
│   ├── plugin.go
│   ├── plugin_manager_test.go
│   ├── plugin_test.go
│   └── retryandreflect/
│       ├── exceeded.md
│       ├── plugin.go
│       ├── plugin_test.go
│       └── reflection.md
├── runner/
│   ├── runner.go
│   └── runner_test.go
├── scripts/
│   └── adk-web/
│       ├── Dockerfile
│       └── update-adk-web.sh
├── server/
│   ├── adka2a/
│   │   ├── agent_card.go
│   │   ├── agent_card_test.go
│   │   ├── doc.go
│   │   ├── events.go
│   │   ├── events_test.go
│   │   ├── executor.go
│   │   ├── executor_context.go
│   │   ├── executor_plugin.go
│   │   ├── executor_test.go
│   │   ├── input_required.go
│   │   ├── metadata.go
│   │   ├── metadata_test.go
│   │   ├── parts.go
│   │   ├── parts_test.go
│   │   ├── processor.go
│   │   ├── processor_test.go
│   │   ├── task_artifact.go
│   │   └── utils.go
│   ├── adkrest/
│   │   ├── controllers/
│   │   │   ├── apps.go
│   │   │   ├── artifacts.go
│   │   │   ├── debug.go
│   │   │   ├── debug_test.go
│   │   │   ├── errors.go
│   │   │   ├── handlers.go
│   │   │   ├── runtime.go
│   │   │   ├── runtime_test.go
│   │   │   ├── sessions.go
│   │   │   └── sessions_test.go
│   │   ├── handler.go
│   │   └── internal/
│   │       ├── fakes/
│   │       │   └── testsessionservice.go
│   │       ├── models/
│   │       │   ├── event.go
│   │       │   ├── models.go
│   │       │   ├── runtime.go
│   │       │   └── session.go
│   │       ├── routers/
│   │       │   ├── apps.go
│   │       │   ├── artifacts.go
│   │       │   ├── debug.go
│   │       │   ├── eval.go
│   │       │   ├── routers.go
│   │       │   ├── runtime.go
│   │       │   └── sessions.go
│   │       └── services/
│   │           ├── agentgraphgenerator.go
│   │           ├── agentgraphgenerator_test.go
│   │           ├── debugtelemetry.go
│   │           ├── debugtelemetry_test.go
│   │           └── doc.go
│   └── doc.go
├── session/
│   ├── database/
│   │   ├── gorm_datatypes.go
│   │   ├── service.go
│   │   ├── service_test.go
│   │   ├── session.go
│   │   └── storage_session.go
│   ├── doc.go
│   ├── inmemory.go
│   ├── inmemory_test.go
│   ├── service.go
│   ├── session.go
│   └── vertexai/
│       ├── service_test.go
│       ├── session.go
│       ├── testdata/
│       │   ├── app_state_is_shared.replay
│       │   ├── append_event_to_the_session_and_overwrite_in_storage.replay
│       │   ├── append_event_to_the_session_with_events_and_overwrite_in_storage.replay
│       │   ├── append_event_when_session_not_found_should_fail.replay
│       │   ├── append_event_with_all_fields.replay
│       │   ├── append_event_with_bytes_content.replay
│       │   ├── empty_list_for_non-existent_user.replay
│       │   ├── error_when_not_found.replay
│       │   ├── full_key.replay
│       │   ├── generated_session_id.replay
│       │   ├── get_session_respects_user_id.replay
│       │   ├── list_all_users_for_app.replay
│       │   ├── list_for_user1.replay
│       │   ├── list_for_user2.replay
│       │   ├── missing_author.replay
│       │   ├── missing_invocation_id.replay
│       │   ├── missing_session_id.replay
│       │   ├── nil_event.replay
│       │   ├── ok.replay
│       │   ├── partial_events_are_not_persisted.replay
│       │   ├── session_state_is_not_shared.replay
│       │   ├── temp_state_is_not_persisted.replay
│       │   ├── user_state_is_user_specific.replay
│       │   ├── when_already_exists__it_fails.replay
│       │   ├── with_config_after_timestamp.replay
│       │   ├── with_config_combined_filters.replay
│       │   ├── with_config_no_config_returns_all_events.replay
│       │   └── with_config_num_recent_events.replay
│       ├── vertexai.go
│       ├── vertexai_client.go
│       └── vertexai_test.go
├── telemetry/
│   ├── config.go
│   ├── setup_otel.go
│   ├── telemetry.go
│   └── telemetry_test.go
├── tool/
│   ├── agenttool/
│   │   ├── agent_tool.go
│   │   └── agent_tool_test.go
│   ├── exampletool/
│   │   ├── tool.go
│   │   └── tool_test.go
│   ├── exitlooptool/
│   │   ├── tool.go
│   │   └── tool_test.go
│   ├── functiontool/
│   │   ├── function.go
│   │   ├── function_test.go
│   │   ├── long_running_function_test.go
│   │   └── testdata/
│   │       └── TestFunctionTool_Simple.httprr
│   ├── geminitool/
│   │   ├── google_search.go
│   │   ├── tool.go
│   │   └── tool_test.go
│   ├── loadartifactstool/
│   │   ├── load_artifacts_tool.go
│   │   └── load_artifacts_tool_test.go
│   ├── loadmemorytool/
│   │   ├── tool.go
│   │   └── tool_test.go
│   ├── mcptoolset/
│   │   ├── client.go
│   │   ├── set.go
│   │   ├── set_test.go
│   │   ├── testdata/
│   │   │   ├── TestMCPToolSet.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Conditional_Confirmation_Not_Required.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Conditional_Confirmation_Not_Required_For_This_Tool.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Conditional_Confirmation_Required.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Conditional_Confirmation_Required_For_This_Tool.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Conditional_Confirmation_Required_and_is_confirmed.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Conditional_Confirmation_Required_and_is_rejected.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Confirmation_Required.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Confirmation_Required_and_is_confirmed.httprr
│   │   │   ├── TestMCPToolSetConfirmation_Confirmation_Required_and_is_rejected.httprr
│   │   │   └── TestMCPToolSetConfirmation_No_Confirmation_Required.httprr
│   │   └── tool.go
│   ├── preloadmemorytool/
│   │   ├── tool.go
│   │   └── tool_test.go
│   ├── tool.go
│   ├── tool_test.go
│   └── toolconfirmation/
│       ├── tool_confirmation.go
│       └── tool_confirmation_test.go
└── util/
    └── instructionutil/
        └── instruction.go
Copy disabled (too large) Download .txt
Showing preview only (58,614K chars total). Download the full file to get everything.
SYMBOL INDEX (12465 symbols across 278 files)

FILE: agent/agent.go
  type Agent (line 43) | type Agent interface
  function New (line 53) | func New(cfg Config) (Agent, error) {
  type Config (line 75) | type Config struct
  type Artifacts (line 109) | type Artifacts interface
  type Memory (line 118) | type Memory interface
  type BeforeAgentCallback (line 127) | type BeforeAgentCallback
  type AfterAgentCallback (line 135) | type AfterAgentCallback
  type agent (line 137) | type agent struct
    method Name (line 148) | func (a *agent) Name() string {
    method Description (line 152) | func (a *agent) Description() string {
    method SubAgents (line 156) | func (a *agent) SubAgents() []Agent {
    method Run (line 160) | func (a *agent) Run(ctx InvocationContext) iter.Seq2[*session.Event, e...
    method internal (line 215) | func (a *agent) internal() *agent {
  function getAuthorForEvent (line 219) | func getAuthorForEvent(ctx InvocationContext, event *session.Event) stri...
  function runBeforeAgentCallbacks (line 229) | func runBeforeAgentCallbacks(ctx InvocationContext) (*session.Event, err...
  function runAfterAgentCallbacks (line 291) | func runAfterAgentCallbacks(ctx InvocationContext) (*session.Event, erro...
  type callbackContext (line 352) | type callbackContext struct
    method AgentName (line 358) | func (c *callbackContext) AgentName() string {
    method ReadonlyState (line 362) | func (c *callbackContext) ReadonlyState() session.ReadonlyState {
    method State (line 366) | func (c *callbackContext) State() session.State {
    method Artifacts (line 370) | func (c *callbackContext) Artifacts() Artifacts {
    method InvocationID (line 374) | func (c *callbackContext) InvocationID() string {
    method UserContent (line 378) | func (c *callbackContext) UserContent() *genai.Content {
    method AppName (line 383) | func (c *callbackContext) AppName() string {
    method Branch (line 388) | func (c *callbackContext) Branch() string {
    method SessionID (line 393) | func (c *callbackContext) SessionID() string {
    method UserID (line 398) | func (c *callbackContext) UserID() string {
  type callbackContextState (line 404) | type callbackContextState struct
    method Get (line 408) | func (c *callbackContextState) Get(key string) (any, error) {
    method Set (line 417) | func (c *callbackContextState) Set(key string, val any) error {
    method All (line 424) | func (c *callbackContextState) All() iter.Seq2[string, any] {
  type invocationContext (line 428) | type invocationContext struct
    method Agent (line 443) | func (c *invocationContext) Agent() Agent {
    method Artifacts (line 447) | func (c *invocationContext) Artifacts() Artifacts {
    method Memory (line 451) | func (c *invocationContext) Memory() Memory {
    method Session (line 455) | func (c *invocationContext) Session() session.Session {
    method InvocationID (line 459) | func (c *invocationContext) InvocationID() string {
    method Branch (line 463) | func (c *invocationContext) Branch() string {
    method UserContent (line 467) | func (c *invocationContext) UserContent() *genai.Content {
    method RunConfig (line 471) | func (c *invocationContext) RunConfig() *RunConfig {
    method EndInvocation (line 475) | func (c *invocationContext) EndInvocation() {
    method Ended (line 479) | func (c *invocationContext) Ended() bool {
    method WithContext (line 483) | func (c *invocationContext) WithContext(ctx context.Context) Invocatio...
  function pluginManagerFromContext (line 489) | func pluginManagerFromContext(ctx context.Context) pluginManager {
  type pluginManager (line 498) | type pluginManager interface

FILE: agent/agent_test.go
  function TestAgentCallbacks (line 30) | func TestAgentCallbacks(t *testing.T) {
  function TestEndInvocation_EndsBeforeMainCall (line 155) | func TestEndInvocation_EndsBeforeMainCall(t *testing.T) {
  function TestEndInvocation_EndsAfterMainCall (line 190) | func TestEndInvocation_EndsAfterMainCall(t *testing.T) {
  type customAgent (line 239) | type customAgent struct
    method Run (line 244) | func (a *customAgent) Run(ctx InvocationContext) iter.Seq2[*session.Ev...
  type testKey (line 260) | type testKey struct
  function TestWithContext (line 262) | func TestWithContext(t *testing.T) {
  type mockSession (line 282) | type mockSession struct
    method ID (line 287) | func (m *mockSession) ID() string { return m.sessionID }

FILE: agent/context.go
  type InvocationContext (line 60) | type InvocationContext interface
  type ReadonlyContext (line 106) | type ReadonlyContext interface
  type CallbackContext (line 123) | type CallbackContext interface

FILE: agent/llmagent/llmagent.go
  function New (line 34) | func New(cfg Config) (agent.Agent, error) {
  type Config (line 130) | type Config struct
  type BeforeModelCallback (line 289) | type BeforeModelCallback
  type AfterModelCallback (line 295) | type AfterModelCallback
  type OnModelErrorCallback (line 301) | type OnModelErrorCallback
  type BeforeToolCallback (line 313) | type BeforeToolCallback
  type AfterToolCallback (line 322) | type AfterToolCallback
  type OnToolErrorCallback (line 328) | type OnToolErrorCallback
  type IncludeContents (line 331) | type IncludeContents
  constant IncludeContentsNone (line 335) | IncludeContentsNone IncludeContents = "none"
  constant IncludeContentsDefault (line 337) | IncludeContentsDefault IncludeContents = "default"
  type llmAgent (line 340) | type llmAgent struct
    method run (line 361) | func (a *llmAgent) run(ctx agent.InvocationContext) iter.Seq2[*session...
    method maybeSaveOutputToState (line 398) | func (a *llmAgent) maybeSaveOutputToState(event *session.Event) {
  type InstructionProvider (line 439) | type InstructionProvider

FILE: agent/llmagent/llmagent_saveoutput_test.go
  type MockOutputSchema (line 27) | type MockOutputSchema struct
  function createTestEvent (line 33) | func createTestEvent(author, contentText string, isFinal bool) *session....
  function TestLlmAgent_MaybeSaveOutputToState (line 52) | func TestLlmAgent_MaybeSaveOutputToState(t *testing.T) {

FILE: agent/llmagent/llmagent_test.go
  constant modelName (line 39) | modelName = "gemini-2.5-flash"
  function TestLLMAgent (line 43) | func TestLLMAgent(t *testing.T) {
  function TestLLMAgentStreamingModeSSE (line 89) | func TestLLMAgentStreamingModeSSE(t *testing.T) {
  function TestModelCallbacks (line 135) | func TestModelCallbacks(t *testing.T) {
  function TestToolCallback (line 444) | func TestToolCallback(t *testing.T) {
  function TestInstructionProvider (line 677) | func TestInstructionProvider(t *testing.T) {
  function TestFunctionTool (line 848) | func TestFunctionTool(t *testing.T) {
  function TestAgentTransfer (line 897) | func TestAgentTransfer(t *testing.T) {
  function newGeminiModel (line 1095) | func newGeminiModel(t *testing.T, modelName string, transport http.Round...
  type roundTripperFunc (line 1111) | type roundTripperFunc
    method RoundTrip (line 1114) | func (fn roundTripperFunc) RoundTrip(req *http.Request) (*http.Respons...

FILE: agent/llmagent/state_agent_test.go
  type FakeLLM (line 40) | type FakeLLM struct
    method Name (line 44) | func (f *FakeLLM) Name() string {
    method GenerateContent (line 48) | func (f *FakeLLM) GenerateContent(ctx context.Context, req *model.LLMR...
  type assertSessionParams (line 64) | type assertSessionParams struct
  function assertSessionValues (line 71) | func assertSessionValues(
  function beforeAgentCallback (line 109) | func beforeAgentCallback(t *testing.T) agent.BeforeAgentCallback {
  function beforeModelCallback (line 128) | func beforeModelCallback(t *testing.T) func(ctx agent.CallbackContext, l...
  function afterModelCallback (line 144) | func afterModelCallback(t *testing.T) func(ctx agent.CallbackContext, ll...
  function afterAgentCallback (line 160) | func afterAgentCallback(t *testing.T) agent.AfterAgentCallback {
  function TestAgentSessionLifecycle (line 176) | func TestAgentSessionLifecycle(t *testing.T) {
  type WeatherArgs (line 253) | type WeatherArgs struct
  type WeatherResult (line 257) | type WeatherResult struct
  function GetWeather (line 265) | func GetWeather(ctx tool.Context, args WeatherArgs) (WeatherResult, erro...
  type CalculationArgs (line 279) | type CalculationArgs struct
  type CalculationResult (line 285) | type CalculationResult struct
  function Calculate (line 293) | func Calculate(ctx tool.Context, args CalculationArgs) (CalculationResul...
  type LogActivityParams (line 327) | type LogActivityParams struct
  type LogEntry (line 331) | type LogEntry struct
  type LogActivityResult (line 336) | type LogActivityResult struct
  function LogActivity (line 343) | func LogActivity(ctx tool.Context, params LogActivityParams) (LogActivit...
  function beforeToolAuditCallback (line 368) | func beforeToolAuditCallback(ctx tool.Context, t tool.Tool, args map[str...
  function beforeToolSecurityCallback (line 389) | func beforeToolSecurityCallback(ctx tool.Context, t tool.Tool, args map[...
  function beforeToolValidationCallback (line 413) | func beforeToolValidationCallback(ctx tool.Context, t tool.Tool, args ma...
  function afterToolEnhancementCallback (line 432) | func afterToolEnhancementCallback(ctx tool.Context, t tool.Tool, args, r...
  function afterToolAsyncCallback (line 446) | func afterToolAsyncCallback(ctx tool.Context, t tool.Tool, args, result ...
  function collectToolResults (line 461) | func collectToolResults(t *testing.T, stream iter.Seq2[*session.Event, e...
  function TestToolCallbacksAgent (line 483) | func TestToolCallbacksAgent(t *testing.T) {

FILE: agent/loader.go
  type Loader (line 22) | type Loader interface
  type multiLoader (line 32) | type multiLoader struct
    method ListAgents (line 87) | func (m *multiLoader) ListAgents() []string {
    method LoadAgent (line 96) | func (m *multiLoader) LoadAgent(name string) (Agent, error) {
    method RootAgent (line 105) | func (m *multiLoader) RootAgent() Agent {
  type singleLoader (line 38) | type singleLoader struct
    method ListAgents (line 48) | func (s *singleLoader) ListAgents() []string {
    method LoadAgent (line 53) | func (s *singleLoader) LoadAgent(name string) (Agent, error) {
    method RootAgent (line 64) | func (s *singleLoader) RootAgent() Agent {
  function NewSingleLoader (line 43) | func NewSingleLoader(a Agent) Loader {
  function NewMultiLoader (line 70) | func NewMultiLoader(root Agent, agents ...Agent) (Loader, error) {

FILE: agent/loader_test.go
  type testAgent (line 26) | type testAgent struct
    method Name (line 30) | func (a *testAgent) Name() string {
    method Description (line 34) | func (a *testAgent) Description() string {
    method Run (line 38) | func (a *testAgent) Run(InvocationContext) iter.Seq2[*session.Event, e...
    method SubAgents (line 42) | func (a *testAgent) SubAgents() []Agent {
    method internal (line 46) | func (a *testAgent) internal() *agent {
  function TestDuplicateName (line 50) | func TestDuplicateName(t *testing.T) {

FILE: agent/remoteagent/a2a_agent.go
  type BeforeA2ARequestCallback (line 39) | type BeforeA2ARequestCallback
  type A2AEventConverter (line 42) | type A2AEventConverter
  type AfterA2ARequestCallback (line 49) | type AfterA2ARequestCallback
  type A2ARemoteTaskCleanupCallback (line 52) | type A2ARemoteTaskCleanupCallback
  type A2AConfig (line 55) | type A2AConfig struct
  function NewA2A (line 123) | func NewA2A(cfg A2AConfig) (agent.Agent, error) {
  type a2aAgent (line 160) | type a2aAgent struct
    method run (line 164) | func (a *a2aAgent) run(ctx agent.InvocationContext, cfg A2AConfig) ite...
  function cleanupRemoteTask (line 266) | func cleanupRemoteTask(ctx context.Context, cfg A2AConfig, card *a2a.Age...
  function newMessage (line 306) | func newMessage(ctx agent.InvocationContext, cfg A2AConfig) (*a2a.Messag...
  function toErrorEvent (line 326) | func toErrorEvent(ctx agent.InvocationContext, err error) *session.Event {
  function convertParts (line 334) | func convertParts(ctx agent.InvocationContext, cfg A2AConfig, event *ses...
  function destroy (line 356) | func destroy(client *a2aclient.Client) {

FILE: agent/remoteagent/a2a_agent_run_processor.go
  type artifactAggregation (line 32) | type artifactAggregation struct
  type a2aAgentRunProcessor (line 40) | type a2aAgentRunProcessor struct
    method aggregatePartial (line 62) | func (p *a2aAgentRunProcessor) aggregatePartial(ctx agent.InvocationCo...
    method removeAggregation (line 119) | func (p *a2aAgentRunProcessor) removeAggregation(aid a2a.ArtifactID) {
    method removeFromOrder (line 124) | func (p *a2aAgentRunProcessor) removeFromOrder(aid a2a.ArtifactID) {
    method updateAggregation (line 130) | func (p *a2aAgentRunProcessor) updateAggregation(aid a2a.ArtifactID, a...
    method buildNonPartialAggregation (line 175) | func (p *a2aAgentRunProcessor) buildNonPartialAggregation(ctx agent.In...
    method convertToSessionEvent (line 187) | func (p *a2aAgentRunProcessor) convertToSessionEvent(ctx agent.Invocat...
    method runBeforeA2ARequestCallbacks (line 208) | func (p *a2aAgentRunProcessor) runBeforeA2ARequestCallbacks(ctx agent....
    method runAfterA2ARequestCallbacks (line 218) | func (p *a2aAgentRunProcessor) runAfterA2ARequestCallbacks(ctx agent.I...
    method updateCustomMetadata (line 228) | func (p *a2aAgentRunProcessor) updateCustomMetadata(event *session.Eve...
  function newRunProcessor (line 51) | func newRunProcessor(config A2AConfig, request *a2a.MessageSendParams) *...

FILE: agent/remoteagent/a2a_agent_run_processor_test.go
  function TestA2AAgentRunProcessor_aggregatePartial (line 33) | func TestA2AAgentRunProcessor_aggregatePartial(t *testing.T) {

FILE: agent/remoteagent/a2a_agent_test.go
  type mockA2AExecutor (line 46) | type mockA2AExecutor struct
    method Execute (line 54) | func (e *mockA2AExecutor) Execute(ctx context.Context, reqCtx *a2asrv....
    method Cancel (line 61) | func (e *mockA2AExecutor) Cancel(ctx context.Context, reqCtx *a2asrv.R...
    method Cleanup (line 70) | func (e *mockA2AExecutor) Cleanup(ctx context.Context, reqCtx *a2asrv....
  type testA2AServer (line 76) | type testA2AServer struct
  function startA2AServer (line 81) | func startA2AServer(agentExecutor a2asrv.AgentExecutor) *testA2AServer {
  function newA2ARemoteAgent (line 89) | func newA2ARemoteAgent(t *testing.T, name string, server *testA2AServer)...
  function newInvocationContext (line 95) | func newInvocationContext(t *testing.T, events []*session.Event) agent.I...
  function prepareSession (line 99) | func prepareSession(t *testing.T, ctx context.Context, events []*session...
  function newInvocationContextWithStreamingMode (line 114) | func newInvocationContextWithStreamingMode(t *testing.T, events []*sessi...
  function runAndCollect (line 127) | func runAndCollect(ic agent.InvocationContext, agnt agent.Agent) ([]*ses...
  function toLLMResponses (line 138) | func toLLMResponses(events []*session.Event) []model.LLMResponse {
  function newADKEventReplay (line 146) | func newADKEventReplay(t *testing.T, name string, events []*session.Even...
  function newA2AEventReplay (line 169) | func newA2AEventReplay(t *testing.T, events []a2a.Event) a2asrv.AgentExe...
  function newUserHello (line 197) | func newUserHello() *session.Event {
  function newFinalStatusUpdate (line 204) | func newFinalStatusUpdate(task *a2a.Task, state a2a.TaskState, msgParts ...
  function TestRemoteAgent_ADK2ADK (line 213) | func TestRemoteAgent_ADK2ADK(t *testing.T) {
  function TestRemoteAgent_ADK2A2A (line 430) | func TestRemoteAgent_ADK2A2A(t *testing.T) {
  function TestRemoteAgent_RequestCallbacks (line 653) | func TestRemoteAgent_RequestCallbacks(t *testing.T) {
  function TestRemoteAgent_RequestPayload (line 899) | func TestRemoteAgent_RequestPayload(t *testing.T) {
  function TestRemoteAgent_EmptyResultForEmptySession (line 1066) | func TestRemoteAgent_EmptyResultForEmptySession(t *testing.T) {
  function TestRemoteAgent_ResolvesAgentCard (line 1096) | func TestRemoteAgent_ResolvesAgentCard(t *testing.T) {
  function TestRemoteAgent_ErrorEventIfNoCompatibleTransport (line 1135) | func TestRemoteAgent_ErrorEventIfNoCompatibleTransport(t *testing.T) {
  function TestRemoteAgent_ErrorEventOnServerError (line 1166) | func TestRemoteAgent_ErrorEventOnServerError(t *testing.T) {
  function TestRemoteAgent_CustomConverters (line 1190) | func TestRemoteAgent_CustomConverters(t *testing.T) {
  function TestRemoteAgent_CleanupCallback (line 1228) | func TestRemoteAgent_CleanupCallback(t *testing.T) {
  function TestRemoteAgent_PartConverter (line 1370) | func TestRemoteAgent_PartConverter(t *testing.T) {

FILE: agent/remoteagent/a2a_e2e_test.go
  constant approvalToolName (line 57) | approvalToolName            = "request_approval"
  constant modelTextRequiresApproval (line 58) | modelTextRequiresApproval   = "need to request approval first!"
  constant modelTextWaitingForApproval (line 59) | modelTextWaitingForApproval = "waiting for user's approval..."
  constant modelTextTaskComplete (line 60) | modelTextTaskComplete       = "Task complete!"
  constant transferToolName (line 62) | transferToolName      = "transfer_to_agent"
  constant modelTextRootTransfer (line 63) | modelTextRootTransfer = "transfering... please hold... beepboop..."
  type approvalStatus (line 66) | type approvalStatus
  type approval (line 74) | type approval struct
  function TestA2AInputRequired (line 82) | func TestA2AInputRequired(t *testing.T) {
  function TestA2AMultiHopInputRequired (line 250) | func TestA2AMultiHopInputRequired(t *testing.T) {
  function TestA2ACleanupPropagation (line 375) | func TestA2ACleanupPropagation(t *testing.T) {
  function TestA2ASingleHopFinalResponse (line 466) | func TestA2ASingleHopFinalResponse(t *testing.T) {
  function TestA2ARemoteAgentStreamingGeminiSuccess (line 644) | func TestA2ARemoteAgentStreamingGeminiSuccess(t *testing.T) {
  function TestA2ARemoteAgentStreamingGeminiError (line 745) | func TestA2ARemoteAgentStreamingGeminiError(t *testing.T) {
  type llmStub (line 828) | type llmStub struct
    method Name (line 833) | func (d *llmStub) Name() string {
    method GenerateContent (line 837) | func (d *llmStub) GenerateContent(ctx context.Context, req *model.LLMR...
  function newLongRunningTool (line 841) | func newLongRunningTool(t *testing.T) tool.Tool {
  function newToolConfirmation (line 856) | func newToolConfirmation(t *testing.T) tool.Tool {
  function newInputRequestingAgent (line 890) | func newInputRequestingAgent(t *testing.T, name string, requestApproval ...
  function newRootAgent (line 919) | func newRootAgent(name string, subAgent agent.Agent) agent.Agent {
  function newAgentExecutor (line 939) | func newAgentExecutor(agnt agent.Agent, service session.Service, mode ad...
  function mustSendMessage (line 954) | func mustSendMessage(t *testing.T, client *a2aclient.Client, msg *a2a.Me...
  function filterPartial (line 968) | func filterPartial(parts []a2a.Part) []a2a.Part {
  function findLongRunningCall (line 979) | func findLongRunningCall(t *testing.T, parts []*genai.Part) (*genai.Func...
  function toA2AParts (line 1001) | func toA2AParts(t *testing.T, parts []*genai.Part, callIDs []string) []a...
  function toGenaiParts (line 1010) | func toGenaiParts(t *testing.T, a2aParts []a2a.Part) []*genai.Part {
  function toMap (line 1019) | func toMap(t *testing.T, v any) map[string]any {
  function fromMap (line 1028) | func fromMap[T any](t *testing.T, m map[string]any) *T {
  function newA2AClient (line 1037) | func newA2AClient(t *testing.T, server *testA2AServer) *a2aclient.Client {
  function createLongRunningToolApproval (line 1050) | func createLongRunningToolApproval(t *testing.T, pendingResponse *genai....
  function createToolConfirmationApproval (line 1061) | func createToolConfirmationApproval(t *testing.T, toolCall *genai.Functi...
  function newGeminiTestClientConfig (line 1087) | func newGeminiTestClientConfig(t *testing.T, rrfile string) (http.RoundT...
  function newGeminiModel (line 1107) | func newGeminiModel(t *testing.T, modelName string) model.LLM {
  function TestA2AMultiHopInputRequiredCancellation (line 1126) | func TestA2AMultiHopInputRequiredCancellation(t *testing.T) {

FILE: agent/remoteagent/utils.go
  type userFunctionCall (line 29) | type userFunctionCall struct
  function getUserFunctionCallAt (line 37) | func getUserFunctionCallAt(events session.Events, index int) *userFuncti...
  function isFunctionCallEvent (line 63) | func isFunctionCallEvent(event *session.Event, callID string) bool {
  function getFunctionResponseCallID (line 73) | func getFunctionResponseCallID(event *session.Event) (string, bool) {
  function toMissingRemoteSessionParts (line 92) | func toMissingRemoteSessionParts(ctx agent.InvocationContext, events ses...
  function presentAsUserMessage (line 127) | func presentAsUserMessage(ctx agent.InvocationContext, agentEvent *sessi...

FILE: agent/remoteagent/utils_test.go
  function newTestInvocationContext (line 33) | func newTestInvocationContext(t *testing.T, agentName string, events ......
  function newEventFromParts (line 59) | func newEventFromParts(author string, parts ...*genai.Part) *session.Eve...
  function TestGetUserFunctionCallAt (line 71) | func TestGetUserFunctionCallAt(t *testing.T) {
  function TestToMissingRemoteSessionParts (line 155) | func TestToMissingRemoteSessionParts(t *testing.T) {
  function TestPresentAsUserMessage (line 239) | func TestPresentAsUserMessage(t *testing.T) {

FILE: agent/run_config.go
  type StreamingMode (line 18) | type StreamingMode
  constant StreamingModeNone (line 22) | StreamingModeNone StreamingMode = "none"
  constant StreamingModeSSE (line 25) | StreamingModeSSE StreamingMode = "sse"
  type RunConfig (line 29) | type RunConfig struct

FILE: agent/workflowagents/loopagent/agent.go
  type Config (line 29) | type Config struct
  function New (line 45) | func New(cfg Config) (agent.Agent, error) {
  type loopAgent (line 71) | type loopAgent struct
    method Run (line 75) | func (a *loopAgent) Run(ctx agent.InvocationContext) iter.Seq2[*sessio...

FILE: agent/workflowagents/loopagent/agent_test.go
  function TestNewLoopAgent (line 37) | func TestNewLoopAgent(t *testing.T) {
  function newCustomAgent (line 271) | func newCustomAgent(t *testing.T, id int) agent.Agent {
  type customAgent (line 290) | type customAgent struct
    method Run (line 295) | func (a *customAgent) Run(agent.InvocationContext) iter.Seq2[*session....
  type EmptyArgs (line 307) | type EmptyArgs struct
  function exampleFunctionThatEscalates (line 309) | func exampleFunctionThatEscalates(ctx tool.Context, myArgs EmptyArgs) (m...
  function exampleFunctionThatEscalatesAndSkips (line 315) | func exampleFunctionThatEscalatesAndSkips(ctx tool.Context, myArgs Empty...
  function newLmmAgentWithFunctionCall (line 321) | func newLmmAgentWithFunctionCall(t *testing.T, id int, skipSummarization...
  type FakeLLM (line 350) | type FakeLLM struct
    method Name (line 356) | func (f *FakeLLM) Name() string {
    method GenerateContent (line 360) | func (f *FakeLLM) GenerateContent(ctx context.Context, req *model.LLMR...

FILE: agent/workflowagents/parallelagent/agent.go
  type Config (line 31) | type Config struct
  function New (line 44) | func New(cfg Config) (agent.Agent, error) {
  function run (line 67) | func run(ctx agent.InvocationContext) iter.Seq2[*session.Event, error] {
  function runSubAgent (line 130) | func runSubAgent(ctx agent.InvocationContext, agent agent.Agent, results...
  type result (line 160) | type result struct

FILE: agent/workflowagents/parallelagent/agent_test.go
  constant modelName (line 46) | modelName = "gemini-2.5-flash"
  function TestNewParallelAgent (line 48) | func TestNewParallelAgent(t *testing.T) {
  function newParallelAgent (line 176) | func newParallelAgent(t *testing.T, maxIterations uint, numSubAgents int...
  function must (line 215) | func must[T agent.Agent](a T, err error) T {
  function customRun (line 222) | func customRun(id int, agentErr error) func(agent.InvocationContext) ite...
  function TestParallelAgentWithTools (line 239) | func TestParallelAgentWithTools(t *testing.T) {
  function createAgentWithGemini (line 293) | func createAgentWithGemini(t *testing.T, name string) agent.Agent {
  function newGeminiModelForTest (line 338) | func newGeminiModelForTest(t *testing.T, modelName, agentName string) mo...
  function newGeminiTestTransport (line 360) | func newGeminiTestTransport(t *testing.T, rrfile string) (http.RoundTrip...
  function TestParallelAgent_PropagatesContextError (line 372) | func TestParallelAgent_PropagatesContextError(t *testing.T) {
  type spyAgent (line 445) | type spyAgent struct
    method Run (line 450) | func (s *spyAgent) Run(ctx agent.InvocationContext) iter.Seq2[*session...
  function TestParallelAgent_StateSync (line 464) | func TestParallelAgent_StateSync(t *testing.T) {

FILE: agent/workflowagents/sequentialagent/agent.go
  function New (line 33) | func New(cfg Config) (agent.Agent, error) {
  type Config (line 58) | type Config struct
  type sequentialAgent (line 63) | type sequentialAgent struct
    method Run (line 65) | func (a *sequentialAgent) Run(ctx agent.InvocationContext) iter.Seq2[*...

FILE: agent/workflowagents/sequentialagent/agent_test.go
  function TestNewSequentialAgent (line 35) | func TestNewSequentialAgent(t *testing.T) {
  function newCustomAgent (line 289) | func newCustomAgent(t *testing.T, id int) agent.Agent {
  function newSequentialAgent (line 303) | func newSequentialAgent(t *testing.T, subAgents []agent.Agent, name stri...
  type FakeLLM (line 320) | type FakeLLM struct
    method Name (line 325) | func (f *FakeLLM) Name() string {
    method GenerateContent (line 329) | func (f *FakeLLM) GenerateContent(ctx context.Context, req *model.LLMR...

FILE: artifact/artifact_key_test.go
  function TestArtifactKey (line 23) | func TestArtifactKey(t *testing.T) {

FILE: artifact/gcsartifact/gcs_client.go
  type gcsClient (line 26) | type gcsClient interface
  type gcsBucket (line 31) | type gcsBucket interface
  type gcsObject (line 37) | type gcsObject interface
  type gcsObjectIterator (line 45) | type gcsObjectIterator interface
  type gcsWriter (line 50) | type gcsWriter interface
  type gcsClientWrapper (line 58) | type gcsClientWrapper struct
    method bucket (line 63) | func (w *gcsClientWrapper) bucket(name string) gcsBucket {
  type gcsBucketWrapper (line 70) | type gcsBucketWrapper struct
    method object (line 75) | func (w *gcsBucketWrapper) object(name string) gcsObject {
    method objects (line 83) | func (w *gcsBucketWrapper) objects(ctx context.Context, q *storage.Que...
  type gcsObjectWrapper (line 91) | type gcsObjectWrapper struct
    method newWriter (line 96) | func (w *gcsObjectWrapper) newWriter(ctx context.Context) gcsWriter {
    method newReader (line 101) | func (w *gcsObjectWrapper) newReader(ctx context.Context) (io.ReadClos...
    method delete (line 106) | func (w *gcsObjectWrapper) delete(ctx context.Context) error {
    method attrs (line 111) | func (w *gcsObjectWrapper) attrs(ctx context.Context) (*storage.Object...
  type gcsObjectIteratorWrapper (line 116) | type gcsObjectIteratorWrapper struct
    method next (line 120) | func (w *gcsObjectIteratorWrapper) next() (*storage.ObjectAttrs, error) {
  type gcsWriterWrapper (line 125) | type gcsWriterWrapper struct
    method Write (line 129) | func (g *gcsWriterWrapper) Write(p []byte) (n int, err error) {
    method Close (line 133) | func (g *gcsWriterWrapper) Close() error {
    method SetContentType (line 137) | func (g *gcsWriterWrapper) SetContentType(cType string) {

FILE: artifact/gcsartifact/gcs_test.go
  function newGCSArtifactServiceForTesting (line 35) | func newGCSArtifactServiceForTesting(bucketName string) (artifact.Servic...
  function TestGCSArtifactService (line 45) | func TestGCSArtifactService(t *testing.T) {
  type fakeClient (line 54) | type fakeClient struct
    method bucket (line 67) | func (c *fakeClient) bucket(name string) gcsBucket {
  function newFakeClient (line 58) | func newFakeClient() gcsClient {
  type fakeBucket (line 72) | type fakeBucket struct
    method object (line 78) | func (f *fakeBucket) object(name string) gcsObject {
    method objects (line 88) | func (f *fakeBucket) objects(ctx context.Context, q *storage.Query) gc...
  type fakeObject (line 111) | type fakeObject struct
    method newWriter (line 120) | func (f *fakeObject) newWriter(ctx context.Context) gcsWriter {
    method attrs (line 129) | func (f *fakeObject) attrs(ctx context.Context) (*storage.ObjectAttrs,...
    method delete (line 139) | func (f *fakeObject) delete(ctx context.Context) error {
    method newReader (line 147) | func (f *fakeObject) newReader(ctx context.Context) (io.ReadCloser, er...
  type fakeWriter (line 157) | type fakeWriter struct
    method Write (line 163) | func (w *fakeWriter) Write(p []byte) (n int, err error) {
    method Close (line 167) | func (w *fakeWriter) Close() error {
    method SetContentType (line 176) | func (w *fakeWriter) SetContentType(cType string) {
  type fakeObjectIterator (line 182) | type fakeObjectIterator struct
    method next (line 189) | func (i *fakeObjectIterator) next() (*storage.ObjectAttrs, error) {

FILE: artifact/gcsartifact/service.go
  type gcsService (line 43) | type gcsService struct
    method Save (line 94) | func (s *gcsService) Save(ctx context.Context, req *artifact.SaveReque...
    method Delete (line 140) | func (s *gcsService) Delete(ctx context.Context, req *artifact.DeleteR...
    method Load (line 185) | func (s *gcsService) Load(ctx context.Context, req *artifact.LoadReque...
    method fetchFilenamesFromPrefix (line 242) | func (s *gcsService) fetchFilenamesFromPrefix(ctx context.Context, pre...
    method List (line 280) | func (s *gcsService) List(ctx context.Context, req *artifact.ListReque...
    method versions (line 306) | func (s *gcsService) versions(ctx context.Context, req *artifact.Versi...
    method Versions (line 343) | func (s *gcsService) Versions(ctx context.Context, req *artifact.Versi...
  function NewService (line 50) | func NewService(ctx context.Context, bucketName string, opts ...option.C...
  function fileHasUserNamespace (line 66) | func fileHasUserNamespace(filename string) bool {
  function buildBlobName (line 71) | func buildBlobName(appName, userID, sessionID, fileName string, version ...
  function buildBlobNamePrefix (line 78) | func buildBlobNamePrefix(appName, userID, sessionID, fileName string) st...
  function buildSessionPrefix (line 85) | func buildSessionPrefix(appName, userID, sessionID string) string {
  function buildUserPrefix (line 89) | func buildUserPrefix(appName, userID string) string {

FILE: artifact/inmemory.go
  type inMemoryService (line 36) | type inMemoryService struct
    method scan (line 83) | func (s *inMemoryService) scan(lo, hi string) iter.Seq2[artifactKey, *...
    method find (line 98) | func (s *inMemoryService) find(appName, userID, sessionID, fileName st...
    method get (line 108) | func (s *inMemoryService) get(appName, userID, sessionID, fileName str...
    method set (line 119) | func (s *inMemoryService) set(appName, userID, sessionID, fileName str...
    method delete (line 130) | func (s *inMemoryService) delete(appName, userID, sessionID, fileName ...
    method Save (line 142) | func (s *inMemoryService) Save(ctx context.Context, req *SaveRequest) ...
    method Delete (line 166) | func (s *inMemoryService) Delete(ctx context.Context, req *DeleteReque...
    method Load (line 194) | func (s *inMemoryService) Load(ctx context.Context, req *LoadRequest) ...
    method List (line 225) | func (s *inMemoryService) List(ctx context.Context, req *ListRequest) ...
    method Versions (line 262) | func (s *inMemoryService) Versions(ctx context.Context, req *VersionsR...
  function InMemoryService (line 43) | func InMemoryService() Service {
  function fileHasUserNamespace (line 48) | func fileHasUserNamespace(filename string) bool {
  constant userScopedArtifactKey (line 54) | userScopedArtifactKey = "user"
  type artifactKey (line 56) | type artifactKey struct
    method Encode (line 65) | func (ak artifactKey) Encode() string {
    method Decode (line 70) | func (ak *artifactKey) Decode(key string) error {

FILE: artifact/inmemory_test.go
  function TestInMemoryArtifactService (line 24) | func TestInMemoryArtifactService(t *testing.T) {

FILE: artifact/request_validation_test.go
  type Validator (line 26) | type Validator interface
  type ValidatorTestCase (line 30) | type ValidatorTestCase struct
  function TestSaveRequest_Validate (line 38) | func TestSaveRequest_Validate(t *testing.T) {
  function TestLoadRequest_Validate (line 130) | func TestLoadRequest_Validate(t *testing.T) {
  function TestDeleteRequest_Validate (line 183) | func TestDeleteRequest_Validate(t *testing.T) {
  function TestListRequest_Validate (line 236) | func TestListRequest_Validate(t *testing.T) {
  function TestVersionsRequest_Validate (line 276) | func TestVersionsRequest_Validate(t *testing.T) {
  function executeValidatorTestCases (line 328) | func executeValidatorTestCases(t *testing.T, requestTypeName string, tes...
  function TestValidateRequiredStrings (line 347) | func TestValidateRequiredStrings(t *testing.T) {

FILE: artifact/service.go
  type Service (line 31) | type Service interface
  type requiredField (line 48) | type requiredField struct
  type SaveRequest (line 54) | type SaveRequest struct
    method Validate (line 79) | func (req *SaveRequest) Validate() error {
  function validateRequiredStrings (line 68) | func validateRequiredStrings(fields []requiredField) []string {
  function validateFileName (line 112) | func validateFileName(name string) error {
  type SaveResponse (line 120) | type SaveResponse struct
  type LoadRequest (line 125) | type LoadRequest struct
    method Validate (line 133) | func (req *LoadRequest) Validate() error {
  type LoadResponse (line 159) | type LoadResponse struct
  type DeleteRequest (line 165) | type DeleteRequest struct
    method Validate (line 173) | func (req *DeleteRequest) Validate() error {
  type ListRequest (line 199) | type ListRequest struct
    method Validate (line 204) | func (req *ListRequest) Validate() error {
  type ListResponse (line 223) | type ListResponse struct
  type VersionsRequest (line 228) | type VersionsRequest struct
    method Validate (line 233) | func (req *VersionsRequest) Validate() error {
  type VersionsResponse (line 259) | type VersionsResponse struct

FILE: cmd/adkgo/adkgo.go
  function main (line 23) | func main() {

FILE: cmd/adkgo/internal/deploy/cloudrun/cloudrun.go
  type gCloudFlags (line 34) | type gCloudFlags struct
  type cloudRunServiceFlags (line 39) | type cloudRunServiceFlags struct
  type localProxyFlags (line 48) | type localProxyFlags struct
  type buildFlags (line 52) | type buildFlags struct
  type sourceFlags (line 59) | type sourceFlags struct
  type deployCloudRunFlags (line 64) | type deployCloudRunFlags struct
    method computeFlags (line 105) | func (f *deployCloudRunFlags) computeFlags() error {
    method cleanTemp (line 145) | func (f *deployCloudRunFlags) cleanTemp() error {
    method compileEntryPoint (line 158) | func (f *deployCloudRunFlags) compileEntryPoint() error {
    method prepareDockerfile (line 176) | func (f *deployCloudRunFlags) prepareDockerfile() error {
    method gcloudDeployToCloudRun (line 205) | func (f *deployCloudRunFlags) gcloudDeployToCloudRun() error {
    method runGcloudProxy (line 226) | func (f *deployCloudRunFlags) runGcloudProxy() error {
    method deployOnCloudRun (line 246) | func (f *deployCloudRunFlags) deployOnCloudRun() error {
  function init (line 88) | func init() {

FILE: cmd/adkgo/internal/deploy/deploy.go
  function init (line 37) | func init() {

FILE: cmd/adkgo/internal/root/root.go
  function Execute (line 32) | func Execute() {

FILE: cmd/internal/adkcli/main.go
  function main (line 35) | func main() {

FILE: cmd/launcher/console/console.go
  type consoleConfig (line 42) | type consoleConfig struct
  type consoleLauncher (line 50) | type consoleLauncher struct
    method Run (line 68) | func (l *consoleLauncher) Run(ctx context.Context, config *launcher.Co...
    method Parse (line 208) | func (l *consoleLauncher) Parse(args []string) ([]string, error) {
    method Keyword (line 224) | func (l *consoleLauncher) Keyword() string {
    method CommandLineSyntax (line 229) | func (l *consoleLauncher) CommandLineSyntax() string {
    method SimpleDescription (line 234) | func (l *consoleLauncher) SimpleDescription() string {
    method Execute (line 239) | func (l *consoleLauncher) Execute(ctx context.Context, config *launche...
  function NewLauncher (line 56) | func NewLauncher() launcher.SubLauncher {

FILE: cmd/launcher/full/full.go
  function NewLauncher (line 29) | func NewLauncher() launcher.Launcher {

FILE: cmd/launcher/internal/telemetry/telemetry.go
  function InitAndSetGlobalOtelProviders (line 26) | func InitAndSetGlobalOtelProviders(ctx context.Context, config *launcher...

FILE: cmd/launcher/launcher.go
  type Launcher (line 34) | type Launcher interface
  type SubLauncher (line 44) | type SubLauncher interface
  type Config (line 58) | type Config struct

FILE: cmd/launcher/prod/prod.go
  function NewLauncher (line 29) | func NewLauncher() launcher.Launcher {

FILE: cmd/launcher/universal/universal.go
  type uniLauncher (line 29) | type uniLauncher struct
    method Execute (line 35) | func (l *uniLauncher) Execute(ctx context.Context, config *launcher.Co...
    method ParseAndRun (line 48) | func (l *uniLauncher) ParseAndRun(ctx context.Context, config *launche...
    method run (line 64) | func (l *uniLauncher) run(ctx context.Context, config *launcher.Config...
    method parse (line 69) | func (l *uniLauncher) parse(args []string) ([]string, error) {
    method CommandLineSyntax (line 101) | func (l *uniLauncher) CommandLineSyntax() string {
    method simpleDescription (line 120) | func (l *uniLauncher) simpleDescription() string {
  function NewLauncher (line 40) | func NewLauncher(sublaunchers ...launcher.SubLauncher) launcher.Launcher {
  function ErrorOnUnparsedArgs (line 127) | func ErrorOnUnparsedArgs(args []string) error {

FILE: cmd/launcher/web/a2a/a2a.go
  constant apiPath (line 35) | apiPath = "/a2a/invoke"
  type a2aConfig (line 38) | type a2aConfig struct
  type a2aLauncher (line 42) | type a2aLauncher struct
    method CommandLineSyntax (line 62) | func (a *a2aLauncher) CommandLineSyntax() string {
    method Keyword (line 67) | func (a *a2aLauncher) Keyword() string {
    method Parse (line 71) | func (a *a2aLauncher) Parse(args []string) ([]string, error) {
    method SetupSubrouters (line 81) | func (a *a2aLauncher) SetupSubrouters(router *mux.Router, config *laun...
    method SimpleDescription (line 117) | func (a *a2aLauncher) SimpleDescription() string {
    method UserMessage (line 122) | func (a *a2aLauncher) UserMessage(webUrl string, printer func(v ...any...
  function NewLauncher (line 48) | func NewLauncher() web.Sublauncher {

FILE: cmd/launcher/web/a2a/a2a_test.go
  function getFreePort (line 35) | func getFreePort(t *testing.T) int {
  function TestWebLauncher_ServesA2A (line 56) | func TestWebLauncher_ServesA2A(t *testing.T) {

FILE: cmd/launcher/web/api/api.go
  type apiConfig (line 35) | type apiConfig struct
  type apiLauncher (line 42) | type apiLauncher struct
    method CommandLineSyntax (line 48) | func (a *apiLauncher) CommandLineSyntax() string {
    method UserMessage (line 69) | func (a *apiLauncher) UserMessage(webURL string, printer func(v ...any...
    method SetupSubrouters (line 75) | func (a *apiLauncher) SetupSubrouters(router *mux.Router, config *laun...
    method Keyword (line 108) | func (a *apiLauncher) Keyword() string {
    method Parse (line 113) | func (a *apiLauncher) Parse(args []string) ([]string, error) {
    method SimpleDescription (line 129) | func (a *apiLauncher) SimpleDescription() string {
  function corsWithArgs (line 53) | func corsWithArgs(frontendAddress string) func(next http.Handler) http.H...
  function NewLauncher (line 134) | func NewLauncher() weblauncher.Sublauncher {

FILE: cmd/launcher/web/web.go
  type webConfig (line 38) | type webConfig struct
  type webLauncher (line 48) | type webLauncher struct
    method Execute (line 57) | func (w *webLauncher) Execute(ctx context.Context, config *launcher.Co...
    method CommandLineSyntax (line 89) | func (w *webLauncher) CommandLineSyntax() string {
    method Keyword (line 104) | func (w *webLauncher) Keyword() string {
    method Parse (line 111) | func (w *webLauncher) Parse(args []string) ([]string, error) {
    method Run (line 151) | func (w *webLauncher) Run(ctx context.Context, config *launcher.Config...
    method SimpleDescription (line 223) | func (w *webLauncher) SimpleDescription() string {
  type Sublauncher (line 72) | type Sublauncher interface
  function NewLauncher (line 229) | func NewLauncher(sublaunchers ...Sublauncher) launcher.SubLauncher {
  function logger (line 248) | func logger(inner http.Handler) http.Handler {
  function BuildBaseRouter (line 264) | func BuildBaseRouter() *mux.Router {

FILE: cmd/launcher/web/webui/distr/assets/audio-processor.js
  class AudioProcessor (line 17) | class AudioProcessor extends AudioWorkletProcessor {
    method constructor (line 18) | constructor() {
    method process (line 25) | process(inputs, outputs, parameters) {
    method resample (line 39) | resample(audioData) {

FILE: cmd/launcher/web/webui/distr/chunk-2FK4DXD6.js
  function M (line 1) | function M(e,F){if(e&1&&h(0,0),e&2){let i=F.$implicit,n=y();m("surfaceId...
  class e (line 1) | class e extends _{static \u0275fac=(()=>{let i;return function(t){return...

FILE: cmd/launcher/web/webui/distr/chunk-4ZK7FQPX.js
  function _ (line 1) | function _(e,D){if(e&1&&(m(0,"section")(1,"span",1),f(2),d()()),e&2){let...
  class e (line 1) | class e extends M{name=I.required();resolvedName=C(()=>this.resolvePrimi...

FILE: cmd/launcher/web/webui/distr/chunk-7TJPJFPQ.js
  function I (line 1) | function I(e){let t=me;return me=e,t}
  function ji (line 1) | function ji(){return me}
  function Kt (line 1) | function Kt(e){if(Li)throw new Error("");if(me===null)return;me.consumer...
  function Nh (line 1) | function Nh(){Ha++}
  function xn (line 1) | function xn(e){if(!(mr(e)&&!e.dirty)&&!(!e.dirty&&e.lastCleanEpoch===Ha)...
  function $a (line 1) | function $a(e){if(e.consumers===void 0)return;let t=Li;Li=!0;try{for(let...
  function Ua (line 1) | function Ua(){return me?.consumerAllowSignalWrites!==!1}
  function nD (line 1) | function nD(e){e.dirty=!0,$a(e),e.consumerMarkedDirty?.(e)}
  function hr (line 1) | function hr(e){e.dirty=!1,e.lastCleanEpoch=Ha}
  function Tt (line 1) | function Tt(e){return e&&kh(e),I(e)}
  function kh (line 1) | function kh(e){e.producersTail=void 0,e.recomputing=!0}
  function Jt (line 1) | function Jt(e,t){I(t),e&&Rh(e)}
  function Rh (line 1) | function Rh(e){e.recomputing=!1;let t=e.producersTail,n=t!==void 0?t.nex...
  function gr (line 1) | function gr(e){for(let t=e.producers;t!==void 0;t=t.nextProducer){let n=...
  function Xt (line 1) | function Xt(e){if(mr(e)){let t=e.producers;for(;t!==void 0;)t=za(t)}e.pr...
  function Fh (line 1) | function Fh(e,t){let n=e.consumersTail,r=mr(e);if(n!==void 0?(t.nextCons...
  function za (line 1) | function za(e){let t=e.producer,n=e.nextProducer,r=e.nextConsumer,o=e.pr...
  function mr (line 1) | function mr(e){return e.consumerIsAlwaysLive||e.consumers!==void 0}
  function bo (line 1) | function bo(e){tD?.(e)}
  function rD (line 1) | function rD(e,t){let n=t.producersTail;if(n!==void 0){let r=t.producers;...
  function vo (line 1) | function vo(e,t){return Object.is(e,t)}
  function Do (line 1) | function Do(e,t){let n=Object.create(oD);n.computation=e,t!==void 0&&(n....
  method producerMustRecompute (line 1) | producerMustRecompute(e){return e.value===Yt||e.value===wn}
  method producerRecomputeValue (line 1) | producerRecomputeValue(e){if(e.value===wn)throw new Error("");let t=e.va...
  function iD (line 1) | function iD(){throw new Error}
  function Ph (line 1) | function Ph(e){Oh(e)}
  function qa (line 1) | function qa(e){Oh=e}
  function Ga (line 1) | function Ga(e,t){let n=Object.create(Eo);n.value=e,t!==void 0&&(n.equal=...
  function Lh (line 1) | function Lh(e){return Kt(e),e.value}
  function In (line 1) | function In(e,t){Ua()||Ph(e),e.equal(e.value,t)||(e.value=t,uD(e))}
  function Bi (line 1) | function Bi(e,t){Ua()||Ph(e),In(e,t(e.value))}
  function uD (line 1) | function uD(e){e.version++,Nh(),$a(e),sD?.(e)}
  function Za (line 1) | function Za(e){if(e.dirty=!1,e.version>0&&!gr(e))return;e.version++;let ...
  function k (line 1) | function k(e){return typeof e=="function"}
  function yr (line 1) | function yr(e){let n=e(r=>{Error.call(r),r.stack=new Error().stack});ret...
  function Tn (line 3) | function Tn(e,t){if(e){let n=e.indexOf(t);0<=n&&e.splice(n,1)}}
  method constructor (line 3) | constructor(t){this.initialTeardown=t,this.closed=!1,this._parentage=nul...
  method unsubscribe (line 3) | unsubscribe(){let t;if(!this.closed){this.closed=!0;let{_parentage:n}=th...
  method add (line 3) | add(t){var n;if(t&&t!==this)if(this.closed)jh(t);else{if(t instanceof e)...
  method _hasParent (line 3) | _hasParent(t){let{_parentage:n}=this;return n===t||Array.isArray(n)&&n.i...
  method _addParent (line 3) | _addParent(t){let{_parentage:n}=this;this._parentage=Array.isArray(n)?(n...
  method _removeParent (line 3) | _removeParent(t){let{_parentage:n}=this;n===t?this._parentage=null:Array...
  method remove (line 3) | remove(t){let{_finalizers:n}=this;n&&Tn(n,t),t instanceof e&&t._removePa...
  function Hi (line 3) | function Hi(e){return e instanceof X||e&&"closed"in e&&k(e.remove)&&k(e....
  function jh (line 3) | function jh(e){k(e)?e():e.unsubscribe()}
  method setTimeout (line 3) | setTimeout(e,t,...n){let{delegate:r}=br;return r?.setTimeout?r.setTimeou...
  method clearTimeout (line 3) | clearTimeout(e){let{delegate:t}=br;return(t?.clearTimeout||clearTimeout)...
  function $i (line 3) | function $i(e){br.setTimeout(()=>{let{onUnhandledError:t}=We;if(t)t(e);e...
  function St (line 3) | function St(){}
  function Vh (line 3) | function Vh(e){return Qa("E",void 0,e)}
  function Hh (line 3) | function Hh(e){return Qa("N",e,void 0)}
  function Qa (line 3) | function Qa(e,t,n){return{kind:e,value:t,error:n}}
  function vr (line 3) | function vr(e){if(We.useDeprecatedSynchronousErrorHandling){let t=!Sn;if...
  function $h (line 3) | function $h(e){We.useDeprecatedSynchronousErrorHandling&&Sn&&(Sn.errorTh...
  method constructor (line 3) | constructor(t){super(),this.isStopped=!1,t?(this.destination=t,Hi(t)&&t....
  method create (line 3) | static create(t,n,r){return new Ze(t,n,r)}
  method next (line 3) | next(t){this.isStopped?Ja(Hh(t),this):this._next(t)}
  method error (line 3) | error(t){this.isStopped?Ja(Vh(t),this):(this.isStopped=!0,this._error(t))}
  method complete (line 3) | complete(){this.isStopped?Ja(Bh,this):(this.isStopped=!0,this._complete())}
  method unsubscribe (line 3) | unsubscribe(){this.closed||(this.isStopped=!0,super.unsubscribe(),this.d...
  method _next (line 3) | _next(t){this.destination.next(t)}
  method _error (line 3) | _error(t){try{this.destination.error(t)}finally{this.unsubscribe()}}
  method _complete (line 3) | _complete(){try{this.destination.complete()}finally{this.unsubscribe()}}
  function Ka (line 3) | function Ka(e,t){return aD.call(e,t)}
  method constructor (line 3) | constructor(t){this.partialObserver=t}
  method next (line 3) | next(t){let{partialObserver:n}=this;if(n.next)try{n.next(t)}catch(r){Ui(...
  method error (line 3) | error(t){let{partialObserver:n}=this;if(n.error)try{n.error(t)}catch(r){...
  method complete (line 3) | complete(){let{partialObserver:t}=this;if(t.complete)try{t.complete()}ca...
  method constructor (line 3) | constructor(t,n,r){super();let o;if(k(t)||!t)o={next:t??void 0,error:n??...
  function Ui (line 3) | function Ui(e){We.useDeprecatedSynchronousErrorHandling?$h(e):$i(e)}
  function cD (line 3) | function cD(e){throw e}
  function Ja (line 3) | function Ja(e,t){let{onStoppedNotification:n}=We;n&&br.setTimeout(()=>n(...
  function Ee (line 3) | function Ee(e){return e}
  function dD (line 3) | function dD(...e){return ec(e)}
  function ec (line 3) | function ec(e){return e.length===0?Ee:e.length===1?e[0]:function(n){retu...
  class e (line 3) | class e{constructor(n){n&&(this._subscribe=n)}lift(n){let r=new e;return...
    method constructor (line 3) | constructor(n){n&&(this._subscribe=n)}
    method lift (line 3) | lift(n){let r=new e;return r.source=this,r.operator=n,r}
    method subscribe (line 3) | subscribe(n,r,o){let i=pD(n)?n:new Ze(n,r,o);return vr(()=>{let{operat...
    method _trySubscribe (line 3) | _trySubscribe(n){try{return this._subscribe(n)}catch(r){n.error(r)}}
    method forEach (line 3) | forEach(n,r){return r=Uh(r),new r((o,i)=>{let s=new Ze({next:u=>{try{n...
    method _subscribe (line 3) | _subscribe(n){var r;return(r=this.source)===null||r===void 0?void 0:r....
    method [Dr] (line 3) | [Dr](){return this}
    method pipe (line 3) | pipe(...n){return ec(n)(this)}
    method toPromise (line 3) | toPromise(n){return n=Uh(n),new n((r,o)=>{let i;this.subscribe(s=>i=s,...
    method constructor (line 3) | constructor(){super(),this.closed=!1,this.currentObservers=null,this.o...
    method lift (line 3) | lift(n){let r=new zi(this,this);return r.operator=n,r}
    method _throwIfClosed (line 3) | _throwIfClosed(){if(this.closed)throw new qh}
    method next (line 3) | next(n){vr(()=>{if(this._throwIfClosed(),!this.isStopped){this.current...
    method error (line 3) | error(n){vr(()=>{if(this._throwIfClosed(),!this.isStopped){this.hasErr...
    method complete (line 3) | complete(){vr(()=>{if(this._throwIfClosed(),!this.isStopped){this.isSt...
    method unsubscribe (line 3) | unsubscribe(){this.isStopped=this.closed=!0,this.observers=this.curren...
    method observed (line 3) | get observed(){var n;return((n=this.observers)===null||n===void 0?void...
    method _trySubscribe (line 3) | _trySubscribe(n){return this._throwIfClosed(),super._trySubscribe(n)}
    method _subscribe (line 3) | _subscribe(n){return this._throwIfClosed(),this._checkFinalizedStatuse...
    method _innerSubscribe (line 3) | _innerSubscribe(n){let{hasError:r,isStopped:o,observers:i}=this;return...
    method _checkFinalizedStatuses (line 3) | _checkFinalizedStatuses(n){let{hasError:r,thrownError:o,isStopped:i}=t...
    method asObservable (line 3) | asObservable(){let n=new B;return n.source=this,n}
    method hasPendingTasks (line 4) | get hasPendingTasks(){return this.destroyed?!1:this.pendingTask.value}
    method hasPendingTasksObservable (line 4) | get hasPendingTasksObservable(){return this.destroyed?new B(n=>{n.next...
    method add (line 4) | add(){!this.hasPendingTasks&&!this.destroyed&&this.pendingTask.next(!0...
    method has (line 4) | has(n){return this.pendingTasks.has(n)}
    method remove (line 4) | remove(n){this.pendingTasks.delete(n),this.debugTaskTracker?.remove(n)...
    method ngOnDestroy (line 4) | ngOnDestroy(){this.pendingTasks.clear(),this.hasPendingTasks&&this.pen...
    method constructor (line 4) | constructor(n,r){this.view=n,this.node=r}
    method add (line 4) | add(){let n=this.internalPendingTasks.add();return()=>{this.internalPe...
    method run (line 4) | run(n){let r=this.add();n().catch(this.errorHandler).finally(r)}
    method constructor (line 4) | constructor(n){this.nativeElement=n}
    method execute (line 4) | execute(){this.impl?.execute()}
    method constructor (line 4) | constructor(){b(ot,{optional:!0})}
    method execute (line 4) | execute(){let n=this.sequences.size>0;n&&Y(q.AfterRenderHooksStart),th...
    method register (line 4) | register(n){let{view:r}=n;r!==void 0?((r[Hn]??=[]).push(n),zn(r),r[L]|...
    method addSequence (line 4) | addSequence(n){this.sequences.add(n),this.scheduler.notify(7)}
    method unregister (line 4) | unregister(n){this.executing&&this.sequences.has(n)?(n.erroredOrDestro...
    method maybeTrace (line 4) | maybeTrace(n,r){return r?r.run(wu.AFTER_NEXT_RENDER,n):n()}
    method constructor (line 4) | constructor(n,r,o){this._declarationLView=n,this._declarationTContaine...
    method ssrId (line 4) | get ssrId(){return this._declarationTContainer.tView?.ssrId||null}
    method createEmbeddedView (line 4) | createEmbeddedView(n,r){return this.createEmbeddedViewImpl(n,r)}
    method createEmbeddedViewImpl (line 4) | createEmbeddedViewImpl(n,r,o){let i=li(this._declarationLView,this._de...
    method constructor (line 4) | constructor(n){this._injector=n}
    method getOrCreateStandaloneInjector (line 4) | getOrCreateStandaloneInjector(n){if(!n.standalone)return null;if(!this...
    method ngOnDestroy (line 4) | ngOnDestroy(){try{for(let n of this.cachedInjectors.values())n!==null&...
    method log (line 4) | log(n){console.log(n)}
    method warn (line 4) | warn(n){console.warn(n)}
    method constructor (line 4) | constructor(n,r,o){this._ngZone=n,this.registry=r,As()&&(this._destroy...
    method _watchAngularEvents (line 4) | _watchAngularEvents(){let n=this._ngZone.onUnstable.subscribe({next:()...
    method isStable (line 4) | isStable(){return this._isZoneStable&&!this._ngZone.hasPendingMacrotasks}
    method _runCallbacksIfReady (line 4) | _runCallbacksIfReady(){if(this.isStable())queueMicrotask(()=>{for(;thi...
    method getPendingTasks (line 4) | getPendingTasks(){return this._taskTrackingZone?this._taskTrackingZone...
    method addCallback (line 4) | addCallback(n,r,o){let i=-1;r&&r>0&&(i=setTimeout(()=>{this._callbacks...
    method whenStable (line 4) | whenStable(n,r,o){if(o&&!this._taskTrackingZone)throw new Error('Task ...
    method registerApplication (line 4) | registerApplication(n){this.registry.registerApplication(n,this)}
    method unregisterApplication (line 4) | unregisterApplication(n){this.registry.unregisterApplication(n)}
    method findProviders (line 4) | findProviders(n,r,o){return[]}
    method registerApplication (line 4) | registerApplication(n,r){this._applications.set(n,r)}
    method unregisterApplication (line 4) | unregisterApplication(n){this._applications.delete(n)}
    method unregisterAllApplications (line 4) | unregisterAllApplications(){this._applications.clear()}
    method getTestability (line 4) | getTestability(n){return this._applications.get(n)||null}
    method getAllTestabilities (line 4) | getAllTestabilities(){return Array.from(this._applications.values())}
    method getAllRootElements (line 4) | getAllRootElements(){return Array.from(this._applications.keys())}
    method findTestabilityInTree (line 4) | findTestabilityInTree(n,r=!0){return Yd?.findTestabilityInTree(this,n,...
    method constructor (line 4) | constructor(){}
    method runInitializers (line 4) | runInitializers(){if(this.initialized)return;let n=[];for(let o of thi...
    method allViews (line 4) | get allViews(){return[...(this.includeAllTestViews?this.allTestViews:t...
    method destroyed (line 4) | get destroyed(){return this._destroyed}
    method isStable (line 4) | get isStable(){return this.internalPendingTask.hasPendingTasksObservab...
    method constructor (line 4) | constructor(){b(ot,{optional:!0})}
    method whenStable (line 4) | whenStable(){let n;return new Promise(r=>{n=this.isStable.subscribe({n...
    method injector (line 4) | get injector(){return this._injector}
    method bootstrap (line 4) | bootstrap(n,r){return this.bootstrapImpl(n,r)}
    method bootstrapImpl (line 4) | bootstrapImpl(n,r,o=fe.NULL){return this._injector.get(be).run(()=>{Y(...
    method tick (line 4) | tick(){this.zonelessEnabled||(this.dirtyFlags|=1),this._tick()}
    method _tick (line 4) | _tick(){Y(q.ChangeDetectionStart),this.tracingSnapshot!==null?this.tra...
    method synchronize (line 4) | synchronize(){this._rendererFactory===null&&!this._injector.destroyed&...
    method synchronizeOnce (line 4) | synchronizeOnce(){this.dirtyFlags&16&&(this.dirtyFlags&=-17,this.rootE...
    method syncDirtyFlagsWithViews (line 4) | syncDirtyFlagsWithViews(){if(this.allViews.some(({_lView:n})=>Uo(n))){...
    method attachView (line 4) | attachView(n){let r=n;this._views.push(r),r.attachToAppRef(this)}
    method detachView (line 4) | detachView(n){let r=n;Ko(this._views,r),r.detachFromAppRef()}
    method _loadComponent (line 4) | _loadComponent(n){this.attachView(n.hostView);try{this.tick()}catch(o)...
    method ngOnDestroy (line 4) | ngOnDestroy(){if(!this._destroyed)try{this._destroyListeners.forEach(n...
    method onDestroy (line 4) | onDestroy(n){return this._destroyListeners.push(n),()=>Ko(this._destro...
    method destroy (line 4) | destroy(){if(this._destroyed)throw new C(406,!1);let n=this._injector;...
    method viewCount (line 4) | get viewCount(){return this._views.length}
    method compileModuleSync (line 4) | compileModuleSync(n){return new du(n)}
    method compileModuleAsync (line 4) | compileModuleAsync(n){return Promise.resolve(this.compileModuleSync(n))}
    method compileModuleAndAllComponentsSync (line 4) | compileModuleAndAllComponentsSync(n){let r=this.compileModuleSync(n),o...
    method compileModuleAndAllComponentsAsync (line 4) | compileModuleAndAllComponentsAsync(n){return Promise.resolve(this.comp...
    method clearCache (line 4) | clearCache(){}
    method clearCacheFor (line 4) | clearCacheFor(n){}
    method getModuleId (line 4) | getModuleId(n){}
    method constructor (line 4) | constructor(){this.subscriptions.add(this.appRef.afterTick.subscribe((...
    method switchToMicrotaskScheduler (line 4) | switchToMicrotaskScheduler(){this.ngZone.runOutsideAngular(()=>{let n=...
    method notify (line 4) | notify(n){if(!this.zonelessEnabled&&n===5)return;switch(n){case 0:{thi...
    method shouldScheduleTick (line 4) | shouldScheduleTick(){return!(this.appRef.destroyed||this.pendingRender...
    method tick (line 4) | tick(){if(this.runningTick||this.appRef.destroyed)return;if(this.appRe...
    method ngOnDestroy (line 4) | ngOnDestroy(){this.subscriptions.unsubscribe(),this.cleanup()}
    method cleanup (line 4) | cleanup(){if(this.runningTick=!1,this.cancelScheduledCallback?.(),this...
    method constructor (line 4) | constructor(n){this.factories=n}
    method create (line 4) | static create(n,r){if(r!=null){let o=r.factories.slice();n=n.concat(o)...
    method extend (line 4) | static extend(n){return{provide:e,useFactory:()=>{let r=b(e,{optional:...
    method find (line 4) | find(n){let r=this.factories.find(o=>o.supports(n));if(r!=null)return ...
    method constructor (line 4) | constructor(n){this.factories=n}
    method create (line 4) | static create(n,r){if(r){let o=r.factories.slice();n=n.concat(o)}retur...
    method extend (line 4) | static extend(n){return{provide:e,useFactory:()=>{let r=b(e,{optional:...
    method find (line 4) | find(n){let r=this.factories.find(o=>o.supports(n));if(r)return r;thro...
    method constructor (line 4) | constructor(n){}
    method constructor (line 422) | constructor(n={mapCtor:Map,arrayCtor:Array,setCtor:Set,objCtor:Object}...
    method getSurfaces (line 422) | getSurfaces(){return this.surfaces}
    method clearSurfaces (line 422) | clearSurfaces(){this.surfaces.clear()}
    method processMessages (line 422) | processMessages(n){for(let r of n)r.beginRendering&&this.handleBeginRe...
    method getData (line 422) | getData(n,r,o=e.DEFAULT_SURFACE_ID){let i=this.getOrCreateSurface(o);i...
    method setData (line 422) | setData(n,r,o,i=e.DEFAULT_SURFACE_ID){if(!n){console.warn("No componen...
    method resolvePath (line 422) | resolvePath(n,r){return n.startsWith("/")?n:r&&r!=="/"?r.endsWith("/")...
    method parseIfJsonString (line 422) | parseIfJsonString(n){if(typeof n!="string")return n;let r=n.trim();if(...
    method convertKeyValueArrayToMap (line 422) | convertKeyValueArrayToMap(n){let r=new this.mapCtor;for(let o of n){if...
    method setDataByPath (line 422) | setDataByPath(n,r,o){if(Array.isArray(o)&&(o.length===0||$(o[0])&&"key...
    method normalizePath (line 422) | normalizePath(n){return"/"+n.replace(/\[(\d+)\]/g,".$1").split(".").fi...
    method getDataByPath (line 422) | getDataByPath(n,r){let o=this.normalizePath(r).split("/").filter(s=>s)...
    method getOrCreateSurface (line 422) | getOrCreateSurface(n){let r=this.surfaces.get(n);return r||(r=new this...
    method handleBeginRendering (line 422) | handleBeginRendering(n,r){let o=this.getOrCreateSurface(r);o.rootCompo...
    method handleSurfaceUpdate (line 422) | handleSurfaceUpdate(n,r){let o=this.getOrCreateSurface(r);for(let i of...
    method handleDataModelUpdate (line 422) | handleDataModelUpdate(n,r){let o=this.getOrCreateSurface(r),i=n.path??...
    method handleDeleteSurface (line 422) | handleDeleteSurface(n){this.surfaces.delete(n.surfaceId)}
    method rebuildComponentTree (line 422) | rebuildComponentTree(n){if(!n.rootComponentId){n.componentTree=null;re...
    method findValueKey (line 422) | findValueKey(n){return Object.keys(n).find(r=>r.startsWith("value"))}
    method buildNodeRecursive (line 422) | buildNodeRecursive(n,r,o,i,s=""){let u=`${n}${s}`,{components:a}=r;if(...
    method resolvePropertyValue (line 422) | resolvePropertyValue(n,r,o,i,s=""){if(typeof n=="string"&&r.components...
    method historyGo (line 422) | historyGo(n){throw new Error("")}
    method constructor (line 422) | constructor(){super(),this._location=window.location,this._history=win...
    method getBaseHrefFromDOM (line 422) | getBaseHrefFromDOM(){return _t().getBaseHref(this._doc)}
    method onPopState (line 422) | onPopState(n){let r=_t().getGlobalEventTarget(this._doc,"window");retu...
    method onHashChange (line 422) | onHashChange(n){let r=_t().getGlobalEventTarget(this._doc,"window");re...
    method href (line 422) | get href(){return this._location.href}
    method protocol (line 422) | get protocol(){return this._location.protocol}
    method hostname (line 422) | get hostname(){return this._location.hostname}
    method port (line 422) | get port(){return this._location.port}
    method pathname (line 422) | get pathname(){return this._location.pathname}
    method search (line 422) | get search(){return this._location.search}
    method hash (line 422) | get hash(){return this._location.hash}
    method pathname (line 422) | set pathname(n){this._location.pathname=n}
    method pushState (line 422) | pushState(n,r,o){this._history.pushState(n,r,o)}
    method replaceState (line 422) | replaceState(n,r,o){this._history.replaceState(n,r,o)}
    method forward (line 422) | forward(){this._history.forward()}
    method back (line 422) | back(){this._history.back()}
    method historyGo (line 422) | historyGo(n=0){this._history.go(n)}
    method getState (line 422) | getState(){return this._history.state}
    method historyGo (line 422) | historyGo(n){throw new Error("")}
    method constructor (line 422) | constructor(n,r){super(),this._platformLocation=n,this._baseHref=r??th...
    method ngOnDestroy (line 422) | ngOnDestroy(){for(;this._removeListenerFns.length;)this._removeListene...
    method onPopState (line 422) | onPopState(n){this._removeListenerFns.push(this._platformLocation.onPo...
    method getBaseHref (line 422) | getBaseHref(){return this._baseHref}
    method prepareExternalUrl (line 422) | prepareExternalUrl(n){return aa(this._baseHref,n)}
    method path (line 422) | path(n=!1){let r=this._platformLocation.pathname+ut(this._platformLoca...
    method pushState (line 422) | pushState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i));this._platfo...
    method replaceState (line 422) | replaceState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i));this._pla...
    method forward (line 422) | forward(){this._platformLocation.forward()}
    method back (line 422) | back(){this._platformLocation.back()}
    method getState (line 422) | getState(){return this._platformLocation.getState()}
    method historyGo (line 422) | historyGo(n=0){this._platformLocation.historyGo?.(n)}
    method constructor (line 422) | constructor(n){this._locationStrategy=n;let r=this._locationStrategy.g...
    method ngOnDestroy (line 422) | ngOnDestroy(){this._urlChangeSubscription?.unsubscribe(),this._urlChan...
    method path (line 422) | path(n=!1){return this.normalize(this._locationStrategy.path(n))}
    method getState (line 422) | getState(){return this._locationStrategy.getState()}
    method isCurrentPathEqualTo (line 422) | isCurrentPathEqualTo(n,r=""){return this.path()==this.normalize(n+ut(r))}
    method normalize (line 422) | normalize(n){return e.stripTrailingSlash(U2(this._basePath,D1(n)))}
    method prepareExternalUrl (line 422) | prepareExternalUrl(n){return n&&n[0]!=="/"&&(n="/"+n),this._locationSt...
    method go (line 422) | go(n,r="",o=null){this._locationStrategy.pushState(o,"",n,r),this._not...
    method replaceState (line 422) | replaceState(n,r="",o=null){this._locationStrategy.replaceState(o,"",n...
    method forward (line 422) | forward(){this._locationStrategy.forward()}
    method back (line 422) | back(){this._locationStrategy.back()}
    method historyGo (line 422) | historyGo(n=0){this._locationStrategy.historyGo?.(n)}
    method onUrlChange (line 422) | onUrlChange(n){return this._urlChangeListeners.push(n),this._urlChange...
    method _notifyUrlChangeListeners (line 422) | _notifyUrlChangeListeners(n="",r){this._urlChangeListeners.forEach(o=>...
    method subscribe (line 422) | subscribe(n,r,o){return this._subject.subscribe({next:n,error:r??void ...
    method constructor (line 422) | constructor(n,r){super(),this._platformLocation=n,r!=null&&(this._base...
    method ngOnDestroy (line 422) | ngOnDestroy(){for(;this._removeListenerFns.length;)this._removeListene...
    method onPopState (line 422) | onPopState(n){this._removeListenerFns.push(this._platformLocation.onPo...
    method getBaseHref (line 422) | getBaseHref(){return this._baseHref}
    method path (line 422) | path(n=!1){let r=this._platformLocation.hash??"#";return r.length>0?r....
    method prepareExternalUrl (line 422) | prepareExternalUrl(n){let r=aa(this._baseHref,n);return r.length>0?"#"...
    method pushState (line 422) | pushState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i))||this._platf...
    method replaceState (line 422) | replaceState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i))||this._pl...
    method forward (line 422) | forward(){this._platformLocation.forward()}
    method back (line 422) | back(){this._platformLocation.back()}
    method getState (line 422) | getState(){return this._platformLocation.getState()}
    method historyGo (line 422) | historyGo(n=0){this._platformLocation.historyGo?.(n)}
    method constructor (line 422) | constructor(n,r){this._ngEl=n,this._renderer=r}
    method klass (line 422) | set klass(n){this.initialClasses=n!=null?n.trim().split(op):_1}
    method ngClass (line 422) | set ngClass(n){this.rawClass=typeof n=="string"?n.trim().split(op):n}
    method ngDoCheck (line 422) | ngDoCheck(){for(let r of this.initialClasses)this._updateState(r,!0);l...
    method _updateState (line 422) | _updateState(n,r){let o=this.stateMap.get(n);o!==void 0?(o.enabled!==r...
    method _applyStateDiff (line 422) | _applyStateDiff(){for(let n of this.stateMap){let r=n[0],o=n[1];o.chan...
    method _toggleClass (line 422) | _toggleClass(n,r){n=n.trim(),n.length>0&&n.split(op).forEach(o=>{r?thi...
    method componentInstance (line 422) | get componentInstance(){return this._componentRef?.instance??null}
    method constructor (line 422) | constructor(n){this._viewContainerRef=n}
    method _needToReCreateNgModuleInstance (line 422) | _needToReCreateNgModuleInstance(n){return n.ngComponentOutletNgModule!...
    method _needToReCreateComponentInstance (line 422) | _needToReCreateComponentInstance(n){return n.ngComponentOutlet!==void ...
    method ngOnChanges (line 422) | ngOnChanges(n){if(this._needToReCreateComponentInstance(n)&&(this._vie...
    method ngDoCheck (line 422) | ngDoCheck(){if(this._componentRef){if(this.ngComponentOutletInputs)for...
    method ngOnDestroy (line 422) | ngOnDestroy(){this._moduleRef?.destroy()}
    method _applyInputStateDiff (line 422) | _applyInputStateDiff(n){for(let[r,o]of this._inputsUsed)o?(n.setInput(...
    method ngForOf (line 422) | set ngForOf(n){this._ngForOf=n,this._ngForOfDirty=!0}
    method ngForTrackBy (line 422) | set ngForTrackBy(n){this._trackByFn=n}
    method ngForTrackBy (line 422) | get ngForTrackBy(){return this._trackByFn}
    method constructor (line 422) | constructor(n,r,o){this._viewContainer=n,this._template=r,this._differ...
    method ngForTemplate (line 422) | set ngForTemplate(n){n&&(this._template=n)}
    method ngDoCheck (line 422) | ngDoCheck(){if(this._ngForOfDirty){this._ngForOfDirty=!1;let n=this._n...
    method _applyChanges (line 422) | _applyChanges(n){let r=this._viewContainer;n.forEachOperation((o,i,s)=...
    method ngTemplateContextGuard (line 422) | static ngTemplateContextGuard(n,r){return!0}
    method constructor (line 422) | constructor(n,r){this._viewContainer=n,this._thenTemplateRef=r}
    method ngIf (line 422) | set ngIf(n){this._context.$implicit=this._context.ngIf=n,this._updateV...
    method ngIfThen (line 422) | set ngIfThen(n){x1(n,!1),this._thenTemplateRef=n,this._thenViewRef=nul...
    method ngIfElse (line 422) | set ngIfElse(n){x1(n,!1),this._elseTemplateRef=n,this._elseViewRef=nul...
    method _updateView (line 422) | _updateView(){this._context.$implicit?this._thenViewRef||(this._viewCo...
    method ngTemplateContextGuard (line 422) | static ngTemplateContextGuard(n,r){return!0}
    method constructor (line 422) | constructor(n,r,o){this._ngEl=n,this._differs=r,this._renderer=o}
    method ngStyle (line 422) | set ngStyle(n){this._ngStyle=n,!this._differ&&n&&(this._differ=this._d...
    method ngDoCheck (line 422) | ngDoCheck(){if(this._differ){let n=this._differ.diff(this._ngStyle);n&...
    method _setStyle (line 422) | _setStyle(n,r){let[o,i]=n.split("."),s=o.indexOf("-")===-1?void 0:rt.D...
    method _applyChanges (line 422) | _applyChanges(n){n.forEachRemovedItem(r=>this._setStyle(r.key,null)),n...
    method constructor (line 422) | constructor(n){this._viewContainerRef=n}
    method ngOnChanges (line 422) | ngOnChanges(n){if(this._shouldRecreateView(n)){let r=this._viewContain...
    method _getInjector (line 422) | _getInjector(){return this.ngTemplateOutletInjector==="outlet"?this.in...
    method _shouldRecreateView (line 422) | _shouldRecreateView(n){return!!n.ngTemplateOutlet||!!n.ngTemplateOutle...
    method _createContextForwardProxy (line 422) | _createContextForwardProxy(){return new Proxy({},{set:(n,r,o)=>this.ng...
    method constructor (line 422) | constructor(n){this._ref=n}
    method ngOnDestroy (line 422) | ngOnDestroy(){this._subscription&&this._dispose(),this._ref=null}
    method transform (line 422) | transform(n){if(!this._obj){if(n)try{this.markForCheckOnValueUpdate=!1...
    method _subscribe (line 422) | _subscribe(n){this._obj=n,this._strategy=this._selectStrategy(n),this....
    method _selectStrategy (line 422) | _selectStrategy(n){if(gi(n))return X2;if(Lu(n))return eT;throw J2(e,n)}
    method _dispose (line 422) | _dispose(){this._strategy.dispose(this._subscription),this._latestValu...
    method _updateLatestValue (line 422) | _updateLatestValue(n,r){n===this._obj&&(this._latestValue=r,this.markF...
    method constructor (line 422) | constructor(n){this.differs=n}
    method transform (line 422) | transform(n,r=I1){if(!n||!(n instanceof Map)&&typeof n!="object")retur...
    method constructor (line 422) | constructor(n){super(n)}
    method supports (line 422) | supports(n){return!0}
    method addEventListener (line 422) | addEventListener(n,r,o,i){return n.addEventListener(r,o,i),()=>this.re...
    method removeEventListener (line 422) | removeEventListener(n,r,o,i){return n.removeEventListener(r,o,i)}
    method constructor (line 422) | constructor(n,r){this._zone=r,n.forEach(s=>{s.manager=this});let o=n.f...
    method addEventListener (line 422) | addEventListener(n,r,o,i){return this._findPluginFor(r).addEventListen...
    method getZone (line 422) | getZone(){return this._zone}
    method _findPluginFor (line 422) | _findPluginFor(n){let r=this._eventNameToPlugin.get(n);if(r)return r;i...
    method constructor (line 422) | constructor(n,r,o,i={}){this.doc=n,this.appId=r,this.nonce=o,iT(n,r,th...
    method addStyles (line 422) | addStyles(n,r){for(let o of n)this.addUsage(o,this.inline,A1);r?.forEa...
    method removeStyles (line 422) | removeStyles(n,r){for(let o of n)this.removeUsage(o,this.inline);r?.fo...
    method addUsage (line 422) | addUsage(n,r,o){let i=r.get(n);i?i.usage++:r.set(n,{usage:1,elements:[...
    method removeUsage (line 422) | removeUsage(n,r){let o=r.get(n);o&&(o.usage--,o.usage<=0&&(M1(o.elemen...
    method ngOnDestroy (line 422) | ngOnDestroy(){for(let[,{elements:n}]of[...this.inline,...this.external...
    method addHost (line 422) | addHost(n){this.hosts.add(n);for(let[r,{elements:o}]of this.inline)o.p...
    method removeHost (line 422) | removeHost(n){this.hosts.delete(n)}
    method addElement (line 422) | addElement(n,r){return this.nonce&&r.setAttribute("nonce",this.nonce),...
    method constructor (line 422) | constructor(n,r,o,i,s,u,a=null,c=null){this.eventManager=n,this.shared...
    method createRenderer (line 422) | createRenderer(n,r){if(!n||!r)return this.defaultRenderer;let o=this.g...
    method getOrCreateRenderer (line 422) | getOrCreateRenderer(n,r){let o=this.rendererByCompId,i=o.get(r.id);if(...
    method ngOnDestroy (line 422) | ngOnDestroy(){this.rendererByCompId.clear()}
    method componentReplaced (line 422) | componentReplaced(n){this.rendererByCompId.delete(n)}
    method build (line 422) | build(){return new XMLHttpRequest}
    method constructor (line 422) | constructor(n){super(n)}
    method supports (line 422) | supports(n){return e.parseEventName(n)!=null}
    method addEventListener (line 422) | addEventListener(n,r,o,i){let s=e.parseEventName(r),u=e.eventCallback(...
    method parseEventName (line 422) | static parseEventName(n){let r=n.toLowerCase().split("."),o=r.shift();...
    method matchEventFullKeyCode (line 422) | static matchEventFullKeyCode(n,r){let o=gT[n.key]||n.key,i="";return r...
    method eventCallback (line 422) | static eventCallback(n,r,o){return i=>{e.matchEventFullKeyCode(i,n)&&o...
    method _normalizeKey (line 422) | static _normalizeKey(n){return n==="esc"?"escape":n}
    method constructor (line 422) | constructor(){}
    method constructor (line 423) | constructor(n){this.xhrFactory=n}
    method maybePropagateTrace (line 423) | maybePropagateTrace(n){return this.tracingService?.propagate?this.trac...
    method handle (line 423) | handle(n){if(n.method==="JSONP")throw new C(-2800,!1);let r=this.xhrFa...
    method constructor (line 423) | constructor(n,r){this.backend=n,this.injector=r}
    method handle (line 423) | handle(n){if(this.chain===null){let r=Array.from(new Set([...this.inje...
    method constructor (line 423) | constructor(n){this.handler=n}
    method request (line 423) | request(n,r,o={}){let i;if(n instanceof uo)i=n;else{let a;o.headers in...
    method delete (line 423) | delete(n,r={}){return this.request("DELETE",n,r)}
    method get (line 423) | get(n,r={}){return this.request("GET",n,r)}
    method head (line 423) | head(n,r={}){return this.request("HEAD",n,r)}
    method jsonp (line 423) | jsonp(n,r){return this.request("JSONP",n,{params:new zt().append(r,"JS...
    method options (line 423) | options(n,r={}){return this.request("OPTIONS",n,r)}
    method patch (line 423) | patch(n,r,o={}){return this.request("PATCH",n,yp(o,r))}
    method post (line 423) | post(n,r,o={}){return this.request("POST",n,yp(o,r))}
    method put (line 423) | put(n,r,o={}){return this.request("PUT",n,yp(o,r))}
    method getToken (line 423) | getToken(){let n=this.doc.cookie||"";return n!==this.lastCookieString&...
    method constructor (line 423) | constructor(n){this._doc=n}
    method getTitle (line 423) | getTitle(){return this._doc.title}
    method setTitle (line 423) | setTitle(n){this._doc.title=n||""}
    method constructor (line 423) | constructor(n){super(),this._doc=n}
    method sanitize (line 423) | sanitize(n,r){if(r==null)return null;switch(n){case Pe.NONE:return r;c...
    method bypassSecurityTrustHtml (line 423) | bypassSecurityTrustHtml(n){return md(n)}
    method bypassSecurityTrustStyle (line 423) | bypassSecurityTrustStyle(n){return yd(n)}
    method bypassSecurityTrustScript (line 423) | bypassSecurityTrustScript(n){return bd(n)}
    method bypassSecurityTrustUrl (line 423) | bypassSecurityTrustUrl(n){return vd(n)}
    method bypassSecurityTrustResourceUrl (line 423) | bypassSecurityTrustResourceUrl(n){return Dd(n)}
    method setData (line 438) | setData(n,r,o,i){return super.setData(n,r,o,i??void 0)}
    method dispatch (line 438) | dispatch(n){let r=new ce;return this.events.next({message:n,completion...
    method sendAction (line 438) | sendAction(n){let r=this.component(),o=this.surfaceId()??void 0,i={};i...
    method resolvePrimitive (line 438) | resolvePrimitive(n){let r=this.component(),o=this.surfaceId();return!n...
    method getUniqueId (line 438) | getUniqueId(n){return`${n}-${ZM++}`}
    method constructor (line 438) | constructor(){Yo(()=>{let o=this.surfaceId(),i=this.component();De(()=...
    method ngOnDestroy (line 438) | ngOnDestroy(){this.isDestroyed=!0,this.clear()}
    method render (line 438) | render(n,r){return lt(this,null,function*(){let o=this.catalog[r.type]...
    method clear (line 438) | clear(){this.currentRef?.destroy(),this.currentRef=null}
    method render (line 438) | render(n,r){r&&this.applyTagClassMap(r);let o=this.markdownIt.render(n...
    method applyTagClassMap (line 438) | applyTagClassMap(n){Object.entries(n).forEach(([r,o])=>{let i;switch(r...
    method unapplyTagClassMap (line 438) | unapplyTagClassMap(){for(let[n,r]of this.originalClassMap)this.markdow...
    method areHintedStyles (line 438) | areHintedStyles(n){return typeof n!="object"||!n||Array.isArray(n)?!1:...
  function Uh (line 3) | function Uh(e){var t;return(t=e??We.Promise)!==null&&t!==void 0?t:Promise}
  function fD (line 3) | function fD(e){return e&&k(e.next)&&k(e.error)&&k(e.complete)}
  function pD (line 3) | function pD(e){return e&&e instanceof Mn||fD(e)&&Hi(e)}
  function tc (line 3) | function tc(e){return k(e?.lift)}
  function j (line 3) | function j(e){return t=>{if(tc(t))return t.lift(function(n){try{return e...
  function R (line 3) | function R(e,t,n,r,o){return new nc(e,t,n,r,o)}
  method constructor (line 3) | constructor(t,n,r,o,i,s){super(t),this.onFinalize=i,this.shouldUnsubscri...
  method unsubscribe (line 3) | unsubscribe(){var t;if(!this.shouldUnsubscribe||this.shouldUnsubscribe()...
  function zh (line 3) | function zh(){return j((e,t)=>{let n=null;e._refCount++;let r=R(t,void 0...
  method constructor (line 3) | constructor(t,n){super(),this.source=t,this.subjectFactory=n,this._subje...
  method _subscribe (line 3) | _subscribe(t){return this.getSubject().subscribe(t)}
  method getSubject (line 3) | getSubject(){let t=this._subject;return(!t||t.isStopped)&&(this._subject...
  method _teardown (line 3) | _teardown(){this._refCount=0;let{_connection:t}=this;this._subject=this....
  method connect (line 3) | connect(){let t=this._connection;if(!t){t=this._connection=new X;let n=t...
  method refCount (line 3) | refCount(){return zh()(this)}
  method schedule (line 3) | schedule(e){let t=requestAnimationFrame,n=cancelAnimationFrame,{delegate...
  method requestAnimationFrame (line 3) | requestAnimationFrame(...e){let{delegate:t}=Er;return(t?.requestAnimatio...
  method cancelAnimationFrame (line 3) | cancelAnimationFrame(...e){let{delegate:t}=Er;return(t?.cancelAnimationF...
  class e (line 3) | class e extends B{constructor(){super(),this.closed=!1,this.currentObser...
    method constructor (line 3) | constructor(n){n&&(this._subscribe=n)}
    method lift (line 3) | lift(n){let r=new e;return r.source=this,r.operator=n,r}
    method subscribe (line 3) | subscribe(n,r,o){let i=pD(n)?n:new Ze(n,r,o);return vr(()=>{let{operat...
    method _trySubscribe (line 3) | _trySubscribe(n){try{return this._subscribe(n)}catch(r){n.error(r)}}
    method forEach (line 3) | forEach(n,r){return r=Uh(r),new r((o,i)=>{let s=new Ze({next:u=>{try{n...
    method _subscribe (line 3) | _subscribe(n){var r;return(r=this.source)===null||r===void 0?void 0:r....
    method [Dr] (line 3) | [Dr](){return this}
    method pipe (line 3) | pipe(...n){return ec(n)(this)}
    method toPromise (line 3) | toPromise(n){return n=Uh(n),new n((r,o)=>{let i;this.subscribe(s=>i=s,...
    method constructor (line 3) | constructor(){super(),this.closed=!1,this.currentObservers=null,this.o...
    method lift (line 3) | lift(n){let r=new zi(this,this);return r.operator=n,r}
    method _throwIfClosed (line 3) | _throwIfClosed(){if(this.closed)throw new qh}
    method next (line 3) | next(n){vr(()=>{if(this._throwIfClosed(),!this.isStopped){this.current...
    method error (line 3) | error(n){vr(()=>{if(this._throwIfClosed(),!this.isStopped){this.hasErr...
    method complete (line 3) | complete(){vr(()=>{if(this._throwIfClosed(),!this.isStopped){this.isSt...
    method unsubscribe (line 3) | unsubscribe(){this.isStopped=this.closed=!0,this.observers=this.curren...
    method observed (line 3) | get observed(){var n;return((n=this.observers)===null||n===void 0?void...
    method _trySubscribe (line 3) | _trySubscribe(n){return this._throwIfClosed(),super._trySubscribe(n)}
    method _subscribe (line 3) | _subscribe(n){return this._throwIfClosed(),this._checkFinalizedStatuse...
    method _innerSubscribe (line 3) | _innerSubscribe(n){let{hasError:r,isStopped:o,observers:i}=this;return...
    method _checkFinalizedStatuses (line 3) | _checkFinalizedStatuses(n){let{hasError:r,thrownError:o,isStopped:i}=t...
    method asObservable (line 3) | asObservable(){let n=new B;return n.source=this,n}
    method hasPendingTasks (line 4) | get hasPendingTasks(){return this.destroyed?!1:this.pendingTask.value}
    method hasPendingTasksObservable (line 4) | get hasPendingTasksObservable(){return this.destroyed?new B(n=>{n.next...
    method add (line 4) | add(){!this.hasPendingTasks&&!this.destroyed&&this.pendingTask.next(!0...
    method has (line 4) | has(n){return this.pendingTasks.has(n)}
    method remove (line 4) | remove(n){this.pendingTasks.delete(n),this.debugTaskTracker?.remove(n)...
    method ngOnDestroy (line 4) | ngOnDestroy(){this.pendingTasks.clear(),this.hasPendingTasks&&this.pen...
    method constructor (line 4) | constructor(n,r){this.view=n,this.node=r}
    method add (line 4) | add(){let n=this.internalPendingTasks.add();return()=>{this.internalPe...
    method run (line 4) | run(n){let r=this.add();n().catch(this.errorHandler).finally(r)}
    method constructor (line 4) | constructor(n){this.nativeElement=n}
    method execute (line 4) | execute(){this.impl?.execute()}
    method constructor (line 4) | constructor(){b(ot,{optional:!0})}
    method execute (line 4) | execute(){let n=this.sequences.size>0;n&&Y(q.AfterRenderHooksStart),th...
    method register (line 4) | register(n){let{view:r}=n;r!==void 0?((r[Hn]??=[]).push(n),zn(r),r[L]|...
    method addSequence (line 4) | addSequence(n){this.sequences.add(n),this.scheduler.notify(7)}
    method unregister (line 4) | unregister(n){this.executing&&this.sequences.has(n)?(n.erroredOrDestro...
    method maybeTrace (line 4) | maybeTrace(n,r){return r?r.run(wu.AFTER_NEXT_RENDER,n):n()}
    method constructor (line 4) | constructor(n,r,o){this._declarationLView=n,this._declarationTContaine...
    method ssrId (line 4) | get ssrId(){return this._declarationTContainer.tView?.ssrId||null}
    method createEmbeddedView (line 4) | createEmbeddedView(n,r){return this.createEmbeddedViewImpl(n,r)}
    method createEmbeddedViewImpl (line 4) | createEmbeddedViewImpl(n,r,o){let i=li(this._declarationLView,this._de...
    method constructor (line 4) | constructor(n){this._injector=n}
    method getOrCreateStandaloneInjector (line 4) | getOrCreateStandaloneInjector(n){if(!n.standalone)return null;if(!this...
    method ngOnDestroy (line 4) | ngOnDestroy(){try{for(let n of this.cachedInjectors.values())n!==null&...
    method log (line 4) | log(n){console.log(n)}
    method warn (line 4) | warn(n){console.warn(n)}
    method constructor (line 4) | constructor(n,r,o){this._ngZone=n,this.registry=r,As()&&(this._destroy...
    method _watchAngularEvents (line 4) | _watchAngularEvents(){let n=this._ngZone.onUnstable.subscribe({next:()...
    method isStable (line 4) | isStable(){return this._isZoneStable&&!this._ngZone.hasPendingMacrotasks}
    method _runCallbacksIfReady (line 4) | _runCallbacksIfReady(){if(this.isStable())queueMicrotask(()=>{for(;thi...
    method getPendingTasks (line 4) | getPendingTasks(){return this._taskTrackingZone?this._taskTrackingZone...
    method addCallback (line 4) | addCallback(n,r,o){let i=-1;r&&r>0&&(i=setTimeout(()=>{this._callbacks...
    method whenStable (line 4) | whenStable(n,r,o){if(o&&!this._taskTrackingZone)throw new Error('Task ...
    method registerApplication (line 4) | registerApplication(n){this.registry.registerApplication(n,this)}
    method unregisterApplication (line 4) | unregisterApplication(n){this.registry.unregisterApplication(n)}
    method findProviders (line 4) | findProviders(n,r,o){return[]}
    method registerApplication (line 4) | registerApplication(n,r){this._applications.set(n,r)}
    method unregisterApplication (line 4) | unregisterApplication(n){this._applications.delete(n)}
    method unregisterAllApplications (line 4) | unregisterAllApplications(){this._applications.clear()}
    method getTestability (line 4) | getTestability(n){return this._applications.get(n)||null}
    method getAllTestabilities (line 4) | getAllTestabilities(){return Array.from(this._applications.values())}
    method getAllRootElements (line 4) | getAllRootElements(){return Array.from(this._applications.keys())}
    method findTestabilityInTree (line 4) | findTestabilityInTree(n,r=!0){return Yd?.findTestabilityInTree(this,n,...
    method constructor (line 4) | constructor(){}
    method runInitializers (line 4) | runInitializers(){if(this.initialized)return;let n=[];for(let o of thi...
    method allViews (line 4) | get allViews(){return[...(this.includeAllTestViews?this.allTestViews:t...
    method destroyed (line 4) | get destroyed(){return this._destroyed}
    method isStable (line 4) | get isStable(){return this.internalPendingTask.hasPendingTasksObservab...
    method constructor (line 4) | constructor(){b(ot,{optional:!0})}
    method whenStable (line 4) | whenStable(){let n;return new Promise(r=>{n=this.isStable.subscribe({n...
    method injector (line 4) | get injector(){return this._injector}
    method bootstrap (line 4) | bootstrap(n,r){return this.bootstrapImpl(n,r)}
    method bootstrapImpl (line 4) | bootstrapImpl(n,r,o=fe.NULL){return this._injector.get(be).run(()=>{Y(...
    method tick (line 4) | tick(){this.zonelessEnabled||(this.dirtyFlags|=1),this._tick()}
    method _tick (line 4) | _tick(){Y(q.ChangeDetectionStart),this.tracingSnapshot!==null?this.tra...
    method synchronize (line 4) | synchronize(){this._rendererFactory===null&&!this._injector.destroyed&...
    method synchronizeOnce (line 4) | synchronizeOnce(){this.dirtyFlags&16&&(this.dirtyFlags&=-17,this.rootE...
    method syncDirtyFlagsWithViews (line 4) | syncDirtyFlagsWithViews(){if(this.allViews.some(({_lView:n})=>Uo(n))){...
    method attachView (line 4) | attachView(n){let r=n;this._views.push(r),r.attachToAppRef(this)}
    method detachView (line 4) | detachView(n){let r=n;Ko(this._views,r),r.detachFromAppRef()}
    method _loadComponent (line 4) | _loadComponent(n){this.attachView(n.hostView);try{this.tick()}catch(o)...
    method ngOnDestroy (line 4) | ngOnDestroy(){if(!this._destroyed)try{this._destroyListeners.forEach(n...
    method onDestroy (line 4) | onDestroy(n){return this._destroyListeners.push(n),()=>Ko(this._destro...
    method destroy (line 4) | destroy(){if(this._destroyed)throw new C(406,!1);let n=this._injector;...
    method viewCount (line 4) | get viewCount(){return this._views.length}
    method compileModuleSync (line 4) | compileModuleSync(n){return new du(n)}
    method compileModuleAsync (line 4) | compileModuleAsync(n){return Promise.resolve(this.compileModuleSync(n))}
    method compileModuleAndAllComponentsSync (line 4) | compileModuleAndAllComponentsSync(n){let r=this.compileModuleSync(n),o...
    method compileModuleAndAllComponentsAsync (line 4) | compileModuleAndAllComponentsAsync(n){return Promise.resolve(this.comp...
    method clearCache (line 4) | clearCache(){}
    method clearCacheFor (line 4) | clearCacheFor(n){}
    method getModuleId (line 4) | getModuleId(n){}
    method constructor (line 4) | constructor(){this.subscriptions.add(this.appRef.afterTick.subscribe((...
    method switchToMicrotaskScheduler (line 4) | switchToMicrotaskScheduler(){this.ngZone.runOutsideAngular(()=>{let n=...
    method notify (line 4) | notify(n){if(!this.zonelessEnabled&&n===5)return;switch(n){case 0:{thi...
    method shouldScheduleTick (line 4) | shouldScheduleTick(){return!(this.appRef.destroyed||this.pendingRender...
    method tick (line 4) | tick(){if(this.runningTick||this.appRef.destroyed)return;if(this.appRe...
    method ngOnDestroy (line 4) | ngOnDestroy(){this.subscriptions.unsubscribe(),this.cleanup()}
    method cleanup (line 4) | cleanup(){if(this.runningTick=!1,this.cancelScheduledCallback?.(),this...
    method constructor (line 4) | constructor(n){this.factories=n}
    method create (line 4) | static create(n,r){if(r!=null){let o=r.factories.slice();n=n.concat(o)...
    method extend (line 4) | static extend(n){return{provide:e,useFactory:()=>{let r=b(e,{optional:...
    method find (line 4) | find(n){let r=this.factories.find(o=>o.supports(n));if(r!=null)return ...
    method constructor (line 4) | constructor(n){this.factories=n}
    method create (line 4) | static create(n,r){if(r){let o=r.factories.slice();n=n.concat(o)}retur...
    method extend (line 4) | static extend(n){return{provide:e,useFactory:()=>{let r=b(e,{optional:...
    method find (line 4) | find(n){let r=this.factories.find(o=>o.supports(n));if(r)return r;thro...
    method constructor (line 4) | constructor(n){}
    method constructor (line 422) | constructor(n={mapCtor:Map,arrayCtor:Array,setCtor:Set,objCtor:Object}...
    method getSurfaces (line 422) | getSurfaces(){return this.surfaces}
    method clearSurfaces (line 422) | clearSurfaces(){this.surfaces.clear()}
    method processMessages (line 422) | processMessages(n){for(let r of n)r.beginRendering&&this.handleBeginRe...
    method getData (line 422) | getData(n,r,o=e.DEFAULT_SURFACE_ID){let i=this.getOrCreateSurface(o);i...
    method setData (line 422) | setData(n,r,o,i=e.DEFAULT_SURFACE_ID){if(!n){console.warn("No componen...
    method resolvePath (line 422) | resolvePath(n,r){return n.startsWith("/")?n:r&&r!=="/"?r.endsWith("/")...
    method parseIfJsonString (line 422) | parseIfJsonString(n){if(typeof n!="string")return n;let r=n.trim();if(...
    method convertKeyValueArrayToMap (line 422) | convertKeyValueArrayToMap(n){let r=new this.mapCtor;for(let o of n){if...
    method setDataByPath (line 422) | setDataByPath(n,r,o){if(Array.isArray(o)&&(o.length===0||$(o[0])&&"key...
    method normalizePath (line 422) | normalizePath(n){return"/"+n.replace(/\[(\d+)\]/g,".$1").split(".").fi...
    method getDataByPath (line 422) | getDataByPath(n,r){let o=this.normalizePath(r).split("/").filter(s=>s)...
    method getOrCreateSurface (line 422) | getOrCreateSurface(n){let r=this.surfaces.get(n);return r||(r=new this...
    method handleBeginRendering (line 422) | handleBeginRendering(n,r){let o=this.getOrCreateSurface(r);o.rootCompo...
    method handleSurfaceUpdate (line 422) | handleSurfaceUpdate(n,r){let o=this.getOrCreateSurface(r);for(let i of...
    method handleDataModelUpdate (line 422) | handleDataModelUpdate(n,r){let o=this.getOrCreateSurface(r),i=n.path??...
    method handleDeleteSurface (line 422) | handleDeleteSurface(n){this.surfaces.delete(n.surfaceId)}
    method rebuildComponentTree (line 422) | rebuildComponentTree(n){if(!n.rootComponentId){n.componentTree=null;re...
    method findValueKey (line 422) | findValueKey(n){return Object.keys(n).find(r=>r.startsWith("value"))}
    method buildNodeRecursive (line 422) | buildNodeRecursive(n,r,o,i,s=""){let u=`${n}${s}`,{components:a}=r;if(...
    method resolvePropertyValue (line 422) | resolvePropertyValue(n,r,o,i,s=""){if(typeof n=="string"&&r.components...
    method historyGo (line 422) | historyGo(n){throw new Error("")}
    method constructor (line 422) | constructor(){super(),this._location=window.location,this._history=win...
    method getBaseHrefFromDOM (line 422) | getBaseHrefFromDOM(){return _t().getBaseHref(this._doc)}
    method onPopState (line 422) | onPopState(n){let r=_t().getGlobalEventTarget(this._doc,"window");retu...
    method onHashChange (line 422) | onHashChange(n){let r=_t().getGlobalEventTarget(this._doc,"window");re...
    method href (line 422) | get href(){return this._location.href}
    method protocol (line 422) | get protocol(){return this._location.protocol}
    method hostname (line 422) | get hostname(){return this._location.hostname}
    method port (line 422) | get port(){return this._location.port}
    method pathname (line 422) | get pathname(){return this._location.pathname}
    method search (line 422) | get search(){return this._location.search}
    method hash (line 422) | get hash(){return this._location.hash}
    method pathname (line 422) | set pathname(n){this._location.pathname=n}
    method pushState (line 422) | pushState(n,r,o){this._history.pushState(n,r,o)}
    method replaceState (line 422) | replaceState(n,r,o){this._history.replaceState(n,r,o)}
    method forward (line 422) | forward(){this._history.forward()}
    method back (line 422) | back(){this._history.back()}
    method historyGo (line 422) | historyGo(n=0){this._history.go(n)}
    method getState (line 422) | getState(){return this._history.state}
    method historyGo (line 422) | historyGo(n){throw new Error("")}
    method constructor (line 422) | constructor(n,r){super(),this._platformLocation=n,this._baseHref=r??th...
    method ngOnDestroy (line 422) | ngOnDestroy(){for(;this._removeListenerFns.length;)this._removeListene...
    method onPopState (line 422) | onPopState(n){this._removeListenerFns.push(this._platformLocation.onPo...
    method getBaseHref (line 422) | getBaseHref(){return this._baseHref}
    method prepareExternalUrl (line 422) | prepareExternalUrl(n){return aa(this._baseHref,n)}
    method path (line 422) | path(n=!1){let r=this._platformLocation.pathname+ut(this._platformLoca...
    method pushState (line 422) | pushState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i));this._platfo...
    method replaceState (line 422) | replaceState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i));this._pla...
    method forward (line 422) | forward(){this._platformLocation.forward()}
    method back (line 422) | back(){this._platformLocation.back()}
    method getState (line 422) | getState(){return this._platformLocation.getState()}
    method historyGo (line 422) | historyGo(n=0){this._platformLocation.historyGo?.(n)}
    method constructor (line 422) | constructor(n){this._locationStrategy=n;let r=this._locationStrategy.g...
    method ngOnDestroy (line 422) | ngOnDestroy(){this._urlChangeSubscription?.unsubscribe(),this._urlChan...
    method path (line 422) | path(n=!1){return this.normalize(this._locationStrategy.path(n))}
    method getState (line 422) | getState(){return this._locationStrategy.getState()}
    method isCurrentPathEqualTo (line 422) | isCurrentPathEqualTo(n,r=""){return this.path()==this.normalize(n+ut(r))}
    method normalize (line 422) | normalize(n){return e.stripTrailingSlash(U2(this._basePath,D1(n)))}
    method prepareExternalUrl (line 422) | prepareExternalUrl(n){return n&&n[0]!=="/"&&(n="/"+n),this._locationSt...
    method go (line 422) | go(n,r="",o=null){this._locationStrategy.pushState(o,"",n,r),this._not...
    method replaceState (line 422) | replaceState(n,r="",o=null){this._locationStrategy.replaceState(o,"",n...
    method forward (line 422) | forward(){this._locationStrategy.forward()}
    method back (line 422) | back(){this._locationStrategy.back()}
    method historyGo (line 422) | historyGo(n=0){this._locationStrategy.historyGo?.(n)}
    method onUrlChange (line 422) | onUrlChange(n){return this._urlChangeListeners.push(n),this._urlChange...
    method _notifyUrlChangeListeners (line 422) | _notifyUrlChangeListeners(n="",r){this._urlChangeListeners.forEach(o=>...
    method subscribe (line 422) | subscribe(n,r,o){return this._subject.subscribe({next:n,error:r??void ...
    method constructor (line 422) | constructor(n,r){super(),this._platformLocation=n,r!=null&&(this._base...
    method ngOnDestroy (line 422) | ngOnDestroy(){for(;this._removeListenerFns.length;)this._removeListene...
    method onPopState (line 422) | onPopState(n){this._removeListenerFns.push(this._platformLocation.onPo...
    method getBaseHref (line 422) | getBaseHref(){return this._baseHref}
    method path (line 422) | path(n=!1){let r=this._platformLocation.hash??"#";return r.length>0?r....
    method prepareExternalUrl (line 422) | prepareExternalUrl(n){let r=aa(this._baseHref,n);return r.length>0?"#"...
    method pushState (line 422) | pushState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i))||this._platf...
    method replaceState (line 422) | replaceState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i))||this._pl...
    method forward (line 422) | forward(){this._platformLocation.forward()}
    method back (line 422) | back(){this._platformLocation.back()}
    method getState (line 422) | getState(){return this._platformLocation.getState()}
    method historyGo (line 422) | historyGo(n=0){this._platformLocation.historyGo?.(n)}
    method constructor (line 422) | constructor(n,r){this._ngEl=n,this._renderer=r}
    method klass (line 422) | set klass(n){this.initialClasses=n!=null?n.trim().split(op):_1}
    method ngClass (line 422) | set ngClass(n){this.rawClass=typeof n=="string"?n.trim().split(op):n}
    method ngDoCheck (line 422) | ngDoCheck(){for(let r of this.initialClasses)this._updateState(r,!0);l...
    method _updateState (line 422) | _updateState(n,r){let o=this.stateMap.get(n);o!==void 0?(o.enabled!==r...
    method _applyStateDiff (line 422) | _applyStateDiff(){for(let n of this.stateMap){let r=n[0],o=n[1];o.chan...
    method _toggleClass (line 422) | _toggleClass(n,r){n=n.trim(),n.length>0&&n.split(op).forEach(o=>{r?thi...
    method componentInstance (line 422) | get componentInstance(){return this._componentRef?.instance??null}
    method constructor (line 422) | constructor(n){this._viewContainerRef=n}
    method _needToReCreateNgModuleInstance (line 422) | _needToReCreateNgModuleInstance(n){return n.ngComponentOutletNgModule!...
    method _needToReCreateComponentInstance (line 422) | _needToReCreateComponentInstance(n){return n.ngComponentOutlet!==void ...
    method ngOnChanges (line 422) | ngOnChanges(n){if(this._needToReCreateComponentInstance(n)&&(this._vie...
    method ngDoCheck (line 422) | ngDoCheck(){if(this._componentRef){if(this.ngComponentOutletInputs)for...
    method ngOnDestroy (line 422) | ngOnDestroy(){this._moduleRef?.destroy()}
    method _applyInputStateDiff (line 422) | _applyInputStateDiff(n){for(let[r,o]of this._inputsUsed)o?(n.setInput(...
    method ngForOf (line 422) | set ngForOf(n){this._ngForOf=n,this._ngForOfDirty=!0}
    method ngForTrackBy (line 422) | set ngForTrackBy(n){this._trackByFn=n}
    method ngForTrackBy (line 422) | get ngForTrackBy(){return this._trackByFn}
    method constructor (line 422) | constructor(n,r,o){this._viewContainer=n,this._template=r,this._differ...
    method ngForTemplate (line 422) | set ngForTemplate(n){n&&(this._template=n)}
    method ngDoCheck (line 422) | ngDoCheck(){if(this._ngForOfDirty){this._ngForOfDirty=!1;let n=this._n...
    method _applyChanges (line 422) | _applyChanges(n){let r=this._viewContainer;n.forEachOperation((o,i,s)=...
    method ngTemplateContextGuard (line 422) | static ngTemplateContextGuard(n,r){return!0}
    method constructor (line 422) | constructor(n,r){this._viewContainer=n,this._thenTemplateRef=r}
    method ngIf (line 422) | set ngIf(n){this._context.$implicit=this._context.ngIf=n,this._updateV...
    method ngIfThen (line 422) | set ngIfThen(n){x1(n,!1),this._thenTemplateRef=n,this._thenViewRef=nul...
    method ngIfElse (line 422) | set ngIfElse(n){x1(n,!1),this._elseTemplateRef=n,this._elseViewRef=nul...
    method _updateView (line 422) | _updateView(){this._context.$implicit?this._thenViewRef||(this._viewCo...
    method ngTemplateContextGuard (line 422) | static ngTemplateContextGuard(n,r){return!0}
    method constructor (line 422) | constructor(n,r,o){this._ngEl=n,this._differs=r,this._renderer=o}
    method ngStyle (line 422) | set ngStyle(n){this._ngStyle=n,!this._differ&&n&&(this._differ=this._d...
    method ngDoCheck (line 422) | ngDoCheck(){if(this._differ){let n=this._differ.diff(this._ngStyle);n&...
    method _setStyle (line 422) | _setStyle(n,r){let[o,i]=n.split("."),s=o.indexOf("-")===-1?void 0:rt.D...
    method _applyChanges (line 422) | _applyChanges(n){n.forEachRemovedItem(r=>this._setStyle(r.key,null)),n...
    method constructor (line 422) | constructor(n){this._viewContainerRef=n}
    method ngOnChanges (line 422) | ngOnChanges(n){if(this._shouldRecreateView(n)){let r=this._viewContain...
    method _getInjector (line 422) | _getInjector(){return this.ngTemplateOutletInjector==="outlet"?this.in...
    method _shouldRecreateView (line 422) | _shouldRecreateView(n){return!!n.ngTemplateOutlet||!!n.ngTemplateOutle...
    method _createContextForwardProxy (line 422) | _createContextForwardProxy(){return new Proxy({},{set:(n,r,o)=>this.ng...
    method constructor (line 422) | constructor(n){this._ref=n}
    method ngOnDestroy (line 422) | ngOnDestroy(){this._subscription&&this._dispose(),this._ref=null}
    method transform (line 422) | transform(n){if(!this._obj){if(n)try{this.markForCheckOnValueUpdate=!1...
    method _subscribe (line 422) | _subscribe(n){this._obj=n,this._strategy=this._selectStrategy(n),this....
    method _selectStrategy (line 422) | _selectStrategy(n){if(gi(n))return X2;if(Lu(n))return eT;throw J2(e,n)}
    method _dispose (line 422) | _dispose(){this._strategy.dispose(this._subscription),this._latestValu...
    method _updateLatestValue (line 422) | _updateLatestValue(n,r){n===this._obj&&(this._latestValue=r,this.markF...
    method constructor (line 422) | constructor(n){this.differs=n}
    method transform (line 422) | transform(n,r=I1){if(!n||!(n instanceof Map)&&typeof n!="object")retur...
    method constructor (line 422) | constructor(n){super(n)}
    method supports (line 422) | supports(n){return!0}
    method addEventListener (line 422) | addEventListener(n,r,o,i){return n.addEventListener(r,o,i),()=>this.re...
    method removeEventListener (line 422) | removeEventListener(n,r,o,i){return n.removeEventListener(r,o,i)}
    method constructor (line 422) | constructor(n,r){this._zone=r,n.forEach(s=>{s.manager=this});let o=n.f...
    method addEventListener (line 422) | addEventListener(n,r,o,i){return this._findPluginFor(r).addEventListen...
    method getZone (line 422) | getZone(){return this._zone}
    method _findPluginFor (line 422) | _findPluginFor(n){let r=this._eventNameToPlugin.get(n);if(r)return r;i...
    method constructor (line 422) | constructor(n,r,o,i={}){this.doc=n,this.appId=r,this.nonce=o,iT(n,r,th...
    method addStyles (line 422) | addStyles(n,r){for(let o of n)this.addUsage(o,this.inline,A1);r?.forEa...
    method removeStyles (line 422) | removeStyles(n,r){for(let o of n)this.removeUsage(o,this.inline);r?.fo...
    method addUsage (line 422) | addUsage(n,r,o){let i=r.get(n);i?i.usage++:r.set(n,{usage:1,elements:[...
    method removeUsage (line 422) | removeUsage(n,r){let o=r.get(n);o&&(o.usage--,o.usage<=0&&(M1(o.elemen...
    method ngOnDestroy (line 422) | ngOnDestroy(){for(let[,{elements:n}]of[...this.inline,...this.external...
    method addHost (line 422) | addHost(n){this.hosts.add(n);for(let[r,{elements:o}]of this.inline)o.p...
    method removeHost (line 422) | removeHost(n){this.hosts.delete(n)}
    method addElement (line 422) | addElement(n,r){return this.nonce&&r.setAttribute("nonce",this.nonce),...
    method constructor (line 422) | constructor(n,r,o,i,s,u,a=null,c=null){this.eventManager=n,this.shared...
    method createRenderer (line 422) | createRenderer(n,r){if(!n||!r)return this.defaultRenderer;let o=this.g...
    method getOrCreateRenderer (line 422) | getOrCreateRenderer(n,r){let o=this.rendererByCompId,i=o.get(r.id);if(...
    method ngOnDestroy (line 422) | ngOnDestroy(){this.rendererByCompId.clear()}
    method componentReplaced (line 422) | componentReplaced(n){this.rendererByCompId.delete(n)}
    method build (line 422) | build(){return new XMLHttpRequest}
    method constructor (line 422) | constructor(n){super(n)}
    method supports (line 422) | supports(n){return e.parseEventName(n)!=null}
    method addEventListener (line 422) | addEventListener(n,r,o,i){let s=e.parseEventName(r),u=e.eventCallback(...
    method parseEventName (line 422) | static parseEventName(n){let r=n.toLowerCase().split("."),o=r.shift();...
    method matchEventFullKeyCode (line 422) | static matchEventFullKeyCode(n,r){let o=gT[n.key]||n.key,i="";return r...
    method eventCallback (line 422) | static eventCallback(n,r,o){return i=>{e.matchEventFullKeyCode(i,n)&&o...
    method _normalizeKey (line 422) | static _normalizeKey(n){return n==="esc"?"escape":n}
    method constructor (line 422) | constructor(){}
    method constructor (line 423) | constructor(n){this.xhrFactory=n}
    method maybePropagateTrace (line 423) | maybePropagateTrace(n){return this.tracingService?.propagate?this.trac...
    method handle (line 423) | handle(n){if(n.method==="JSONP")throw new C(-2800,!1);let r=this.xhrFa...
    method constructor (line 423) | constructor(n,r){this.backend=n,this.injector=r}
    method handle (line 423) | handle(n){if(this.chain===null){let r=Array.from(new Set([...this.inje...
    method constructor (line 423) | constructor(n){this.handler=n}
    method request (line 423) | request(n,r,o={}){let i;if(n instanceof uo)i=n;else{let a;o.headers in...
    method delete (line 423) | delete(n,r={}){return this.request("DELETE",n,r)}
    method get (line 423) | get(n,r={}){return this.request("GET",n,r)}
    method head (line 423) | head(n,r={}){return this.request("HEAD",n,r)}
    method jsonp (line 423) | jsonp(n,r){return this.request("JSONP",n,{params:new zt().append(r,"JS...
    method options (line 423) | options(n,r={}){return this.request("OPTIONS",n,r)}
    method patch (line 423) | patch(n,r,o={}){return this.request("PATCH",n,yp(o,r))}
    method post (line 423) | post(n,r,o={}){return this.request("POST",n,yp(o,r))}
    method put (line 423) | put(n,r,o={}){return this.request("PUT",n,yp(o,r))}
    method getToken (line 423) | getToken(){let n=this.doc.cookie||"";return n!==this.lastCookieString&...
    method constructor (line 423) | constructor(n){this._doc=n}
    method getTitle (line 423) | getTitle(){return this._doc.title}
    method setTitle (line 423) | setTitle(n){this._doc.title=n||""}
    method constructor (line 423) | constructor(n){super(),this._doc=n}
    method sanitize (line 423) | sanitize(n,r){if(r==null)return null;switch(n){case Pe.NONE:return r;c...
    method bypassSecurityTrustHtml (line 423) | bypassSecurityTrustHtml(n){return md(n)}
    method bypassSecurityTrustStyle (line 423) | bypassSecurityTrustStyle(n){return yd(n)}
    method bypassSecurityTrustScript (line 423) | bypassSecurityTrustScript(n){return bd(n)}
    method bypassSecurityTrustUrl (line 423) | bypassSecurityTrustUrl(n){return vd(n)}
    method bypassSecurityTrustResourceUrl (line 423) | bypassSecurityTrustResourceUrl(n){return Dd(n)}
    method setData (line 438) | setData(n,r,o,i){return super.setData(n,r,o,i??void 0)}
    method dispatch (line 438) | dispatch(n){let r=new ce;return this.events.next({message:n,completion...
    method sendAction (line 438) | sendAction(n){let r=this.component(),o=this.surfaceId()??void 0,i={};i...
    method resolvePrimitive (line 438) | resolvePrimitive(n){let r=this.component(),o=this.surfaceId();return!n...
    method getUniqueId (line 438) | getUniqueId(n){return`${n}-${ZM++}`}
    method constructor (line 438) | constructor(){Yo(()=>{let o=this.surfaceId(),i=this.component();De(()=...
    method ngOnDestroy (line 438) | ngOnDestroy(){this.isDestroyed=!0,this.clear()}
    method render (line 438) | render(n,r){return lt(this,null,function*(){let o=this.catalog[r.type]...
    method clear (line 438) | clear(){this.currentRef?.destroy(),this.currentRef=null}
    method render (line 438) | render(n,r){r&&this.applyTagClassMap(r);let o=this.markdownIt.render(n...
    method applyTagClassMap (line 438) | applyTagClassMap(n){Object.entries(n).forEach(([r,o])=>{let i;switch(r...
    method unapplyTagClassMap (line 438) | unapplyTagClassMap(){for(let[n,r]of this.originalClassMap)this.markdow...
    method areHintedStyles (line 438) | areHintedStyles(n){return typeof n!="object"||!n||Array.isArray(n)?!1:...
  method constructor (line 3) | constructor(t,n){super(),this.destination=t,this.source=n}
  method next (line 3) | next(t){var n,r;(r=(n=this.destination)===null||n===void 0?void 0:n.next...
  method error (line 3) | error(t){var n,r;(r=(n=this.destination)===null||n===void 0?void 0:n.err...
  method complete (line 3) | complete(){var t,n;(n=(t=this.destination)===null||t===void 0?void 0:t.c...
  method _subscribe (line 3) | _subscribe(t){var n,r;return(r=(n=this.source)===null||n===void 0?void 0...
  method constructor (line 3) | constructor(t){super(),this._value=t}
  method value (line 3) | get value(){return this.getValue()}
  method _subscribe (line 3) | _subscribe(t){let n=super._subscribe(t);return!n.closed&&t.next(this._va...
  method getValue (line 3) | getValue(){let{hasError:t,thrownError:n,_value:r}=this;if(t)throw n;retu...
  method next (line 3) | next(t){super.next(this._value=t)}
  method now (line 3) | now(){return(_o.delegate||Date).now()}
  method constructor (line 3) | constructor(t=1/0,n=1/0,r=_o){super(),this._bufferSize=t,this._windowTim...
  method next (line 3) | next(t){let{isStopped:n,_buffer:r,_infiniteTimeWindow:o,_timestampProvid...
  method _subscribe (line 3) | _subscribe(t){this._throwIfClosed(),this._trimBuffer();let n=this._inner...
  method _trimBuffer (line 3) | _trimBuffer(){let{_bufferSize:t,_timestampProvider:n,_buffer:r,_infinite...
  method constructor (line 3) | constructor(t,n){super()}
  method schedule (line 3) | schedule(t,n=0){return this}
  method setInterval (line 3) | setInterval(e,t,...n){let{delegate:r}=xo;return r?.setInterval?r.setInte...
  method clearInterval (line 3) | clearInterval(e){let{delegate:t}=xo;return(t?.clearInterval||clearInterv...
  method constructor (line 3) | constructor(t,n){super(t,n),this.scheduler=t,this.work=n,this.pending=!1}
  method schedule (line 3) | schedule(t,n=0){var r;if(this.closed)return this;this.state=t;let o=this...
  method requestAsyncId (line 3) | requestAsyncId(t,n,r=0){return xo.setInterval(t.flush.bind(t,this),r)}
  method recycleAsyncId (line 3) | recycleAsyncId(t,n,r=0){if(r!=null&&this.delay===r&&this.pending===!1)re...
  method execute (line 3) | execute(t,n){if(this.closed)return new Error("executing a cancelled acti...
  method _execute (line 3) | _execute(t,n){let r=!1,o;try{this.work(t)}catch(i){r=!0,o=i||new Error("...
  method unsubscribe (line 3) | unsubscribe(){if(!this.closed){let{id:t,scheduler:n}=this,{actions:r}=n;...
  function Gh (line 3) | function Gh(e){return e in ic?(delete ic[e],!0):!1}
  method setImmediate (line 3) | setImmediate(e){let t=hD++;return ic[t]=!0,oc||(oc=Promise.resolve()),oc...
  method clearImmediate (line 3) | clearImmediate(e){Gh(e)}
  method setImmediate (line 3) | setImmediate(...e){let{delegate:t}=Io;return(t?.setImmediate||gD)(...e)}
  method clearImmediate (line 3) | clearImmediate(e){let{delegate:t}=Io;return(t?.clearImmediate||mD)(e)}
  method constructor (line 3) | constructor(t,n){super(t,n),this.scheduler=t,this.work=n}
  method requestAsyncId (line 3) | requestAsyncId(t,n,r=0){return r!==null&&r>0?super.requestAsyncId(t,n,r)...
  method recycleAsyncId (line 3) | recycleAsyncId(t,n,r=0){var o;if(r!=null?r>0:this.delay>0)return super.r...
  method constructor (line 3) | constructor(t,n=e.now){this.schedulerActionCtor=t,this.now=n}
  method schedule (line 3) | schedule(t,n=0,r){return new this.schedulerActionCtor(this,t).schedule(r...
  method constructor (line 3) | constructor(t,n=Cr.now){super(t,n),this.actions=[],this._active=!1}
  method flush (line 3) | flush(t){let{actions:n}=this;if(this._active){n.push(t);return}let r;thi...
  method flush (line 3) | flush(t){this._active=!0;let n=this._scheduled;this._scheduled=void 0;le...
  method constructor (line 3) | constructor(t,n){super(t,n),this.scheduler=t,this.work=n}
  method requestAsyncId (line 3) | requestAsyncId(t,n,r=0){return r!==null&&r>0?super.requestAsyncId(t,n,r)...
  method recycleAsyncId (line 3) | recycleAsyncId(t,n,r=0){var o;if(r!=null?r>0:this.delay>0)return super.r...
  method flush (line 3) | flush(t){this._active=!0;let n;t?n=t.id:(n=this._scheduled,this._schedul...
  function Qi (line 3) | function Qi(e){return e&&k(e.schedule)}
  function uc (line 3) | function uc(e){return e[e.length-1]}
  function nn (line 3) | function nn(e){return k(uc(e))?e.pop():void 0}
  function ft (line 3) | function ft(e){return Qi(uc(e))?e.pop():void 0}
  function Zh (line 3) | function Zh(e,t){return typeof uc(e)=="number"?e.pop():t}
  function tk (line 3) | function tk(e,t,n,r){var o=arguments.length,i=o<3?t:r===null?r=Object.ge...
  function Qh (line 3) | function Qh(e,t,n,r){function o(i){return i instanceof n?i:new n(functio...
  function Yh (line 3) | function Yh(e){var t=typeof Symbol=="function"&&Symbol.iterator,n=t&&e[t...
  function An (line 3) | function An(e){return this instanceof An?(this.v=e,this):new An(e)}
  function Kh (line 3) | function Kh(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol....
  function Jh (line 3) | function Jh(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyn...
  function Ki (line 3) | function Ki(e){return k(e?.then)}
  function Ji (line 3) | function Ji(e){return k(e[Dr])}
  function Xi (line 3) | function Xi(e){return Symbol.asyncIterator&&k(e?.[Symbol.asyncIterator])}
  function es (line 3) | function es(e){return new TypeError(`You provided ${e!==null&&typeof e==...
  function vD (line 3) | function vD(){return typeof Symbol!="function"||!Symbol.iterator?"@@iter...
  function ns (line 3) | function ns(e){return k(e?.[ts])}
  function rs (line 3) | function rs(e){return Kh(this,arguments,function*(){let n=e.getReader();...
  function os (line 3) | function os(e){return k(e?.getReader)}
  function z (line 3) | function z(e){if(e instanceof B)return e;if(e!=null){if(Ji(e))return DD(...
  function DD (line 3) | function DD(e){return new B(t=>{let n=e[Dr]();if(k(n.subscribe))return n...
  function ED (line 3) | function ED(e){return new B(t=>{for(let n=0;n<e.length&&!t.closed;n++)t....
  function CD (line 3) | function CD(e){return new B(t=>{e.then(n=>{t.closed||(t.next(n),t.comple...
  function _D (line 3) | function _D(e){return new B(t=>{for(let n of e)if(t.next(n),t.closed)ret...
  function Xh (line 3) | function Xh(e){return new B(t=>{xD(e,t).catch(n=>t.error(n))})}
  function wD (line 3) | function wD(e){return Xh(rs(e))}
  function xD (line 3) | function xD(e,t){var n,r,o,i;return Qh(this,void 0,void 0,function*(){tr...
  function Me (line 3) | function Me(e,t,n,r=0,o=!1){let i=t.schedule(function(){n(),o?e.add(this...
  function To (line 3) | function To(e,t=0){return j((n,r)=>{n.subscribe(R(r,o=>Me(r,e,()=>r.next...
  function is (line 3) | function is(e,t=0){return j((n,r)=>{r.add(e.schedule(()=>n.subscribe(r),...
  function e0 (line 3) | function e0(e,t){return z(e).pipe(is(t),To(t))}
  function t0 (line 3) | function t0(e,t){return z(e).pipe(is(t),To(t))}
  function n0 (line 3) | function n0(e,t){return new B(n=>{let r=0;return t.schedule(function(){r...
  function r0 (line 3) | function r0(e,t){return new B(n=>{let r;return Me(n,t,()=>{r=e[ts](),Me(...
  function ss (line 3) | function ss(e,t){if(!e)throw new Error("Iterable cannot be null");return...
  function o0 (line 3) | function o0(e,t){return ss(rs(e),t)}
  function i0 (line 3) | function i0(e,t){if(e!=null){if(Ji(e))return e0(e,t);if(wr(e))return n0(...
  function pt (line 3) | function pt(e,t){return t?i0(e,t):z(e)}
  function us (line 3) | function us(...e){let t=ft(e);return pt(e,t)}
  function ID (line 3) | function ID(e,t){let n=k(e)?e:()=>e,r=o=>o.error(n());return new B(t?o=>...
  function TD (line 3) | function TD(e){return!!e&&(e instanceof B||k(e.lift)&&k(e.subscribe))}
  function ac (line 3) | function ac(e,t){let n=typeof t=="object";return new Promise((r,o)=>{let...
  function s0 (line 3) | function s0(e){return e instanceof Date&&!isNaN(e)}
  function Ce (line 3) | function Ce(e,t){return j((n,r)=>{let o=0;n.subscribe(R(r,i=>{r.next(e.c...
  function MD (line 3) | function MD(e,t){return SD(t)?e(...t):e(t)}
  function xr (line 3) | function xr(e){return Ce(t=>MD(e,t))}
  function as (line 3) | function as(e){if(e.length===1){let t=e[0];if(AD(t))return{args:t,keys:n...
  function FD (line 3) | function FD(e){return e&&typeof e=="object"&&ND(e)===kD}
  function cs (line 3) | function cs(e,t){return e.reduce((n,r,o)=>(n[r]=t[o],n),{})}
  function OD (line 3) | function OD(...e){let t=ft(e),n=nn(e),{args:r,keys:o}=as(e);if(r.length=...
  function PD (line 3) | function PD(e,t,n=Ee){return r=>{u0(t,()=>{let{length:o}=e,i=new Array(o...
  function u0 (line 3) | function u0(e,t,n){e?Me(n,e,t):t()}
  function a0 (line 3) | function a0(e,t,n,r,o,i,s,u){let a=[],c=0,l=0,d=!1,h=()=>{d&&!a.length&&...
  function At (line 3) | function At(e,t,n=1/0){return k(t)?At((r,o)=>Ce((i,s)=>t(r,i,o,s))(z(e(r...
  function So (line 3) | function So(e=1/0){return At(Ee,e)}
  function c0 (line 3) | function c0(){return So(1)}
  function ls (line 3) | function ls(...e){return c0()(pt(e,ft(e)))}
  function LD (line 3) | function LD(e){return new B(t=>{z(e()).subscribe(t)})}
  function jD (line 3) | function jD(...e){let t=nn(e),{args:n,keys:r}=as(e),o=new B(i=>{let{leng...
  function cc (line 3) | function cc(e,t,n,r){if(k(n)&&(r=n,n=void 0),r)return cc(e,t,n).pipe(xr(...
  function l0 (line 3) | function l0(e,t){return n=>r=>e[n](t,r)}
  function $D (line 3) | function $D(e){return k(e.addListener)&&k(e.removeListener)}
  function UD (line 3) | function UD(e){return k(e.on)&&k(e.off)}
  function zD (line 3) | function zD(e){return k(e.addEventListener)&&k(e.removeEventListener)}
  function lc (line 3) | function lc(e=0,t,n=sc){let r=-1;return t!=null&&(Qi(t)?n=t:r=t),new B(o...
  function qD (line 3) | function qD(...e){let t=ft(e),n=Zh(e,1/0),r=e;return r.length?r.length==...
  function d0 (line 3) | function d0(e){return e.length===1&&WD(e[0])?e[0]:e}
  function rn (line 3) | function rn(e,t){return j((n,r)=>{let o=0;n.subscribe(R(r,i=>e.call(t,i,...
  function ZD (line 3) | function ZD(...e){let t=nn(e),n=d0(e);return n.length?new B(r=>{let o=n....
  function f0 (line 3) | function f0(e){return j((t,n)=>{let r=!1,o=null,i=null,s=!1,u=()=>{if(i?...
  function YD (line 3) | function YD(e,t=_r){return f0(()=>lc(e,t))}
  function dc (line 3) | function dc(e){return j((t,n)=>{let r=null,o=!1,i;r=t.subscribe(R(n,void...
  function fc (line 3) | function fc(e,t){return k(t)?At(e,t,1):At(e,1)}
  function p0 (line 3) | function p0(e,t=_r){return j((n,r)=>{let o=null,i=null,s=null,u=()=>{if(...
  function h0 (line 3) | function h0(e){return j((t,n)=>{let r=!1;t.subscribe(R(n,o=>{r=!0,n.next...
  function pc (line 3) | function pc(e){return e<=0?()=>Mt:j((t,n)=>{let r=0;t.subscribe(R(n,o=>{...
  function QD (line 3) | function QD(e){return Ce(()=>e)}
  function g0 (line 3) | function g0(e,t=Ee){return e=e??KD,j((n,r)=>{let o,i=!0;n.subscribe(R(r,...
  function KD (line 3) | function KD(e,t){return e===t}
  function m0 (line 3) | function m0(e=JD){return j((t,n)=>{let r=!1;t.subscribe(R(n,o=>{r=!0,n.n...
  function JD (line 3) | function JD(){return new Nn}
  function ds (line 3) | function ds(e){return j((t,n)=>{try{t.subscribe(n)}finally{n.add(e)}})}
  function XD (line 3) | function XD(e,t){let n=arguments.length>=2;return r=>r.pipe(e?rn((o,i)=>...
  function eE (line 3) | function eE(e){return e<=0?()=>Mt:j((t,n)=>{let r=[];t.subscribe(R(n,o=>...
  function y0 (line 3) | function y0(){return j((e,t)=>{let n,r=!1;e.subscribe(R(t,o=>{let i=n;n=...
  function fs (line 3) | function fs(e={}){let{connector:t=()=>new ce,resetOnError:n=!0,resetOnCo...
  function hc (line 3) | function hc(e,t,...n){if(t===!0){e();return}if(t===!1)return;let r=new Z...
  function b0 (line 3) | function b0(e,t,n){let r,o=!1;return e&&typeof e=="object"?{bufferSize:r...
  function v0 (line 3) | function v0(e){return rn((t,n)=>e<=n)}
  function D0 (line 3) | function D0(...e){let t=ft(e);return j((n,r)=>{(t?ls(e,n,t):ls(e,n)).sub...
  function ps (line 3) | function ps(e,t){return j((n,r)=>{let o=null,i=0,s=!1,u=()=>s&&!o&&r.com...
  function tE (line 3) | function tE(e){return j((t,n)=>{z(e).subscribe(R(n,()=>n.complete(),St))...
  function nE (line 3) | function nE(e,t=!1){return j((n,r)=>{let o=0;n.subscribe(R(r,i=>{let s=e...
  function E0 (line 3) | function E0(e,t,n){let r=k(e)||t||n?{next:e,error:t,complete:n}:e;return...
  function rE (line 3) | function rE(...e){let t=nn(e);return j((n,r)=>{let o=e.length,i=new Arra...
  function hs (line 3) | function hs(){return gc}
  function ht (line 3) | function ht(e){let t=gc;return gc=e,t}
  function Ir (line 3) | function Ir(e){return e===C0||e?.name==="\u0275NotFound"}
  function mc (line 3) | function mc(e,t,n){let r=Object.create(oE);r.source=e,r.computation=t,n!...
  function _0 (line 3) | function _0(e,t){xn(e),In(e,t),hr(e)}
  function w0 (line 3) | function w0(e,t){if(xn(e),e.value===dt)throw e.error;Bi(e,t),hr(e)}
  method producerMustRecompute (line 3) | producerMustRecompute(e){return e.value===Yt||e.value===wn}
  method producerRecomputeValue (line 3) | producerRecomputeValue(e){if(e.value===wn)throw new Error("");let t=e.va...
  function x0 (line 3) | function x0(e){let t=I(null);try{return e()}finally{I(t)}}
  method constructor (line 3) | constructor(t,n){super(mt(t,n)),this.code=t}
  function iE (line 3) | function iE(e){return`NG0${Math.abs(e)}`}
  function mt (line 3) | function mt(e,t){return`${iE(e)}${t?": "+t:""}`}
  function W (line 3) | function W(e){for(let t in e)if(e[t]===W)return t;throw Error("")}
  function A0 (line 3) | function A0(e,t){for(let n in t)t.hasOwnProperty(n)&&!e.hasOwnProperty(n...
  function Oo (line 3) | function Oo(e){if(typeof e=="string")return e;if(Array.isArray(e))return...
  function Cs (line 4) | function Cs(e,t){return e?t?`${e} ${t}`:e:t||""}
  function _s (line 4) | function _s(e){return e.__forward_ref__=_s,e}
  function se (line 4) | function se(e){return Mc(e)?e():e}
  function Mc (line 4) | function Mc(e){return typeof e=="function"&&e.hasOwnProperty(sE)&&e.__fo...
  function T (line 4) | function T(e){return{token:e.token,providedIn:e.providedIn||null,factory...
  function yt (line 4) | function yt(e){return{providers:e.providers||[],imports:e.imports||[]}}
  function Po (line 4) | function Po(e){return aE(e,ws)}
  function uE (line 4) | function uE(e){return Po(e)!==null}
  function aE (line 4) | function aE(e,t){return e.hasOwnProperty(t)&&e[t]||null}
  function cE (line 4) | function cE(e){let t=e?.[ws]??null;return t||null}
  function bc (line 4) | function bc(e){return e&&e.hasOwnProperty(ms)?e[ms]:null}
  method constructor (line 4) | constructor(t,n){this._desc=t,this.\u0275prov=void 0,typeof n=="number"?...
  method multi (line 4) | get multi(){return this}
  method toString (line 4) | toString(){return`InjectionToken ${this._desc}`}
  function Ac (line 4) | function Ac(e){return e&&!!e.\u0275providers}
  function Oc (line 4) | function Oc(e){return Is(e,"@NgModule"),e[Fc]||null}
  function bt (line 4) | function bt(e){return Is(e,"@Component"),e[Nc]||null}
  function xs (line 4) | function xs(e){return Is(e,"@Directive"),e[kc]||null}
  function N0 (line 4) | function N0(e){return Is(e,"@Pipe"),e[Rc]||null}
  function Is (line 4) | function Is(e,t){if(e==null)throw new C(-919,!1)}
  function Ve (line 4) | function Ve(e){return typeof e=="string"?e:e==null?"":String(e)}
  function Pc (line 4) | function Pc(e,t){return R0("",-200,t)}
  function Ts (line 4) | function Ts(e,t){throw new C(-201,!1)}
  function R0 (line 4) | function R0(e,t,n){let r=new C(t,e);return r[k0]=t,r[lE]=e,n&&(r[dE]=n),r}
  function fE (line 4) | function fE(e){return e[k0]}
  function F0 (line 4) | function F0(){return vc}
  function _e (line 4) | function _e(e){let t=vc;return vc=e,t}
  function Lc (line 4) | function Lc(e,t,n){let r=Po(e);if(r&&r.providedIn=="root")return r.value...
  method constructor (line 4) | constructor(t){this.injector=t}
  method retrieve (line 4) | retrieve(t,n){let r=Rn(n)||0;try{return this.injector.get(t,r&8?null:kn,...
  function gE (line 4) | function gE(e,t=0){let n=hs();if(n===void 0)throw new C(-203,!1);if(n===...
  function A (line 4) | function A(e,t=0){return(F0()||gE)(se(e),t)}
  function b (line 4) | function b(e,t){return A(e,Rn(t))}
  function Rn (line 4) | function Rn(e){return typeof e>"u"||typeof e=="number"?e:0|(e.optional&&...
  function mE (line 4) | function mE(e){return{optional:!!(e&8),host:!!(e&1),self:!!(e&2),skipSel...
  function Ec (line 4) | function Ec(e){let t=[];for(let n=0;n<e.length;n++){let r=se(e[n]);if(Ar...
  function yE (line 4) | function yE(e){return e[hE]}
  function on (line 4) | function on(e,t){let n=e.hasOwnProperty(Ao);return n?e[Ao]:null}
  function O0 (line 4) | function O0(e,t,n){if(e.length!==t.length)return!1;for(let r=0;r<e.lengt...
  function P0 (line 4) | function P0(e){return e.flat(Number.POSITIVE_INFINITY)}
  function Ss (line 4) | function Ss(e,t){e.forEach(n=>Array.isArray(n)?Ss(n,t):t(n))}
  function jc (line 4) | function jc(e,t,n){t>=e.length?e.push(n):e.splice(t,0,n)}
  function Lo (line 4) | function Lo(e,t){return t>=e.length-1?e.pop():e.splice(t,1)[0]}
  function L0 (line 4) | function L0(e,t){let n=[];for(let r=0;r<e;r++)n.push(t);return n}
  function j0 (line 4) | function j0(e,t,n,r){let o=e.length;if(o==t)e.push(n,r);else if(o===1)e....
  function jo (line 4) | function jo(e,t,n){let r=Sr(e,t);return r>=0?e[r|1]=n:(r=~r,j0(e,r,t,n)),r}
  function Ms (line 4) | function Ms(e,t){let n=Sr(e,t);if(n>=0)return e[n|1]}
  function Sr (line 4) | function Sr(e,t){return bE(e,t,1)}
  function bE (line 4) | function bE(e,t,n){let r=0,o=e.length>>n;for(;o!==r;){let i=r+(o-r>>1),s...
  method get (line 4) | get(t,n=kn){if(n===kn){let o=R0("",-201);throw o.name="\u0275NotFound",o...
  function Ln (line 4) | function Ln(e){return{\u0275providers:e}}
  function B0 (line 4) | function B0(...e){return{\u0275providers:Hc(!0,e),\u0275fromNgModule:!0}}
  function Hc (line 4) | function Hc(e,...t){let n=[],r=new Set,o,i=s=>{n.push(s)};return Ss(t,s=...
  function V0 (line 4) | function V0(e,t){for(let n=0;n<e.length;n++){let{ngModule:r,providers:o}...
  function ys (line 4) | function ys(e,t,n,r){if(e=se(e),!e)return!1;let o=null,i=bc(e),s=!i&&bt(...
  function $c (line 4) | function $c(e,t){for(let n of e)Ac(n)&&(n=n.\u0275providers),Array.isArr...
  function H0 (line 4) | function H0(e){return e!==null&&typeof e=="object"&&vE in e}
  function DE (line 4) | function DE(e){return!!(e&&e.useExisting)}
  function EE (line 4) | function EE(e){return!!(e&&e.useFactory)}
  function Fn (line 4) | function Fn(e){return typeof e=="function"}
  function $0 (line 4) | function $0(e){return!!e.useClass}
  function Ar (line 4) | function Ar(){return yc===void 0&&(yc=new No),yc}
  method destroyed (line 4) | get destroyed(){return this._destroyed}
  method constructor (line 4) | constructor(t,n,r,o){super(),this.parent=n,this.source=r,this.scopes=o,_...
  method retrieve (line 4) | retrieve(t,n){let r=Rn(n)||0;try{return this.get(t,kn,r)}catch(o){if(Ir(...
  method destroy (line 4) | destroy(){Mo(this),this._destroyed=!0;let t=I(null);try{for(let r of thi...
  method onDestroy (line 4) | onDestroy(t){return Mo(this),this._onDestroyHooks.push(t),()=>this.remov...
  method runInContext (line 4) | runInContext(t){Mo(this);let n=ht(this),r=_e(void 0),o;try{return t()}fi...
  method get (line 4) | get(t,n=kn,r){if(Mo(this),t.hasOwnProperty(I0))return t[I0](this);let o=...
  method resolveInjectorInitializers (line 4) | resolveInjectorInitializers(){let t=I(null),n=ht(this),r=_e(void 0),o;tr...
  method toString (line 4) | toString(){return"R3Injector[...]"}
  method processProvider (line 4) | processProvider(t){t=se(t);let n=Fn(t)?t:se(t&&t.provide),r=_E(t);if(!Fn...
  method hydrate (line 4) | hydrate(t,n,r){let o=I(null);try{if(n.value===T0)throw Pc("");return n.v...
  method injectableDefInScope (line 4) | injectableDefInScope(t){if(!t.providedIn)return!1;let n=se(t.providedIn)...
  method removeOnDestroy (line 4) | removeOnDestroy(t){let n=this._onDestroyHooks.indexOf(t);n!==-1&&this._o...
  function Cc (line 4) | function Cc(e){let t=Po(e),n=t!==null?t.factory:on(e);if(n!==null)return...
  function CE (line 4) | function CE(e){if(e.length>0)throw new C(-204,!1);let n=cE(e);return n!=...
  function _E (line 4) | function _E(e){if(H0(e))return Tr(void 0,e.useValue);{let t=Uc(e);return...
  function Uc (line 4) | function Uc(e,t,n){let r;if(Fn(e)){let o=se(e);return on(o)||Cc(o)}else ...
  function Mo (line 4) | function Mo(e){if(e.destroyed)throw new C(-205,!1)}
  function Tr (line 4) | function Tr(e,t,n=!1){return{factory:e,value:t,multi:n?[]:void 0}}
  function wE (line 4) | function wE(e){return!!e.deps}
  function xE (line 4) | function xE(e){return e!==null&&typeof e=="object"&&typeof e.ngOnDestroy...
  function IE (line 4) | function IE(e){return typeof e=="function"||typeof e=="object"&&e.ngMeta...
  function _c (line 4) | function _c(e,t){for(let n of e)Array.isArray(n)?_c(n,t):n&&Ac(n)?_c(n.\...
  function Nr (line 4) | function Nr(e,t){let n;e instanceof On?(Mo(e),n=e):n=new Dc(e);let r,o=h...
  function As (line 4) | function As(){return F0()!==void 0||hs()!=null}
  function TE (line 4) | function TE(e){if(!As())throw new C(-203,!1)}
  function Ot (line 4) | function Ot(e){return Array.isArray(e)&&typeof e[U0]=="object"}
  function Je (line 4) | function Je(e){return Array.isArray(e)&&e[U0]===!0}
  function Wc (line 4) | function Wc(e){return(e.flags&4)!==0}
  function Dt (line 4) | function Dt(e){return e.componentOffset>-1}
  function Fr (line 4) | function Fr(e){return(e.flags&1)===1}
  function Xe (line 4) | function Xe(e){return!!e.template}
  function Or (line 4) | function Or(e){return(e[L]&512)!==0}
  function Un (line 4) | function Un(e){return(e[L]&256)===256}
  function $e (line 4) | function $e(e){for(;Array.isArray(e);)e=e[Qe];return e}
  function Yc (line 4) | function Yc(e,t){return $e(t[e])}
  function Ue (line 4) | function Ue(e,t){return $e(t[e.index])}
  function ks (line 4) | function ks(e,t){return e.data[t]}
  function Ho (line 4) | function Ho(e,t){return e[t]}
  function $o (line 4) | function $o(e,t,n,r){n>=e.data.length&&(e.data[n]=null,e.blueprint[n]=nu...
  function ke (line 4) | function ke(e,t){let n=t[e];return Ot(n)?n:n[Qe]}
  function q0 (line 4) | function q0(e){return(e[L]&4)===4}
  function Rs (line 4) | function Rs(e){return(e[L]&128)===128}
  function G0 (line 4) | function G0(e){return Je(e[ue])}
  function Re (line 4) | function Re(e,t){return t==null?null:e[t]}
  function Qc (line 4) | function Qc(e){e[Vn]=0}
  function Kc (line 4) | function Kc(e){e[L]&1024||(e[L]|=1024,Rs(e)&&zn(e))}
  function W0 (line 4) | function W0(e,t){for(;e>0;)t=t[Bn],e--;return t}
  function Uo (line 4) | function Uo(e){return!!(e[L]&9216||e[Ne]?.dirty)}
  function Fs (line 4) | function Fs(e){e[Ke].changeDetectionScheduler?.notify(8),e[L]&64&&(e[L]|...
  function zn (line 4) | function zn(e){e[Ke].changeDetectionScheduler?.notify(0);let t=un(e);for...
  function Jc (line 4) | function Jc(e,t){if(Un(e))throw new C(911,!1);e[kt]===null&&(e[kt]=[]),e...
  function Z0 (line 4) | function Z0(e,t){if(e[kt]===null)return;let n=e[kt].indexOf(t);n!==-1&&e...
  function un (line 4) | function un(e){let t=e[ue];return Je(t)?t[ue]:t}
  function Xc (line 4) | function Xc(e){return e[kr]??=[]}
  function el (line 4) | function el(e){return e.cleanup??=[]}
  function Y0 (line 4) | function Y0(e,t,n,r){let o=Xc(t);o.push(n),e.firstCreatePass&&el(e).push...
  function Q0 (line 4) | function Q0(){return V.lFrame.elementDepthCount}
  function K0 (line 4) | function K0(){V.lFrame.elementDepthCount++}
  function tl (line 4) | function tl(){V.lFrame.elementDepthCount--}
  function Os (line 4) | function Os(){return V.bindingsEnabled}
  function nl (line 4) | function nl(){return V.skipHydrationRootTNode!==null}
  function rl (line 4) | function rl(e){return V.skipHydrationRootTNode===e}
  function ol (line 4) | function ol(){V.skipHydrationRootTNode=null}
  function _ (line 4) | function _(){return V.lFrame.lView}
  function G (line 4) | function G(){return V.lFrame.tView}
  function J0 (line 4) | function J0(e){return V.lFrame.contextLView=e,e[ee]}
  function X0 (line 4) | function X0(e){return V.lFrame.contextLView=null,e}
  function re (line 4) | function re(){let e=il();for(;e!==null&&e.type===64;)e=e.parent;return e}
  function il (line 4) | function il(){return V.lFrame.currentTNode}
  function eg (line 4) | function eg(){let e=V.lFrame,t=e.currentTNode;return e.isParent?t:t.parent}
  function qn (line 4) | function qn(e,t){let n=V.lFrame;n.currentTNode=e,n.isParent=t}
  function sl (line 4) | function sl(){return V.lFrame.isParent}
  function ul (line 4) | function ul(){V.lFrame.isParent=!1}
  function al (line 4) | function al(){return V.lFrame.contextLView}
  function cl (line 4) | function cl(){return wc}
  function ko (line 4) | function ko(e){let t=wc;return wc=e,t}
  function Pr (line 4) | function Pr(){let e=V.lFrame,t=e.bindingRootIndex;return t===-1&&(t=e.bi...
  function ll (line 4) | function ll(){return V.lFrame.bindingIndex}
  function tg (line 4) | function tg(e){return V.lFrame.bindingIndex=e}
  function et (line 4) | function et(){return V.lFrame.bindingIndex++}
  function zo (line 4) | function zo(e){let t=V.lFrame,n=t.bindingIndex;return t.bindingIndex=t.b...
  function ng (line 4) | function ng(){return V.lFrame.inI18n}
  function rg (line 4) | function rg(e,t){let n=V.lFrame;n.bindingIndex=n.bindingRootIndex=e,Ps(t)}
  function og (line 4) | function og(){return V.lFrame.currentDirectiveIndex}
  function Ps (line 4) | function Ps(e){V.lFrame.currentDirectiveIndex=e}
  function ig (line 4) | function ig(e){let t=V.lFrame.currentDirectiveIndex;return t===-1?null:e...
  function Ls (line 4) | function Ls(){return V.lFrame.currentQueryIndex}
  function qo (line 4) | function qo(e){V.lFrame.currentQueryIndex=e}
  function SE (line 4) | function SE(e){let t=e[S];return t.type===2?t.declTNode:t.type===1?e[Ie]...
  function dl (line 4) | function dl(e,t,n){if(n&4){let o=t,i=e;for(;o=o.parent,o===null&&!(n&1);...
  function js (line 4) | function js(e){let t=sg(),n=e[S];V.lFrame=t,t.currentTNode=n.firstChild,...
  function sg (line 4) | function sg(){let e=V.lFrame,t=e===null?null:e.child;return t===null?ug(...
  function ug (line 4) | function ug(e){let t={currentTNode:null,isParent:!0,lView:null,tView:nul...
  function ag (line 4) | function ag(){let e=V.lFrame;return V.lFrame=e.parent,e.currentTNode=nul...
  function Bs (line 4) | function Bs(){let e=ag();e.isParent=!0,e.tView=null,e.selectedIndex=-1,e...
  function cg (line 4) | function cg(e){return(V.lFrame.contextLView=W0(e,V.lFrame.contextLView))...
  function ze (line 4) | function ze(){return V.lFrame.selectedIndex}
  function dn (line 4) | function dn(e){V.lFrame.selectedIndex=e}
  function fn (line 4) | function fn(){let e=V.lFrame;return ks(e.tView,e.selectedIndex)}
  function lg (line 4) | function lg(){V.lFrame.currentNamespace=Zc}
  function dg (line 4) | function dg(){ME()}
  function ME (line 4) | function ME(){V.lFrame.currentNamespace=null}
  function fg (line 4) | function fg(){return V.lFrame.currentNamespace}
  function Vs (line 4) | function Vs(){return pg}
  function Go (line 4) | function Go(e){pg=e}
  function xc (line 4) | function xc(e,t=null,n=null,r){let o=pl(e,t,n,r);return o.resolveInjecto...
  function pl (line 4) | function pl(e,t=null,n=null,r,o=new Set){let i=[n||ye,B0(e)],s;return ne...
  method create (line 4) | static create(t,n){if(Array.isArray(t))return xc({name:""},n,t,"");{let ...
  class e (line 4) | class e{static __NG_ELEMENT_ID__=AE;static __NG_ENV_ID__=n=>n}
    method constructor (line 3) | constructor(n){n&&(this._subscribe=n)}
    method lift (line 3) | lift(n){let r=new e;return r.source=this,r.operator=n,r}
    method subscribe (line 3) | subscribe(n,r,o){let i=pD(n)?n:new Ze(n,r,o);return vr(()=>{let{operat...
    method _trySubscribe (line 3) | _trySubscribe(n){try{return this._subscribe(n)}catch(r){n.error(r)}}
    method forEach (line 3) | forEach(n,r){return r=Uh(r),new r((o,i)=>{let s=new Ze({next:u=>{try{n...
    method _subscribe (line 3) | _subscribe(n){var r;return(r=this.source)===null||r===void 0?void 0:r....
    method [Dr] (line 3) | [Dr](){return this}
    method pipe (line 3) | pipe(...n){return ec(n)(this)}
    method toPromise (line 3) | toPromise(n){return n=Uh(n),new n((r,o)=>{let i;this.subscribe(s=>i=s,...
    method constructor (line 3) | constructor(){super(),this.closed=!1,this.currentObservers=null,this.o...
    method lift (line 3) | lift(n){let r=new zi(this,this);return r.operator=n,r}
    method _throwIfClosed (line 3) | _throwIfClosed(){if(this.closed)throw new qh}
    method next (line 3) | next(n){vr(()=>{if(this._throwIfClosed(),!this.isStopped){this.current...
    method error (line 3) | error(n){vr(()=>{if(this._throwIfClosed(),!this.isStopped){this.hasErr...
    method complete (line 3) | complete(){vr(()=>{if(this._throwIfClosed(),!this.isStopped){this.isSt...
    method unsubscribe (line 3) | unsubscribe(){this.isStopped=this.closed=!0,this.observers=this.curren...
    method observed (line 3) | get observed(){var n;return((n=this.observers)===null||n===void 0?void...
    method _trySubscribe (line 3) | _trySubscribe(n){return this._throwIfClosed(),super._trySubscribe(n)}
    method _subscribe (line 3) | _subscribe(n){return this._throwIfClosed(),this._checkFinalizedStatuse...
    method _innerSubscribe (line 3) | _innerSubscribe(n){let{hasError:r,isStopped:o,observers:i}=this;return...
    method _checkFinalizedStatuses (line 3) | _checkFinalizedStatuses(n){let{hasError:r,thrownError:o,isStopped:i}=t...
    method asObservable (line 3) | asObservable(){let n=new B;return n.source=this,n}
    method hasPendingTasks (line 4) | get hasPendingTasks(){return this.destroyed?!1:this.pendingTask.value}
    method hasPendingTasksObservable (line 4) | get hasPendingTasksObservable(){return this.destroyed?new B(n=>{n.next...
    method add (line 4) | add(){!this.hasPendingTasks&&!this.destroyed&&this.pendingTask.next(!0...
    method has (line 4) | has(n){return this.pendingTasks.has(n)}
    method remove (line 4) | remove(n){this.pendingTasks.delete(n),this.debugTaskTracker?.remove(n)...
    method ngOnDestroy (line 4) | ngOnDestroy(){this.pendingTasks.clear(),this.hasPendingTasks&&this.pen...
    method constructor (line 4) | constructor(n,r){this.view=n,this.node=r}
    method add (line 4) | add(){let n=this.internalPendingTasks.add();return()=>{this.internalPe...
    method run (line 4) | run(n){let r=this.add();n().catch(this.errorHandler).finally(r)}
    method constructor (line 4) | constructor(n){this.nativeElement=n}
    method execute (line 4) | execute(){this.impl?.execute()}
    method constructor (line 4) | constructor(){b(ot,{optional:!0})}
    method execute (line 4) | execute(){let n=this.sequences.size>0;n&&Y(q.AfterRenderHooksStart),th...
    method register (line 4) | register(n){let{view:r}=n;r!==void 0?((r[Hn]??=[]).push(n),zn(r),r[L]|...
    method addSequence (line 4) | addSequence(n){this.sequences.add(n),this.scheduler.notify(7)}
    method unregister (line 4) | unregister(n){this.executing&&this.sequences.has(n)?(n.erroredOrDestro...
    method maybeTrace (line 4) | maybeTrace(n,r){return r?r.run(wu.AFTER_NEXT_RENDER,n):n()}
    method constructor (line 4) | constructor(n,r,o){this._declarationLView=n,this._declarationTContaine...
    method ssrId (line 4) | get ssrId(){return this._declarationTContainer.tView?.ssrId||null}
    method createEmbeddedView (line 4) | createEmbeddedView(n,r){return this.createEmbeddedViewImpl(n,r)}
    method createEmbeddedViewImpl (line 4) | createEmbeddedViewImpl(n,r,o){let i=li(this._declarationLView,this._de...
    method constructor (line 4) | constructor(n){this._injector=n}
    method getOrCreateStandaloneInjector (line 4) | getOrCreateStandaloneInjector(n){if(!n.standalone)return null;if(!this...
    method ngOnDestroy (line 4) | ngOnDestroy(){try{for(let n of this.cachedInjectors.values())n!==null&...
    method log (line 4) | log(n){console.log(n)}
    method warn (line 4) | warn(n){console.warn(n)}
    method constructor (line 4) | constructor(n,r,o){this._ngZone=n,this.registry=r,As()&&(this._destroy...
    method _watchAngularEvents (line 4) | _watchAngularEvents(){let n=this._ngZone.onUnstable.subscribe({next:()...
    method isStable (line 4) | isStable(){return this._isZoneStable&&!this._ngZone.hasPendingMacrotasks}
    method _runCallbacksIfReady (line 4) | _runCallbacksIfReady(){if(this.isStable())queueMicrotask(()=>{for(;thi...
    method getPendingTasks (line 4) | getPendingTasks(){return this._taskTrackingZone?this._taskTrackingZone...
    method addCallback (line 4) | addCallback(n,r,o){let i=-1;r&&r>0&&(i=setTimeout(()=>{this._callbacks...
    method whenStable (line 4) | whenStable(n,r,o){if(o&&!this._taskTrackingZone)throw new Error('Task ...
    method registerApplication (line 4) | registerApplication(n){this.registry.registerApplication(n,this)}
    method unregisterApplication (line 4) | unregisterApplication(n){this.registry.unregisterApplication(n)}
    method findProviders (line 4) | findProviders(n,r,o){return[]}
    method registerApplication (line 4) | registerApplication(n,r){this._applications.set(n,r)}
    method unregisterApplication (line 4) | unregisterApplication(n){this._applications.delete(n)}
    method unregisterAllApplications (line 4) | unregisterAllApplications(){this._applications.clear()}
    method getTestability (line 4) | getTestability(n){return this._applications.get(n)||null}
    method getAllTestabilities (line 4) | getAllTestabilities(){return Array.from(this._applications.values())}
    method getAllRootElements (line 4) | getAllRootElements(){return Array.from(this._applications.keys())}
    method findTestabilityInTree (line 4) | findTestabilityInTree(n,r=!0){return Yd?.findTestabilityInTree(this,n,...
    method constructor (line 4) | constructor(){}
    method runInitializers (line 4) | runInitializers(){if(this.initialized)return;let n=[];for(let o of thi...
    method allViews (line 4) | get allViews(){return[...(this.includeAllTestViews?this.allTestViews:t...
    method destroyed (line 4) | get destroyed(){return this._destroyed}
    method isStable (line 4) | get isStable(){return this.internalPendingTask.hasPendingTasksObservab...
    method constructor (line 4) | constructor(){b(ot,{optional:!0})}
    method whenStable (line 4) | whenStable(){let n;return new Promise(r=>{n=this.isStable.subscribe({n...
    method injector (line 4) | get injector(){return this._injector}
    method bootstrap (line 4) | bootstrap(n,r){return this.bootstrapImpl(n,r)}
    method bootstrapImpl (line 4) | bootstrapImpl(n,r,o=fe.NULL){return this._injector.get(be).run(()=>{Y(...
    method tick (line 4) | tick(){this.zonelessEnabled||(this.dirtyFlags|=1),this._tick()}
    method _tick (line 4) | _tick(){Y(q.ChangeDetectionStart),this.tracingSnapshot!==null?this.tra...
    method synchronize (line 4) | synchronize(){this._rendererFactory===null&&!this._injector.destroyed&...
    method synchronizeOnce (line 4) | synchronizeOnce(){this.dirtyFlags&16&&(this.dirtyFlags&=-17,this.rootE...
    method syncDirtyFlagsWithViews (line 4) | syncDirtyFlagsWithViews(){if(this.allViews.some(({_lView:n})=>Uo(n))){...
    method attachView (line 4) | attachView(n){let r=n;this._views.push(r),r.attachToAppRef(this)}
    method detachView (line 4) | detachView(n){let r=n;Ko(this._views,r),r.detachFromAppRef()}
    method _loadComponent (line 4) | _loadComponent(n){this.attachView(n.hostView);try{this.tick()}catch(o)...
    method ngOnDestroy (line 4) | ngOnDestroy(){if(!this._destroyed)try{this._destroyListeners.forEach(n...
    method onDestroy (line 4) | onDestroy(n){return this._destroyListeners.push(n),()=>Ko(this._destro...
    method destroy (line 4) | destroy(){if(this._destroyed)throw new C(406,!1);let n=this._injector;...
    method viewCount (line 4) | get viewCount(){return this._views.length}
    method compileModuleSync (line 4) | compileModuleSync(n){return new du(n)}
    method compileModuleAsync (line 4) | compileModuleAsync(n){return Promise.resolve(this.compileModuleSync(n))}
    method compileModuleAndAllComponentsSync (line 4) | compileModuleAndAllComponentsSync(n){let r=this.compileModuleSync(n),o...
    method compileModuleAndAllComponentsAsync (line 4) | compileModuleAndAllComponentsAsync(n){return Promise.resolve(this.comp...
    method clearCache (line 4) | clearCache(){}
    method clearCacheFor (line 4) | clearCacheFor(n){}
    method getModuleId (line 4) | getModuleId(n){}
    method constructor (line 4) | constructor(){this.subscriptions.add(this.appRef.afterTick.subscribe((...
    method switchToMicrotaskScheduler (line 4) | switchToMicrotaskScheduler(){this.ngZone.runOutsideAngular(()=>{let n=...
    method notify (line 4) | notify(n){if(!this.zonelessEnabled&&n===5)return;switch(n){case 0:{thi...
    method shouldScheduleTick (line 4) | shouldScheduleTick(){return!(this.appRef.destroyed||this.pendingRender...
    method tick (line 4) | tick(){if(this.runningTick||this.appRef.destroyed)return;if(this.appRe...
    method ngOnDestroy (line 4) | ngOnDestroy(){this.subscriptions.unsubscribe(),this.cleanup()}
    method cleanup (line 4) | cleanup(){if(this.runningTick=!1,this.cancelScheduledCallback?.(),this...
    method constructor (line 4) | constructor(n){this.factories=n}
    method create (line 4) | static create(n,r){if(r!=null){let o=r.factories.slice();n=n.concat(o)...
    method extend (line 4) | static extend(n){return{provide:e,useFactory:()=>{let r=b(e,{optional:...
    method find (line 4) | find(n){let r=this.factories.find(o=>o.supports(n));if(r!=null)return ...
    method constructor (line 4) | constructor(n){this.factories=n}
    method create (line 4) | static create(n,r){if(r){let o=r.factories.slice();n=n.concat(o)}retur...
    method extend (line 4) | static extend(n){return{provide:e,useFactory:()=>{let r=b(e,{optional:...
    method find (line 4) | find(n){let r=this.factories.find(o=>o.supports(n));if(r)return r;thro...
    method constructor (line 4) | constructor(n){}
    method constructor (line 422) | constructor(n={mapCtor:Map,arrayCtor:Array,setCtor:Set,objCtor:Object}...
    method getSurfaces (line 422) | getSurfaces(){return this.surfaces}
    method clearSurfaces (line 422) | clearSurfaces(){this.surfaces.clear()}
    method processMessages (line 422) | processMessages(n){for(let r of n)r.beginRendering&&this.handleBeginRe...
    method getData (line 422) | getData(n,r,o=e.DEFAULT_SURFACE_ID){let i=this.getOrCreateSurface(o);i...
    method setData (line 422) | setData(n,r,o,i=e.DEFAULT_SURFACE_ID){if(!n){console.warn("No componen...
    method resolvePath (line 422) | resolvePath(n,r){return n.startsWith("/")?n:r&&r!=="/"?r.endsWith("/")...
    method parseIfJsonString (line 422) | parseIfJsonString(n){if(typeof n!="string")return n;let r=n.trim();if(...
    method convertKeyValueArrayToMap (line 422) | convertKeyValueArrayToMap(n){let r=new this.mapCtor;for(let o of n){if...
    method setDataByPath (line 422) | setDataByPath(n,r,o){if(Array.isArray(o)&&(o.length===0||$(o[0])&&"key...
    method normalizePath (line 422) | normalizePath(n){return"/"+n.replace(/\[(\d+)\]/g,".$1").split(".").fi...
    method getDataByPath (line 422) | getDataByPath(n,r){let o=this.normalizePath(r).split("/").filter(s=>s)...
    method getOrCreateSurface (line 422) | getOrCreateSurface(n){let r=this.surfaces.get(n);return r||(r=new this...
    method handleBeginRendering (line 422) | handleBeginRendering(n,r){let o=this.getOrCreateSurface(r);o.rootCompo...
    method handleSurfaceUpdate (line 422) | handleSurfaceUpdate(n,r){let o=this.getOrCreateSurface(r);for(let i of...
    method handleDataModelUpdate (line 422) | handleDataModelUpdate(n,r){let o=this.getOrCreateSurface(r),i=n.path??...
    method handleDeleteSurface (line 422) | handleDeleteSurface(n){this.surfaces.delete(n.surfaceId)}
    method rebuildComponentTree (line 422) | rebuildComponentTree(n){if(!n.rootComponentId){n.componentTree=null;re...
    method findValueKey (line 422) | findValueKey(n){return Object.keys(n).find(r=>r.startsWith("value"))}
    method buildNodeRecursive (line 422) | buildNodeRecursive(n,r,o,i,s=""){let u=`${n}${s}`,{components:a}=r;if(...
    method resolvePropertyValue (line 422) | resolvePropertyValue(n,r,o,i,s=""){if(typeof n=="string"&&r.components...
    method historyGo (line 422) | historyGo(n){throw new Error("")}
    method constructor (line 422) | constructor(){super(),this._location=window.location,this._history=win...
    method getBaseHrefFromDOM (line 422) | getBaseHrefFromDOM(){return _t().getBaseHref(this._doc)}
    method onPopState (line 422) | onPopState(n){let r=_t().getGlobalEventTarget(this._doc,"window");retu...
    method onHashChange (line 422) | onHashChange(n){let r=_t().getGlobalEventTarget(this._doc,"window");re...
    method href (line 422) | get href(){return this._location.href}
    method protocol (line 422) | get protocol(){return this._location.protocol}
    method hostname (line 422) | get hostname(){return this._location.hostname}
    method port (line 422) | get port(){return this._location.port}
    method pathname (line 422) | get pathname(){return this._location.pathname}
    method search (line 422) | get search(){return this._location.search}
    method hash (line 422) | get hash(){return this._location.hash}
    method pathname (line 422) | set pathname(n){this._location.pathname=n}
    method pushState (line 422) | pushState(n,r,o){this._history.pushState(n,r,o)}
    method replaceState (line 422) | replaceState(n,r,o){this._history.replaceState(n,r,o)}
    method forward (line 422) | forward(){this._history.forward()}
    method back (line 422) | back(){this._history.back()}
    method historyGo (line 422) | historyGo(n=0){this._history.go(n)}
    method getState (line 422) | getState(){return this._history.state}
    method historyGo (line 422) | historyGo(n){throw new Error("")}
    method constructor (line 422) | constructor(n,r){super(),this._platformLocation=n,this._baseHref=r??th...
    method ngOnDestroy (line 422) | ngOnDestroy(){for(;this._removeListenerFns.length;)this._removeListene...
    method onPopState (line 422) | onPopState(n){this._removeListenerFns.push(this._platformLocation.onPo...
    method getBaseHref (line 422) | getBaseHref(){return this._baseHref}
    method prepareExternalUrl (line 422) | prepareExternalUrl(n){return aa(this._baseHref,n)}
    method path (line 422) | path(n=!1){let r=this._platformLocation.pathname+ut(this._platformLoca...
    method pushState (line 422) | pushState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i));this._platfo...
    method replaceState (line 422) | replaceState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i));this._pla...
    method forward (line 422) | forward(){this._platformLocation.forward()}
    method back (line 422) | back(){this._platformLocation.back()}
    method getState (line 422) | getState(){return this._platformLocation.getState()}
    method historyGo (line 422) | historyGo(n=0){this._platformLocation.historyGo?.(n)}
    method constructor (line 422) | constructor(n){this._locationStrategy=n;let r=this._locationStrategy.g...
    method ngOnDestroy (line 422) | ngOnDestroy(){this._urlChangeSubscription?.unsubscribe(),this._urlChan...
    method path (line 422) | path(n=!1){return this.normalize(this._locationStrategy.path(n))}
    method getState (line 422) | getState(){return this._locationStrategy.getState()}
    method isCurrentPathEqualTo (line 422) | isCurrentPathEqualTo(n,r=""){return this.path()==this.normalize(n+ut(r))}
    method normalize (line 422) | normalize(n){return e.stripTrailingSlash(U2(this._basePath,D1(n)))}
    method prepareExternalUrl (line 422) | prepareExternalUrl(n){return n&&n[0]!=="/"&&(n="/"+n),this._locationSt...
    method go (line 422) | go(n,r="",o=null){this._locationStrategy.pushState(o,"",n,r),this._not...
    method replaceState (line 422) | replaceState(n,r="",o=null){this._locationStrategy.replaceState(o,"",n...
    method forward (line 422) | forward(){this._locationStrategy.forward()}
    method back (line 422) | back(){this._locationStrategy.back()}
    method historyGo (line 422) | historyGo(n=0){this._locationStrategy.historyGo?.(n)}
    method onUrlChange (line 422) | onUrlChange(n){return this._urlChangeListeners.push(n),this._urlChange...
    method _notifyUrlChangeListeners (line 422) | _notifyUrlChangeListeners(n="",r){this._urlChangeListeners.forEach(o=>...
    method subscribe (line 422) | subscribe(n,r,o){return this._subject.subscribe({next:n,error:r??void ...
    method constructor (line 422) | constructor(n,r){super(),this._platformLocation=n,r!=null&&(this._base...
    method ngOnDestroy (line 422) | ngOnDestroy(){for(;this._removeListenerFns.length;)this._removeListene...
    method onPopState (line 422) | onPopState(n){this._removeListenerFns.push(this._platformLocation.onPo...
    method getBaseHref (line 422) | getBaseHref(){return this._baseHref}
    method path (line 422) | path(n=!1){let r=this._platformLocation.hash??"#";return r.length>0?r....
    method prepareExternalUrl (line 422) | prepareExternalUrl(n){let r=aa(this._baseHref,n);return r.length>0?"#"...
    method pushState (line 422) | pushState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i))||this._platf...
    method replaceState (line 422) | replaceState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i))||this._pl...
    method forward (line 422) | forward(){this._platformLocation.forward()}
    method back (line 422) | back(){this._platformLocation.back()}
    method getState (line 422) | getState(){return this._platformLocation.getState()}
    method historyGo (line 422) | historyGo(n=0){this._platformLocation.historyGo?.(n)}
    method constructor (line 422) | constructor(n,r){this._ngEl=n,this._renderer=r}
    method klass (line 422) | set klass(n){this.initialClasses=n!=null?n.trim().split(op):_1}
    method ngClass (line 422) | set ngClass(n){this.rawClass=typeof n=="string"?n.trim().split(op):n}
    method ngDoCheck (line 422) | ngDoCheck(){for(let r of this.initialClasses)this._updateState(r,!0);l...
    method _updateState (line 422) | _updateState(n,r){let o=this.stateMap.get(n);o!==void 0?(o.enabled!==r...
    method _applyStateDiff (line 422) | _applyStateDiff(){for(let n of this.stateMap){let r=n[0],o=n[1];o.chan...
    method _toggleClass (line 422) | _toggleClass(n,r){n=n.trim(),n.length>0&&n.split(op).forEach(o=>{r?thi...
    method componentInstance (line 422) | get componentInstance(){return this._componentRef?.instance??null}
    method constructor (line 422) | constructor(n){this._viewContainerRef=n}
    method _needToReCreateNgModuleInstance (line 422) | _needToReCreateNgModuleInstance(n){return n.ngComponentOutletNgModule!...
    method _needToReCreateComponentInstance (line 422) | _needToReCreateComponentInstance(n){return n.ngComponentOutlet!==void ...
    method ngOnChanges (line 422) | ngOnChanges(n){if(this._needToReCreateComponentInstance(n)&&(this._vie...
    method ngDoCheck (line 422) | ngDoCheck(){if(this._componentRef){if(this.ngComponentOutletInputs)for...
    method ngOnDestroy (line 422) | ngOnDestroy(){this._moduleRef?.destroy()}
    method _applyInputStateDiff (line 422) | _applyInputStateDiff(n){for(let[r,o]of this._inputsUsed)o?(n.setInput(...
    method ngForOf (line 422) | set ngForOf(n){this._ngForOf=n,this._ngForOfDirty=!0}
    method ngForTrackBy (line 422) | set ngForTrackBy(n){this._trackByFn=n}
    method ngForTrackBy (line 422) | get ngForTrackBy(){return this._trackByFn}
    method constructor (line 422) | constructor(n,r,o){this._viewContainer=n,this._template=r,this._differ...
    method ngForTemplate (line 422) | set ngForTemplate(n){n&&(this._template=n)}
    method ngDoCheck (line 422) | ngDoCheck(){if(this._ngForOfDirty){this._ngForOfDirty=!1;let n=this._n...
    method _applyChanges (line 422) | _applyChanges(n){let r=this._viewContainer;n.forEachOperation((o,i,s)=...
    method ngTemplateContextGuard (line 422) | static ngTemplateContextGuard(n,r){return!0}
    method constructor (line 422) | constructor(n,r){this._viewContainer=n,this._thenTemplateRef=r}
    method ngIf (line 422) | set ngIf(n){this._context.$implicit=this._context.ngIf=n,this._updateV...
    method ngIfThen (line 422) | set ngIfThen(n){x1(n,!1),this._thenTemplateRef=n,this._thenViewRef=nul...
    method ngIfElse (line 422) | set ngIfElse(n){x1(n,!1),this._elseTemplateRef=n,this._elseViewRef=nul...
    method _updateView (line 422) | _updateView(){this._context.$implicit?this._thenViewRef||(this._viewCo...
    method ngTemplateContextGuard (line 422) | static ngTemplateContextGuard(n,r){return!0}
    method constructor (line 422) | constructor(n,r,o){this._ngEl=n,this._differs=r,this._renderer=o}
    method ngStyle (line 422) | set ngStyle(n){this._ngStyle=n,!this._differ&&n&&(this._differ=this._d...
    method ngDoCheck (line 422) | ngDoCheck(){if(this._differ){let n=this._differ.diff(this._ngStyle);n&...
    method _setStyle (line 422) | _setStyle(n,r){let[o,i]=n.split("."),s=o.indexOf("-")===-1?void 0:rt.D...
    method _applyChanges (line 422) | _applyChanges(n){n.forEachRemovedItem(r=>this._setStyle(r.key,null)),n...
    method constructor (line 422) | constructor(n){this._viewContainerRef=n}
    method ngOnChanges (line 422) | ngOnChanges(n){if(this._shouldRecreateView(n)){let r=this._viewContain...
    method _getInjector (line 422) | _getInjector(){return this.ngTemplateOutletInjector==="outlet"?this.in...
    method _shouldRecreateView (line 422) | _shouldRecreateView(n){return!!n.ngTemplateOutlet||!!n.ngTemplateOutle...
    method _createContextForwardProxy (line 422) | _createContextForwardProxy(){return new Proxy({},{set:(n,r,o)=>this.ng...
    method constructor (line 422) | constructor(n){this._ref=n}
    method ngOnDestroy (line 422) | ngOnDestroy(){this._subscription&&this._dispose(),this._ref=null}
    method transform (line 422) | transform(n){if(!this._obj){if(n)try{this.markForCheckOnValueUpdate=!1...
    method _subscribe (line 422) | _subscribe(n){this._obj=n,this._strategy=this._selectStrategy(n),this....
    method _selectStrategy (line 422) | _selectStrategy(n){if(gi(n))return X2;if(Lu(n))return eT;throw J2(e,n)}
    method _dispose (line 422) | _dispose(){this._strategy.dispose(this._subscription),this._latestValu...
    method _updateLatestValue (line 422) | _updateLatestValue(n,r){n===this._obj&&(this._latestValue=r,this.markF...
    method constructor (line 422) | constructor(n){this.differs=n}
    method transform (line 422) | transform(n,r=I1){if(!n||!(n instanceof Map)&&typeof n!="object")retur...
    method constructor (line 422) | constructor(n){super(n)}
    method supports (line 422) | supports(n){return!0}
    method addEventListener (line 422) | addEventListener(n,r,o,i){return n.addEventListener(r,o,i),()=>this.re...
    method removeEventListener (line 422) | removeEventListener(n,r,o,i){return n.removeEventListener(r,o,i)}
    method constructor (line 422) | constructor(n,r){this._zone=r,n.forEach(s=>{s.manager=this});let o=n.f...
    method addEventListener (line 422) | addEventListener(n,r,o,i){return this._findPluginFor(r).addEventListen...
    method getZone (line 422) | getZone(){return this._zone}
    method _findPluginFor (line 422) | _findPluginFor(n){let r=this._eventNameToPlugin.get(n);if(r)return r;i...
    method constructor (line 422) | constructor(n,r,o,i={}){this.doc=n,this.appId=r,this.nonce=o,iT(n,r,th...
    method addStyles (line 422) | addStyles(n,r){for(let o of n)this.addUsage(o,this.inline,A1);r?.forEa...
    method removeStyles (line 422) | removeStyles(n,r){for(let o of n)this.removeUsage(o,this.inline);r?.fo...
    method addUsage (line 422) | addUsage(n,r,o){let i=r.get(n);i?i.usage++:r.set(n,{usage:1,elements:[...
    method removeUsage (line 422) | removeUsage(n,r){let o=r.get(n);o&&(o.usage--,o.usage<=0&&(M1(o.elemen...
    method ngOnDestroy (line 422) | ngOnDestroy(){for(let[,{elements:n}]of[...this.inline,...this.external...
    method addHost (line 422) | addHost(n){this.hosts.add(n);for(let[r,{elements:o}]of this.inline)o.p...
    method removeHost (line 422) | removeHost(n){this.hosts.delete(n)}
    method addElement (line 422) | addElement(n,r){return this.nonce&&r.setAttribute("nonce",this.nonce),...
    method constructor (line 422) | constructor(n,r,o,i,s,u,a=null,c=null){this.eventManager=n,this.shared...
    method createRenderer (line 422) | createRenderer(n,r){if(!n||!r)return this.defaultRenderer;let o=this.g...
    method getOrCreateRenderer (line 422) | getOrCreateRenderer(n,r){let o=this.rendererByCompId,i=o.get(r.id);if(...
    method ngOnDestroy (line 422) | ngOnDestroy(){this.rendererByCompId.clear()}
    method componentReplaced (line 422) | componentReplaced(n){this.rendererByCompId.delete(n)}
    method build (line 422) | build(){return new XMLHttpRequest}
    method constructor (line 422) | constructor(n){super(n)}
    method supports (line 422) | supports(n){return e.parseEventName(n)!=null}
    method addEventListener (line 422) | addEventListener(n,r,o,i){let s=e.parseEventName(r),u=e.eventCallback(...
    method parseEventName (line 422) | static parseEventName(n){let r=n.toLowerCase().split("."),o=r.shift();...
    method matchEventFullKeyCode (line 422) | static matchEventFullKeyCode(n,r){let o=gT[n.key]||n.key,i="";return r...
    method eventCallback (line 422) | static eventCallback(n,r,o){return i=>{e.matchEventFullKeyCode(i,n)&&o...
    method _normalizeKey (line 422) | static _normalizeKey(n){return n==="esc"?"escape":n}
    method constructor (line 422) | constructor(){}
    method constructor (line 423) | constructor(n){this.xhrFactory=n}
    method maybePropagateTrace (line 423) | maybePropagateTrace(n){return this.tracingService?.propagate?this.trac...
    method handle (line 423) | handle(n){if(n.method==="JSONP")throw new C(-2800,!1);let r=this.xhrFa...
    method constructor (line 423) | constructor(n,r){this.backend=n,this.injector=r}
    method handle (line 423) | handle(n){if(this.chain===null){let r=Array.from(new Set([...this.inje...
    method constructor (line 423) | constructor(n){this.handler=n}
    method request (line 423) | request(n,r,o={}){let i;if(n instanceof uo)i=n;else{let a;o.headers in...
    method delete (line 423) | delete(n,r={}){return this.request("DELETE",n,r)}
    method get (line 423) | get(n,r={}){return this.request("GET",n,r)}
    method head (line 423) | head(n,r={}){return this.request("HEAD",n,r)}
    method jsonp (line 423) | jsonp(n,r){return this.request("JSONP",n,{params:new zt().append(r,"JS...
    method options (line 423) | options(n,r={}){return this.request("OPTIONS",n,r)}
    method patch (line 423) | patch(n,r,o={}){return this.request("PATCH",n,yp(o,r))}
    method post (line 423) | post(n,r,o={}){return this.request("POST",n,yp(o,r))}
    method put (line 423) | put(n,r,o={}){return this.request("PUT",n,yp(o,r))}
    method getToken (line 423) | getToken(){let n=this.doc.cookie||"";return n!==this.lastCookieString&...
    method constructor (line 423) | constructor(n){this._doc=n}
    method getTitle (line 423) | getTitle(){return this._doc.title}
    method setTitle (line 423) | setTitle(n){this._doc.title=n||""}
    method constructor (line 423) | constructor(n){super(),this._doc=n}
    method sanitize (line 423) | sanitize(n,r){if(r==null)return null;switch(n){case Pe.NONE:return r;c...
    method bypassSecurityTrustHtml (line 423) | bypassSecurityTrustHtml(n){return md(n)}
    method bypassSecurityTrustStyle (line 423) | bypassSecurityTrustStyle(n){return yd(n)}
    method bypassSecurityTrustScript (line 423) | bypassSecurityTrustScript(n){return bd(n)}
    method bypassSecurityTrustUrl (line 423) | bypassSecurityTrustUrl(n){return vd(n)}
    method bypassSecurityTrustResourceUrl (line 423) | bypassSecurityTrustResourceUrl(n){return Dd(n)}
    method setData (line 438) | setData(n,r,o,i){return super.setData(n,r,o,i??void 0)}
    method dispatch (line 438) | dispatch(n){let r=new ce;return this.events.next({message:n,completion...
    method sendAction (line 438) | sendAction(n){let r=this.component(),o=this.surfaceId()??void 0,i={};i...
    method resolvePrimitive (line 438) | resolvePrimitive(n){let r=this.component(),o=this.surfaceId();return!n...
    method getUniqueId (line 438) | getUniqueId(n){return`${n}-${ZM++}`}
    method constructor (line 438) | constructor(){Yo(()=>{let o=this.surfaceId(),i=this.component();De(()=...
    method ngOnDestroy (line 438) | ngOnDestroy(){this.isDestroyed=!0,this.clear()}
    method render (line 438) | render(n,r){return lt(this,null,function*(){let o=this.catalog[r.type]...
    method clear (line 438) | clear(){this.currentRef?.destroy(),this.currentRef=null}
    method render (line 438) | render(n,r){r&&this.applyTagClassMap(r);let o=this.markdownIt.render(n...
    method applyTagClassMap (line 438) | applyTagClassMap(n){Object.entries(n).forEach(([r,o])=>{let i;switch(r...
    method unapplyTagClassMap (line 438) | unapplyTagClassMap(){for(let[n,r]of this.originalClassMap)this.markdow...
    method areHintedStyles (line 438) | areHintedStyles(n){return typeof n!="object"||!n||Array.isArray(n)?!1:...
  method constructor (line 4) | constructor(t){super(),this._lView=t}
  method destroyed (line 4) | get destroyed(){return Un(this._lView)}
  method onDestroy (line 4) | onDestroy(t){let n=this._lView;return Jc(n,t),()=>Z0(n,t)}
  function AE (line 4) | function AE(){return new bs(_())}
  class e (line 4) | class e{taskId=0;pendingTasks=new Set;destroyed=!1;pendingTask=new Co(!1...
    method constructor (line 3) | constructor(n){n&&(this._subscribe=n)}
    method lift (line 3) | lift(n){let r=new e;return r.source=this,r.operator=n,r}
    method subscribe (line 3) | subscribe(n,r,o){let i=pD(n)?n:new Ze(n,r,o);return vr(()=>{let{operat...
    method _trySubscribe (line 3) | _trySubscribe(n){try{return this._subscribe(n)}catch(r){n.error(r)}}
    method forEach (line 3) | forEach(n,r){return r=Uh(r),new r((o,i)=>{let s=new Ze({next:u=>{try{n...
    method _subscribe (line 3) | _subscribe(n){var r;return(r=this.source)===null||r===void 0?void 0:r....
    method [Dr] (line 3) | [Dr](){return this}
    method pipe (line 3) | pipe(...n){return ec(n)(this)}
    method toPromise (line 3) | toPromise(n){return n=Uh(n),new n((r,o)=>{let i;this.subscribe(s=>i=s,...
    method constructor (line 3) | constructor(){super(),this.closed=!1,this.currentObservers=null,this.o...
    method lift (line 3) | lift(n){let r=new zi(this,this);return r.operator=n,r}
    method _throwIfClosed (line 3) | _throwIfClosed(){if(this.closed)throw new qh}
    method next (line 3) | next(n){vr(()=>{if(this._throwIfClosed(),!this.isStopped){this.current...
    method error (line 3) | error(n){vr(()=>{if(this._throwIfClosed(),!this.isStopped){this.hasErr...
    method complete (line 3) | complete(){vr(()=>{if(this._throwIfClosed(),!this.isStopped){this.isSt...
    method unsubscribe (line 3) | unsubscribe(){this.isStopped=this.closed=!0,this.observers=this.curren...
    method observed (line 3) | get observed(){var n;return((n=this.observers)===null||n===void 0?void...
    method _trySubscribe (line 3) | _trySubscribe(n){return this._throwIfClosed(),super._trySubscribe(n)}
    method _subscribe (line 3) | _subscribe(n){return this._throwIfClosed(),this._checkFinalizedStatuse...
    method _innerSubscribe (line 3) | _innerSubscribe(n){let{hasError:r,isStopped:o,observers:i}=this;return...
    method _checkFinalizedStatuses (line 3) | _checkFinalizedStatuses(n){let{hasError:r,thrownError:o,isStopped:i}=t...
    method asObservable (line 3) | asObservable(){let n=new B;return n.source=this,n}
    method hasPendingTasks (line 4) | get hasPendingTasks(){return this.destroyed?!1:this.pendingTask.value}
    method hasPendingTasksObservable (line 4) | get hasPendingTasksObservable(){return this.destroyed?new B(n=>{n.next...
    method add (line 4) | add(){!this.hasPendingTasks&&!this.destroyed&&this.pendingTask.next(!0...
    method has (line 4) | has(n){return this.pendingTasks.has(n)}
    method remove (line 4) | remove(n){this.pendingTasks.delete(n),this.debugTaskTracker?.remove(n)...
    method ngOnDestroy (line 4) | ngOnDestroy(){this.pendingTasks.clear(),this.hasPendingTasks&&this.pen...
    method constructor (line 4) | constructor(n,r){this.view=n,this.node=r}
    method add (line 4) | add(){let n=this.internalPendingTasks.add();return()=>{this.internalPe...
    method run (line 4) | run(n){let r=this.add();n().catch(this.errorHandler).finally(r)}
    method constructor (line 4) | constructor(n){this.nativeElement=n}
    method execute (line 4) | execute(){this.impl?.execute()}
    method constructor (line 4) | constructor(){b(ot,{optional:!0})}
    method execute (line 4) | execute(){let n=this.sequences.size>0;n&&Y(q.AfterRenderHooksStart),th...
    method register (line 4) | register(n){let{view:r}=n;r!==void 0?((r[Hn]??=[]).push(n),zn(r),r[L]|...
    method addSequence (line 4) | addSequence(n){this.sequences.add(n),this.scheduler.notify(7)}
    method unregister (line 4) | unregister(n){this.executing&&this.sequences.has(n)?(n.erroredOrDestro...
    method maybeTrace (line 4) | maybeTrace(n,r){return r?r.run(wu.AFTER_NEXT_RENDER,n):n()}
    method constructor (line 4) | constructor(n,r,o){this._declarationLView=n,this._declarationTContaine...
    method ssrId (line 4) | get ssrId(){return this._declarationTContainer.tView?.ssrId||null}
    method createEmbeddedView (line 4) | createEmbeddedView(n,r){return this.createEmbeddedViewImpl(n,r)}
    method createEmbeddedViewImpl (line 4) | createEmbeddedViewImpl(n,r,o){let i=li(this._declarationLView,this._de...
    method constructor (line 4) | constructor(n){this._injector=n}
    method getOrCreateStandaloneInjector (line 4) | getOrCreateStandaloneInjector(n){if(!n.standalone)return null;if(!this...
    method ngOnDestroy (line 4) | ngOnDestroy(){try{for(let n of this.cachedInjectors.values())n!==null&...
    method log (line 4) | log(n){console.log(n)}
    method warn (line 4) | warn(n){console.warn(n)}
    method constructor (line 4) | constructor(n,r,o){this._ngZone=n,this.registry=r,As()&&(this._destroy...
    method _watchAngularEvents (line 4) | _watchAngularEvents(){let n=this._ngZone.onUnstable.subscribe({next:()...
    method isStable (line 4) | isStable(){return this._isZoneStable&&!this._ngZone.hasPendingMacrotasks}
    method _runCallbacksIfReady (line 4) | _runCallbacksIfReady(){if(this.isStable())queueMicrotask(()=>{for(;thi...
    method getPendingTasks (line 4) | getPendingTasks(){return this._taskTrackingZone?this._taskTrackingZone...
    method addCallback (line 4) | addCallback(n,r,o){let i=-1;r&&r>0&&(i=setTimeout(()=>{this._callbacks...
    method whenStable (line 4) | whenStable(n,r,o){if(o&&!this._taskTrackingZone)throw new Error('Task ...
    method registerApplication (line 4) | registerApplication(n){this.registry.registerApplication(n,this)}
    method unregisterApplication (line 4) | unregisterApplication(n){this.registry.unregisterApplication(n)}
    method findProviders (line 4) | findProviders(n,r,o){return[]}
    method registerApplication (line 4) | registerApplication(n,r){this._applications.set(n,r)}
    method unregisterApplication (line 4) | unregisterApplication(n){this._applications.delete(n)}
    method unregisterAllApplications (line 4) | unregisterAllApplications(){this._applications.clear()}
    method getTestability (line 4) | getTestability(n){return this._applications.get(n)||null}
    method getAllTestabilities (line 4) | getAllTestabilities(){return Array.from(this._applications.values())}
    method getAllRootElements (line 4) | getAllRootElements(){return Array.from(this._applications.keys())}
    method findTestabilityInTree (line 4) | findTestabilityInTree(n,r=!0){return Yd?.findTestabilityInTree(this,n,...
    method constructor (line 4) | constructor(){}
    method runInitializers (line 4) | runInitializers(){if(this.initialized)return;let n=[];for(let o of thi...
    method allViews (line 4) | get allViews(){return[...(this.includeAllTestViews?this.allTestViews:t...
    method destroyed (line 4) | get destroyed(){return this._destroyed}
    method isStable (line 4) | get isStable(){return this.internalPendingTask.hasPendingTasksObservab...
    method constructor (line 4) | constructor(){b(ot,{optional:!0})}
    method whenStable (line 4) | whenStable(){let n;return new Promise(r=>{n=this.isStable.subscribe({n...
    method injector (line 4) | get injector(){return this._injector}
    method bootstrap (line 4) | bootstrap(n,r){return this.bootstrapImpl(n,r)}
    method bootstrapImpl (line 4) | bootstrapImpl(n,r,o=fe.NULL){return this._injector.get(be).run(()=>{Y(...
    method tick (line 4) | tick(){this.zonelessEnabled||(this.dirtyFlags|=1),this._tick()}
    method _tick (line 4) | _tick(){Y(q.ChangeDetectionStart),this.tracingSnapshot!==null?this.tra...
    method synchronize (line 4) | synchronize(){this._rendererFactory===null&&!this._injector.destroyed&...
    method synchronizeOnce (line 4) | synchronizeOnce(){this.dirtyFlags&16&&(this.dirtyFlags&=-17,this.rootE...
    method syncDirtyFlagsWithViews (line 4) | syncDirtyFlagsWithViews(){if(this.allViews.some(({_lView:n})=>Uo(n))){...
    method attachView (line 4) | attachView(n){let r=n;this._views.push(r),r.attachToAppRef(this)}
    method detachView (line 4) | detachView(n){let r=n;Ko(this._views,r),r.detachFromAppRef()}
    method _loadComponent (line 4) | _loadComponent(n){this.attachView(n.hostView);try{this.tick()}catch(o)...
    method ngOnDestroy (line 4) | ngOnDestroy(){if(!this._destroyed)try{this._destroyListeners.forEach(n...
    method onDestroy (line 4) | onDestroy(n){return this._destroyListeners.push(n),()=>Ko(this._destro...
    method destroy (line 4) | destroy(){if(this._destroyed)throw new C(406,!1);let n=this._injector;...
    method viewCount (line 4) | get viewCount(){return this._views.length}
    method compileModuleSync (line 4) | compileModuleSync(n){return new du(n)}
    method compileModuleAsync (line 4) | compileModuleAsync(n){return Promise.resolve(this.compileModuleSync(n))}
    method compileModuleAndAllComponentsSync (line 4) | compileModuleAndAllComponentsSync(n){let r=this.compileModuleSync(n),o...
    method compileModuleAndAllComponentsAsync (line 4) | compileModuleAndAllComponentsAsync(n){return Promise.resolve(this.comp...
    method clearCache (line 4) | clearCache(){}
    method clearCacheFor (line 4) | clearCacheFor(n){}
    method getModuleId (line 4) | getModuleId(n){}
    method constructor (line 4) | constructor(){this.subscriptions.add(this.appRef.afterTick.subscribe((...
    method switchToMicrotaskScheduler (line 4) | switchToMicrotaskScheduler(){this.ngZone.runOutsideAngular(()=>{let n=...
    method notify (line 4) | notify(n){if(!this.zonelessEnabled&&n===5)return;switch(n){case 0:{thi...
    method shouldScheduleTick (line 4) | shouldScheduleTick(){return!(this.appRef.destroyed||this.pendingRender...
    method tick (line 4) | tick(){if(this.runningTick||this.appRef.destroyed)return;if(this.appRe...
    method ngOnDestroy (line 4) | ngOnDestroy(){this.subscriptions.unsubscribe(),this.cleanup()}
    method cleanup (line 4) | cleanup(){if(this.runningTick=!1,this.cancelScheduledCallback?.(),this...
    method constructor (line 4) | constructor(n){this.factories=n}
    method create (line 4) | static create(n,r){if(r!=null){let o=r.factories.slice();n=n.concat(o)...
    method extend (line 4) | static extend(n){return{provide:e,useFactory:()=>{let r=b(e,{optional:...
    method find (line 4) | find(n){let r=this.factories.find(o=>o.supports(n));if(r!=null)return ...
    method constructor (line 4) | constructor(n){this.factories=n}
    method create (line 4) | static create(n,r){if(r){let o=r.factories.slice();n=n.concat(o)}retur...
    method extend (line 4) | static extend(n){return{provide:e,useFactory:()=>{let r=b(e,{optional:...
    method find (line 4) | find(n){let r=this.factories.find(o=>o.supports(n));if(r)return r;thro...
    method constructor (line 4) | constructor(n){}
    method constructor (line 422) | constructor(n={mapCtor:Map,arrayCtor:Array,setCtor:Set,objCtor:Object}...
    method getSurfaces (line 422) | getSurfaces(){return this.surfaces}
    method clearSurfaces (line 422) | clearSurfaces(){this.surfaces.clear()}
    method processMessages (line 422) | processMessages(n){for(let r of n)r.beginRendering&&this.handleBeginRe...
    method getData (line 422) | getData(n,r,o=e.DEFAULT_SURFACE_ID){let i=this.getOrCreateSurface(o);i...
    method setData (line 422) | setData(n,r,o,i=e.DEFAULT_SURFACE_ID){if(!n){console.warn("No componen...
    method resolvePath (line 422) | resolvePath(n,r){return n.startsWith("/")?n:r&&r!=="/"?r.endsWith("/")...
    method parseIfJsonString (line 422) | parseIfJsonString(n){if(typeof n!="string")return n;let r=n.trim();if(...
    method convertKeyValueArrayToMap (line 422) | convertKeyValueArrayToMap(n){let r=new this.mapCtor;for(let o of n){if...
    method setDataByPath (line 422) | setDataByPath(n,r,o){if(Array.isArray(o)&&(o.length===0||$(o[0])&&"key...
    method normalizePath (line 422) | normalizePath(n){return"/"+n.replace(/\[(\d+)\]/g,".$1").split(".").fi...
    method getDataByPath (line 422) | getDataByPath(n,r){let o=this.normalizePath(r).split("/").filter(s=>s)...
    method getOrCreateSurface (line 422) | getOrCreateSurface(n){let r=this.surfaces.get(n);return r||(r=new this...
    method handleBeginRendering (line 422) | handleBeginRendering(n,r){let o=this.getOrCreateSurface(r);o.rootCompo...
    method handleSurfaceUpdate (line 422) | handleSurfaceUpdate(n,r){let o=this.getOrCreateSurface(r);for(let i of...
    method handleDataModelUpdate (line 422) | handleDataModelUpdate(n,r){let o=this.getOrCreateSurface(r),i=n.path??...
    method handleDeleteSurface (line 422) | handleDeleteSurface(n){this.surfaces.delete(n.surfaceId)}
    method rebuildComponentTree (line 422) | rebuildComponentTree(n){if(!n.rootComponentId){n.componentTree=null;re...
    method findValueKey (line 422) | findValueKey(n){return Object.keys(n).find(r=>r.startsWith("value"))}
    method buildNodeRecursive (line 422) | buildNodeRecursive(n,r,o,i,s=""){let u=`${n}${s}`,{components:a}=r;if(...
    method resolvePropertyValue (line 422) | resolvePropertyValue(n,r,o,i,s=""){if(typeof n=="string"&&r.components...
    method historyGo (line 422) | historyGo(n){throw new Error("")}
    method constructor (line 422) | constructor(){super(),this._location=window.location,this._history=win...
    method getBaseHrefFromDOM (line 422) | getBaseHrefFromDOM(){return _t().getBaseHref(this._doc)}
    method onPopState (line 422) | onPopState(n){let r=_t().getGlobalEventTarget(this._doc,"window");retu...
    method onHashChange (line 422) | onHashChange(n){let r=_t().getGlobalEventTarget(this._doc,"window");re...
    method href (line 422) | get href(){return this._location.href}
    method protocol (line 422) | get protocol(){return this._location.protocol}
    method hostname (line 422) | get hostname(){return this._location.hostname}
    method port (line 422) | get port(){return this._location.port}
    method pathname (line 422) | get pathname(){return this._location.pathname}
    method search (line 422) | get search(){return this._location.search}
    method hash (line 422) | get hash(){return this._location.hash}
    method pathname (line 422) | set pathname(n){this._location.pathname=n}
    method pushState (line 422) | pushState(n,r,o){this._history.pushState(n,r,o)}
    method replaceState (line 422) | replaceState(n,r,o){this._history.replaceState(n,r,o)}
    method forward (line 422) | forward(){this._history.forward()}
    method back (line 422) | back(){this._history.back()}
    method historyGo (line 422) | historyGo(n=0){this._history.go(n)}
    method getState (line 422) | getState(){return this._history.state}
    method historyGo (line 422) | historyGo(n){throw new Error("")}
    method constructor (line 422) | constructor(n,r){super(),this._platformLocation=n,this._baseHref=r??th...
    method ngOnDestroy (line 422) | ngOnDestroy(){for(;this._removeListenerFns.length;)this._removeListene...
    method onPopState (line 422) | onPopState(n){this._removeListenerFns.push(this._platformLocation.onPo...
    method getBaseHref (line 422) | getBaseHref(){return this._baseHref}
    method prepareExternalUrl (line 422) | prepareExternalUrl(n){return aa(this._baseHref,n)}
    method path (line 422) | path(n=!1){let r=this._platformLocation.pathname+ut(this._platformLoca...
    method pushState (line 422) | pushState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i));this._platfo...
    method replaceState (line 422) | replaceState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i));this._pla...
    method forward (line 422) | forward(){this._platformLocation.forward()}
    method back (line 422) | back(){this._platformLocation.back()}
    method getState (line 422) | getState(){return this._platformLocation.getState()}
    method historyGo (line 422) | historyGo(n=0){this._platformLocation.historyGo?.(n)}
    method constructor (line 422) | constructor(n){this._locationStrategy=n;let r=this._locationStrategy.g...
    method ngOnDestroy (line 422) | ngOnDestroy(){this._urlChangeSubscription?.unsubscribe(),this._urlChan...
    method path (line 422) | path(n=!1){return this.normalize(this._locationStrategy.path(n))}
    method getState (line 422) | getState(){return this._locationStrategy.getState()}
    method isCurrentPathEqualTo (line 422) | isCurrentPathEqualTo(n,r=""){return this.path()==this.normalize(n+ut(r))}
    method normalize (line 422) | normalize(n){return e.stripTrailingSlash(U2(this._basePath,D1(n)))}
    method prepareExternalUrl (line 422) | prepareExternalUrl(n){return n&&n[0]!=="/"&&(n="/"+n),this._locationSt...
    method go (line 422) | go(n,r="",o=null){this._locationStrategy.pushState(o,"",n,r),this._not...
    method replaceState (line 422) | replaceState(n,r="",o=null){this._locationStrategy.replaceState(o,"",n...
    method forward (line 422) | forward(){this._locationStrategy.forward()}
    method back (line 422) | back(){this._locationStrategy.back()}
    method historyGo (line 422) | historyGo(n=0){this._locationStrategy.historyGo?.(n)}
    method onUrlChange (line 422) | onUrlChange(n){return this._urlChangeListeners.push(n),this._urlChange...
    method _notifyUrlChangeListeners (line 422) | _notifyUrlChangeListeners(n="",r){this._urlChangeListeners.forEach(o=>...
    method subscribe (line 422) | subscribe(n,r,o){return this._subject.subscribe({next:n,error:r??void ...
    method constructor (line 422) | constructor(n,r){super(),this._platformLocation=n,r!=null&&(this._base...
    method ngOnDestroy (line 422) | ngOnDestroy(){for(;this._removeListenerFns.length;)this._removeListene...
    method onPopState (line 422) | onPopState(n){this._removeListenerFns.push(this._platformLocation.onPo...
    method getBaseHref (line 422) | getBaseHref(){return this._baseHref}
    method path (line 422) | path(n=!1){let r=this._platformLocation.hash??"#";return r.length>0?r....
    method prepareExternalUrl (line 422) | prepareExternalUrl(n){let r=aa(this._baseHref,n);return r.length>0?"#"...
    method pushState (line 422) | pushState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i))||this._platf...
    method replaceState (line 422) | replaceState(n,r,o,i){let s=this.prepareExternalUrl(o+ut(i))||this._pl...
    method forward (line 422) | forward(){this._platformLocation.forward()}
    method back (line 422) | back(){this._platformLocation.back()}
    method getState (line 422) | getState(){return this._platformLocation.getState()}
    method historyGo (line 422) | historyGo(n=0){this._platformLocation.historyGo?.(n)}
    method constructor (line 422) | constructor(n,r){this._ngEl=n,this._renderer=r}
    method klass (line 422) | set klass(n){this.initialClasses=n!=null?n.trim().split(op):_1}
    method ngClass (line 422) | set ngClass(n){this.rawClass=typeof n=="string"?n.trim().split(op):n}
    method ngDoCheck (line 422) | ngDoCheck(){for(let r of this.initialClasses)this._updateState(r,!0);l...
    method _updateState (line 422) | _updateState(n,r){let o=this.stateMap.get(n);o!==void 0?(o.enabled!==r...
    method _applyStateDiff (line 422) | _applyStateDiff(){for(let n of this.stateMap){let r=n[0],o=n[1];o.chan...
    method _toggleClass (line 422) | _toggleClass(n,r){n=n.trim(),n.length>0&&n.split(op).forEach(o=>{r?thi...
    method componentInstance (line 422) | get componentInstance(){return this._componentRef?.instance??null}
    method constructor (line 422) | constructor(n){this._viewContainerRef=n}
    method _needToReCreateNgModuleInstance (line 422) | _needToReCreateNgModuleInstance(n){return n.ngComponentOutletNgModule!...
    method _needToReCreateComponentInstance (line 422) | _needToReCreateComponentInstance(n){return n.ngComponentOutlet!==void ...
    method ngOnChanges (line 422) | ngOnChanges(n){if(this._needToReCreateComponentInstance(n)&&(this._vie...
    method ngDoCheck (line 422) | ngDoCheck(){if(this._componentRef){if(this.ngComponentOutletInputs)for...
    method ngOnDestroy (line 422) | ngOnDestroy(){this._moduleRef?.destroy()}
    method _applyInputStateDiff (line 422) | _applyInputStateDiff(n){for(let[r,o]of this._inputsUsed)o?(n.setInput(...
    method ngForOf (line 422) | set ngForOf(n){this._ngForOf=n,this._ngForOfDirty=!0}
    method ngForTrackBy (line 422) | set ngForTrackBy(n){this._trackByFn=n}
    method ngForTrackBy (line 422) | get ngForTrackBy(){return this._trackByFn}
    method constructor (line 422) | constructor(n,r,o){this._viewContainer=n,this._template=r,this._differ...
    method ngForTemplate (line 422) | set ngForTemplate(n){n&&(this._template=n)}
    method ngDoCheck (line 422) | ngDoCheck(){if(this._ngForOfDirty){this._ngForOfDirty=!1;let n=this._n...
    method _applyChanges (line 422) | _applyChanges(n){let r=this._viewContainer;n.forEachOperation((o,i,s)=...
    method ngTemplateContextGuard (line 422) | static ngTemplateContextGuard(n,r){return!0}
    method constructor (line 422) | constructor(n,r){this._viewContainer=n,this._thenTemplateRef=r}
    method ngIf (line 422) | set ngIf(n){this._context.$implicit=this._context.ngIf=n,this._updateV...
    method ngIfThen (line 422) | set ngIfThen(n){x1(n,!1),this._thenTemplateRef=n,this._thenViewRef=nul...
    method ngIfElse (line 422) | set ngIfElse(n){x1(n,!1),this._elseTemplateRef=n,this._elseViewRef=nul...
    method _updateView (line 422) | _updateView(){this._context.$implicit?this._thenViewRef||(this._viewCo...
    method ngTemplateContextGuard (line 422) | static ngTemplateContextGuard(n,r){return!0}
    method constructor (line 422) | constructor(n,r,o){this._ngEl=n,this._differs=r,this._renderer=o}
    method ngStyle (line 422) | set ngStyle(n){this._ngStyle=n,!this._differ&&n&&(this._differ=this._d...
    method ngDoCheck (line 422) | ngDoCheck(){if(this._differ){let n=this._differ.diff(this._ngStyle);n&...
    method _setStyle (line 422) | _setStyle(n,r){let[o,i]=n.split("."),s=o.indexOf("-")===-1?void 0:rt.D...
    method _applyChanges (line 422) | _applyChanges(n){n.forEachRemovedItem(r=>this._setStyle(r.key,null)),n...
    method constructor (line 422) | constructor(n){this._viewContainerRef=n}
    method ngOnChanges (line 422) | ngOnChanges(n){if(this._shouldRecreateView(n)){let r=this._viewContain...
    method _getInjector (line 422) | _getInjector(){return this.ngTemplateOutletInjector==="outlet"?this.in...
    method _shouldRecreateView (line 422) | _shouldRecreateView(n){return!!n.ngTemplateOutlet||!!n.ngTemplateOutle...
    method _createContextForwardProxy (line 422) | _createContextForwardProxy(){return new Proxy({},{set:(n,r,o)=>this.ng...
    method constructor (line 422) | constructor(n){this._ref=n}
    method ngOnDestroy (line 422) | ngOnDestroy(){this._subscription&&this._dispose(),this._ref=null}
    method transform (line 422) | transform(n){if(!this._obj){if(n)try{this.markForCheckOnValueUpdate=!1...
    method _subscribe (line 422) | _subscribe(n){this._obj=n,this._strategy=this._selectStrategy(n),this....
    method _selectStrategy (line 422) | _selectStrategy(n){if(gi(n))return X2;if(Lu(n))return eT;throw J2(e,n)}
    method _dispose (line 422) | _dispose(){this._strategy.dispose(this._subscription),this._latestValu...
    method _updateLatestValue (line 422) | _updateLatestValue(n,r){n===this._obj&&(this._latestValue=r,this.markF...
    method constructor (line 422) | constructor(n){this.differs=n}
    method transform (line 422) | transform(n,r=I1){if(!n||!(n instanceof Map)&&typeof n!="object")retur...
    method constructor (line 422) | constructor(n){super(n)}
    method supports (line 422) | supports(n){return!0}
    method addEventListener (line 422) | addEventListener(n,r,o,i){return n.addEventListener(r,o,i),()=>this.re...
    method removeEventListener (line 422) | removeEventListener(n,r,o,i){return n.removeEventListener(r,o,i)}
    method constructor (line 422) | constructor(n,r){this._zone=r,n.forEach(s=>{s.manager=this});let o=n.f...
    method addEventListener (line 422) | addEventListener(n,r,o,i){return this._findPluginFor(r).addEventListen...
    method getZone (line 422) | getZone(){return this._zone}
    method _findPluginFor (line 422) | _findPluginFor(n){let r=this._eventNameToPlugin.get(n);if(r)return r;i...
    method constructor (line 422) | constructor(n,r,o,i={}){this.doc=n,this.appId=r,this.nonce=o,iT(n,r,th...
    method addStyles (line 422) | addStyles(n,r){for(let o of n)this.addUsage(o,this.inline,A1);r?.forEa...
    method removeStyles (line 422) | removeStyles(n,r){for(let o of n)this.removeUsage(o,this.inline);r?.fo...
    method addUsage (line 422) | addUsage(n,r,o){let i=r.get(n);i?i.usage++:r.set(n,{usage:1,elements:[...
    method removeUsage (line 422) | removeUsage(n,r){let o=r.get(n);o&&(o.usage--,o.usage<=0&&(M1(o.elemen...
    method ngOnDestroy (line 422) | ngOnDestroy(){for(let[,{elements:n}]of[...this.inline,...this.external...
    method addHost (line 422) | addHost(n){this.hosts.add(n);for(let[r,{elements:o}]of this.inline)o.p...
    method removeHost (line 422) | removeHost(n){this.hosts.delete(n)}
    method addElement (line 422) | addElement(n,r){return this.nonce&&r.setAttribute("nonce",this.nonce),...
    method constructor (line 422) | constructor(n,r,o,i,s,u,a=null,c=null){this.eventManager=n,this.shared...
    method createRenderer (line 422) | createRenderer(n,r){if(!n||!r)return this.defaultRenderer;let o=this.g...
    method getOrCreateRenderer (line 422) | getOrCreateRenderer(n,r){let o=this.rendererByCompId,i=o.get(r.id);if(...
    method ngOnDestroy (line 422) | ngOnDestroy(){this.rendererByCompId.clear()}
    method componentReplaced (line 422) | componentReplaced(n){this.rendererByCompId.delete(n)}
    method build (line 422) | build(){return new XMLHttpRequest}
    method constructor (line 422) | constructor(n){super(n)}
    method supports (line 422) | supports(n){return e.parseEventName(n)!=null}
    method addEventListener (line 422) | addEventListener(n,r,o,i){let s=e.parseEventName(r),u=e.eventCallback(...
    method parseEventName (line 422) | static parseEventName(n){let r=n.toLowerCase().split("."),o=r.shift();...
    method matchEventFullKeyCode (line 422) | static matchEventFullKeyCode(n,r){let o=gT[n.key]||n.key,i="";return r...
    method eventCallback (line 422) | static eventCallback(n,r,o){return i=>{e.matchEventFullKeyCode(i,n)&&o...
    method _normalizeKey (line 422) | static _normalizeKey(n){return n==="esc"?"escape":n}
    method constructor (line 422) | constructor(){}
    method constructor (line 423) | constructor(n){this.xhrFactory=n}
    method maybePropagateTrace (line 423) | maybePropagateTrace(n){return this.tracingService?.propagate?this.trac...
    method handle (line 423) | handle(n){if(n.method==="JSONP")throw new C(-2800,!1);let r=this.xhrFa...
    method constructor (line 423) | constructor(n,r){this.backend=n,this.injector=r}
    method handle (line 423) | handle(n){if(this.chain===null){let r=Array.from(new Set([...this.inje...
    method constructor (line 423) | constructor(n){this.handler=n}
    method request (line 423) | request(n,r,o={}){let i;if(n instanceof uo)i=n;else{let a;o.headers in...
    method delete (line 423) | delete(n,r={}){return this.request("DELETE",n,r)}
    method get (line 423) | get(n,r={}){return this.request("GET",n,r)}
    method head (line 423) | head(n,r={}){return this.request("HEAD",n,r)}
    method jsonp (line 423) | jsonp(n,r){return this.request("JSONP",n,{params:new zt().append(r,"JS...
    method options (line 423) | options(n,r={}){return this.request("OPTIONS",n,r)}
    method patch (line 423) | patch(n,r,o={}){return this.request("PATCH",n,yp(o,r))}
    method post (line 423) | post(n,r,o={}){return this.request("POST",n,yp(o,r))}
    method put (line 423) | put(n,r,o={}){return this.request("PUT",n,yp(o,r))}
    method getToken (line 423) | getToken(){let n=this.doc.cookie||"";return n!==this.lastCookieString&...
    method constructor (line 423) | constructor(n){this._doc=n}
    method getTitle (line 423) | getTitle(){return this._doc.title}
    method setTitle (line 423) | setTitle(n){this._doc.title=n||""}
    method constructor (line 423) | constructor(n){super(),this._doc=n}
    method sanitize (line 423) | sanitize(n,r){if(r==null)return null;switch(n){case Pe.NONE:return r;c...
    method bypassSecurityTrustHtml (line 423) | bypassSecurityTrustHtml(n){return md(n)}
    method bypassSecurityTrustStyle (line 423) | bypassSecurityTrustStyle(n){return yd(n)}
    method bypassSecurityTrustScript (line 423) | bypassSecurityTrustScript(n){return bd(n)}
    method bypassSecurityTrustUrl (line 423) | bypassSecurityTrustUrl(n){return vd(n)}
    method bypassSecurityTrustResourceUrl (line 423) | bypassSecurityTrustResourceUrl(n){return Dd(n)}
    method setData (line 438) | setData(n,r,o,i){return super.setData(n,r,o,i??void 0)}
    method dispatch (line 438) | dispatch(n){let r=new ce;return this.events.next({message:n,completion...
    method sendAction (line 438) | sendAction(n){let r=this.component(),o=this.surfaceId()??void 0,i={};i...
    method resolvePrimitive (line 438) | resolvePrimitive(n){let r=this.component(),o=this.surfaceId();return!n...
    method getUniqueId (line 438) | getUniqueId(n){return`${n}-${ZM++}`}
    method constructor (line 438) | constructor(){Yo(()=>{let o=this.surfaceId(),i=this.component();De(()=...
    method ngOnDestroy (line 438) | ngOnDestroy(){this.isDestroyed=!0,this.clear()}
    method render (line 438) | render(n,r){return lt(this,null,function*(){let o=this.catalog[r.type]...
    method clear (line 438) | clear(){this.currentRef?.destroy(),this.currentRef=null}
    method render (line 438) | render(n,r){r&&this.applyTagClassMap(r);let o=this.markdownIt.render(n...
    method applyTagClassMap (line 438) | applyTagClassMap(n){Object.entries(n).forEach(([r,o])=>{let i;switch(r...
    method unapplyTagClassMap (line 438) | unapplyTagClassMap(){for(let[n,r]of this.originalClassMap)this.markdow...
    method areHintedStyles (line 438) | areHintedStyles(n){return typeof n!="object"||!n||Array.isArray(n)?!1:...
  method constructor (line 4) | constructor(t=!1){super(),this.__isAsync=t,As()&&(this.destroyRef=b(Fe,{...
  method emit (line 4) | emit(t){let n=I(null);try{super.next(t)}finally{I(n)}}
  method subscribe (line 4) | subscribe(t,n,r){let o=t,i=n||(()=>null),s=r;if(t&&typeof t=="object"){l...
  method wrapInTimeout (line 4) | wrapInTimeout(t){return n=>{let r=this.pendingTasks?.add();setTimeout(()...
  function vs (line 4) | function vs(...e){}
  function hl (line 4) | function hl(e){let t,n;function r(){e=vs;try{n!==void 0&&typeof cancelAn...
  function mg (line 4) | function mg(e){return queueMicrotask(()=>e()),()=>{e=vs}}
  method constructor (line 4) | constructor(t){let{enableLongStackTrace:n=!1,shouldCoalesceEventChangeDe...
  method isInAngularZone (line 4) | static isInAngularZone(){return typeof Zone<"u"&&Zone.current.get(gl)===!0}
  method assertInAngularZone (line 4) | static assertInAngularZone(){if(!e.isInAngularZone())throw new C(909,!1)}
  method assertNotInAngularZone (line 4) | static assertNotInAngularZone(){if(e.isInAngularZone())throw new C(909,!1)}
  method run (line 4) | run(t,n,r){return this._inner.run(t,n,r)}
  method runTask (line 4) | runTask(t,n,r,o){let i=this._inner,s=i.scheduleEventTask("NgZoneEvent: "...
  method runGuarded (line 4) | runGuarded(t,n,r){return this._inner.runGuarded(t,n,r)}
  method runOutsideAngular (line 4) | runOutsideAngular(t){return this._outer.run(t)}
  function ml (line 4) | function ml(e){if(e._nesting==0&&!e.hasPendingMicrotasks&&!e.isStable)tr...
  function RE (line 4) | function RE(e){if(e.isCheckStableRunning||e.callbackScheduled)return;e.c...
  function FE (line 4
Condensed preview — 374 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (7,239K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1817,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n** Please make "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 1469,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n** P"
  },
  {
    "path": ".github/actions/setup/action.yml",
    "chars": 757,
    "preview": "name: Setup\ndescription: Setup the environment\n\noutputs:\n  go-version:\n    description: 'Go version'\n    value: ${{ step"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 1730,
    "preview": "**Please ensure you have read the [contribution guide](./CONTRIBUTING.md) before creating a pull request.**\n\n### Link to"
  },
  {
    "path": ".github/workflows/go.yml",
    "chars": 1245,
    "preview": "# This workflow will build a golang project\n# For more information see: \n# - https://docs.github.com/en/actions/automati"
  },
  {
    "path": ".github/workflows/nightly.yml",
    "chars": 627,
    "preview": "name: Nightly\n\non:\n  schedule:\n    - cron: '0 2 * * *'  # 2 AM UTC daily\n\n  workflow_dispatch:\n\njobs:\n  test:\n    runs-o"
  },
  {
    "path": ".gitignore",
    "chars": 434,
    "preview": "# .gitignore is restricted to the artifacts produced by go build and test.\n# for personal setup you can use personal .gi"
  },
  {
    "path": ".golangci.yml",
    "chars": 1580,
    "preview": "version: \"2\"\n\nformatters:\n  enable:\n    - goimports\n    - gofumpt\n\n  settings:\n    goimports:\n      local-prefixes:\n    "
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 5700,
    "preview": "# How to contribute\n\nWe'd love to accept your patches and contributions to this project.\n\n-   [How to contribute](#how-t"
  },
  {
    "path": "LICENSE",
    "chars": 11341,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "README.md",
    "chars": 2887,
    "preview": "# Agent Development Kit (ADK) for Go\n\n[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)\n[!"
  },
  {
    "path": "agent/agent.go",
    "chars": 14418,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/agent_test.go",
    "chars": 7893,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/context.go",
    "chars": 3822,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/doc.go",
    "chars": 664,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/llmagent/doc.go",
    "chars": 854,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/llmagent/llmagent.go",
    "chars": 17595,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/llmagent/llmagent_saveoutput_test.go",
    "chars": 4530,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/llmagent/llmagent_test.go",
    "chars": 38430,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/llmagent/state_agent_test.go",
    "chars": 21421,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/llmagent/testdata/TestFunctionTool.httprr",
    "chars": 4625,
    "preview": "httprr trace v1\n980 1354\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent H"
  },
  {
    "path": "agent/llmagent/testdata/TestLLMAgentStreamingModeSSE.httprr",
    "chars": 9617,
    "preview": "httprr trace v1\n648 8944\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateCon"
  },
  {
    "path": "agent/llmagent/testdata/TestLLMAgent_healthy_backend.httprr",
    "chars": 1487,
    "preview": "httprr trace v1\n618 845\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent HT"
  },
  {
    "path": "agent/llmagent/testdata/TestToolCallback_after_callback_response_used.httprr",
    "chars": 5038,
    "preview": "httprr trace v1\n976 1549\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent H"
  },
  {
    "path": "agent/llmagent/testdata/TestToolCallback_after_callback_returned_when_used_with_before_callback.httprr",
    "chars": 4782,
    "preview": "httprr trace v1\n976 1421\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent H"
  },
  {
    "path": "agent/llmagent/testdata/TestToolCallback_before_callback_response_used.httprr",
    "chars": 4758,
    "preview": "httprr trace v1\n976 1409\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent H"
  },
  {
    "path": "agent/llmagent/testdata/TestToolCallback_both_callbacks_return_nil_actual_tool_is_executed.httprr",
    "chars": 5069,
    "preview": "httprr trace v1\n976 1566\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent H"
  },
  {
    "path": "agent/llmagent/testdata/TestToolCallback_extra_after_callback_skipped.httprr",
    "chars": 4926,
    "preview": "httprr trace v1\n976 1493\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent H"
  },
  {
    "path": "agent/llmagent/testdata/TestToolCallback_extra_before_callback_skipped.httprr",
    "chars": 4799,
    "preview": "httprr trace v1\n976 1430\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent H"
  },
  {
    "path": "agent/loader.go",
    "chars": 3297,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/loader_test.go",
    "chars": 2290,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/remoteagent/a2a_agent.go",
    "chars": 12779,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/remoteagent/a2a_agent_run_processor.go",
    "chars": 8317,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/remoteagent/a2a_agent_run_processor_test.go",
    "chars": 10919,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/remoteagent/a2a_agent_test.go",
    "chars": 49850,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/remoteagent/a2a_e2e_test.go",
    "chars": 43039,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/remoteagent/doc.go",
    "chars": 666,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/remoteagent/testdata/TestA2ARemoteAgentStreamingGeminiError.httprr",
    "chars": 7451,
    "preview": "httprr trace v1\n501 6929\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateCon"
  },
  {
    "path": "agent/remoteagent/testdata/TestA2ARemoteAgentStreamingGeminiSuccess.httprr",
    "chars": 6802,
    "preview": "httprr trace v1\n501 6279\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateCon"
  },
  {
    "path": "agent/remoteagent/testdata/TestA2ASingleHopFinalResponse_llm_mid-response_error.httprr",
    "chars": 1804,
    "preview": "httprr trace v1\n499 1280\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateCon"
  },
  {
    "path": "agent/remoteagent/testdata/TestA2ASingleHopFinalResponse_llm_mid-response_error_response.httprr",
    "chars": 2709,
    "preview": "httprr trace v1\n499 2185\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateCon"
  },
  {
    "path": "agent/remoteagent/utils.go",
    "chars": 5321,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/remoteagent/utils_test.go",
    "chars": 10465,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/run_config.go",
    "chars": 1296,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/workflowagents/loopagent/agent.go",
    "chars": 2851,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/workflowagents/loopagent/agent_test.go",
    "chars": 9895,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/workflowagents/parallelagent/agent.go",
    "chars": 4210,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/workflowagents/parallelagent/agent_test.go",
    "chars": 14066,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/workflowagents/parallelagent/testdata/TestParallelAgentWithTools_agent1.httprr",
    "chars": 5481,
    "preview": "httprr trace v1\n1127 1361\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent "
  },
  {
    "path": "agent/workflowagents/parallelagent/testdata/TestParallelAgentWithTools_agent2.httprr",
    "chars": 5442,
    "preview": "httprr trace v1\n1127 1537\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent "
  },
  {
    "path": "agent/workflowagents/sequentialagent/agent.go",
    "chars": 2331,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "agent/workflowagents/sequentialagent/agent_test.go",
    "chars": 9710,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "artifact/artifact_key_test.go",
    "chars": 1062,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "artifact/gcsartifact/gcs_client.go",
    "chars": 4691,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "artifact/gcsartifact/gcs_test.go",
    "chars": 5604,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "artifact/gcsartifact/service.go",
    "chars": 11793,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "artifact/inmemory.go",
    "chars": 9208,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "artifact/inmemory_test.go",
    "chars": 923,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "artifact/request_validation_test.go",
    "chars": 10240,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "artifact/service.go",
    "chars": 8425,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/adkgo/adkgo.go",
    "chars": 824,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/adkgo/internal/deploy/cloudrun/cloudrun.go",
    "chars": 9672,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/adkgo/internal/deploy/deploy.go",
    "chars": 1124,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/adkgo/internal/root/root.go",
    "chars": 1127,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/internal/adkcli/main.go",
    "chars": 3657,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/launcher/console/console.go",
    "chars": 8035,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/launcher/full/full.go",
    "chars": 1265,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/launcher/internal/telemetry/telemetry.go",
    "chars": 1277,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/launcher/launcher.go",
    "chars": 2570,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/launcher/prod/prod.go",
    "chars": 1244,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/launcher/universal/universal.go",
    "chars": 4702,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/launcher/web/a2a/a2a.go",
    "chars": 4321,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/launcher/web/a2a/a2a_test.go",
    "chars": 3759,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/launcher/web/api/api.go",
    "chars": 5407,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/launcher/web/web.go",
    "chars": 9532,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "cmd/launcher/web/webui/distr/assets/audio-processor.js",
    "chars": 1769,
    "preview": "/**\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
  },
  {
    "path": "cmd/launcher/web/webui/distr/assets/config/runtime-config.json",
    "chars": 22,
    "preview": "{\n  \"backendUrl\": \"\"\n}"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-2FK4DXD6.js",
    "chars": 1076,
    "preview": "import{$a as c,Ca as o,Fb as h,Kb as y,Pa as a,Xb as C,Yb as g,db as d,lc as v,ld as _,md as w,tb as s,ub as l,vb as p,w"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-4ZK7FQPX.js",
    "chars": 967,
    "preview": "import{$a as s,Ab as m,Ac as I,Bb as d,Ca as a,Kb as p,Pa as i,Xb as u,Yb as v,Zb as f,_b as y,db as r,fc as g,gc as h,h"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-7TJPJFPQ.js",
    "chars": 432634,
    "preview": "import{a as M,b as P,e as pr,g as lt}from\"./chunk-W7GRJBO5.js\";var me=null,Li=!1,Ha=1,tD=null,ne=Symbol(\"SIGNAL\");functi"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-ABUNXR7C.js",
    "chars": 955,
    "preview": "import{$a as r,Ac as h,Ca as o,Fb as u,Ib as p,Pa as a,Xb as m,Yb as f,db as c,ld as y,md as g,wb as s,xb as l,yb as d}f"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-BWOBGCSA.js",
    "chars": 1221,
    "preview": "import{$a as m,Ab as g,Ac as r,Bb as p,Ca as a,Cb as v,Hb as h,Kb as f,Lc as D,Ma as l,Pa as o,Xb as y,Yb as x,db as d,f"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-C7MGZAFQ.js",
    "chars": 626,
    "preview": "import{$a as r,Ca as o,Cb as d,Xb as l,Yb as s,db as a,ld as m}from\"./chunk-7TJPJFPQ.js\";import\"./chunk-W7GRJBO5.js\";var"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-CZPJTTNC.js",
    "chars": 1576,
    "preview": "import{$a as s,$b as f,Ab as r,Ac as n,Bb as u,Ca as m,Hb as d,Jb as c,Pa as l,Xb as v,Yb as o,Zb as g,db as p,ld as b,u"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-GLGRLUIJ.js",
    "chars": 18656,
    "preview": "import\"./chunk-W7GRJBO5.js\";var O=function(l,i){if(!(l instanceof i))throw new TypeError(\"Cannot call a class as a funct"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-JFJZPIJV.js",
    "chars": 2147,
    "preview": "import{$a as f,Ab as s,Ac as l,Bb as m,Ca as g,Hb as d,Jb as y,Pa as u,Xb as T,Yb as r,Zb as I,_b as M,db as D,ld as N,n"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-JOTH6MSK.js",
    "chars": 1438,
    "preview": "import{$a as s,Ac as _,Ca as o,Fb as u,Kb as g,Pa as r,Xb as y,Yb as C,db as c,ld as M,md as v,nb as a,tb as d,ub as l,v"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-KPALJACC.js",
    "chars": 1894,
    "preview": "import{$a as c,Ab as l,Ac as r,Bb as d,Ca as m,Hb as p,Jb as g,Kb as h,Pa as o,Xb as x,Yb as a,Zb as y,_b as M,db as b,f"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-P66EZ4FO.js",
    "chars": 2267,
    "preview": "import{$a as C,Aa as f,Bc as k,Fb as m,Gb as p,Ib as d,Kb as o,Pa as r,Sb as w,Tb as v,Xb as y,Yb as u,Zb as D,db as M,l"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-POBF2O3Z.js",
    "chars": 1059,
    "preview": "import{$a as d,Ab as m,Ac as _,Bb as u,Ca as r,Cb as p,Hb as v,Kb as f,Ma as l,Pa as n,Xb as y,Yb as g,db as s,fc as h,g"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-QWN7CXIU.js",
    "chars": 1489,
    "preview": "import{$a as p,Ab as l,Ac as c,Bb as r,Ca as m,Hb as d,Jb as h,Pa as o,Xb as v,Yb as a,Zb as g,_b as b,db as u,ld as f,u"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-QZL3KUOO.js",
    "chars": 1061,
    "preview": "import{$a as l,Ab as c,Ac as M,Bb as u,Ca as r,Cb as m,Hb as p,Kb as v,Pa as n,Xb as f,Yb as y,db as d,fc as g,gc as h,h"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-R2V2IE5A.js",
    "chars": 1620,
    "preview": "import{$a as f,$b as D,Ac as w,Ca as _,Fb as I,Gb as g,Ib as T,Kb as c,Lc as E,Pa as a,Xb as C,Yb as r,Zb as M,db as h,f"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-W7GRJBO5.js",
    "chars": 1866,
    "preview": "var q=Object.create;var k=Object.defineProperty,r=Object.defineProperties,s=Object.getOwnPropertyDescriptor,t=Object.get"
  },
  {
    "path": "cmd/launcher/web/webui/distr/chunk-YQ6GIDJJ.js",
    "chars": 1789,
    "preview": "import{$a as h,Ab as l,Ac as c,Bb as a,Ca as m,Hb as r,Jb as M,Kb as C,Pa as n,Xb as y,Yb as s,Zb as d,_b as u,db as v,l"
  },
  {
    "path": "cmd/launcher/web/webui/distr/index.html",
    "chars": 46190,
    "preview": "<!doctype html>\n<!--\n Copyright 2025 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you m"
  },
  {
    "path": "cmd/launcher/web/webui/distr/main-ORIYWHAC.js",
    "chars": 4107683,
    "preview": "import{$ as xC,$a as kA,$b as Fe,$c as y0,A as fc,Aa as pa,Ab as ti,Ac as nt,B as cf,Ba as ei,Bb as Ii,Bc as Xo,C as mc,"
  },
  {
    "path": "cmd/launcher/web/webui/distr/polyfills-5CFQRCPP.js",
    "chars": 34585,
    "preview": "var ce=globalThis;function te(t){return(ce.__Zone_symbol_prefix||\"__zone_symbol__\")+t}function ht(){let t=ce.performance"
  },
  {
    "path": "cmd/launcher/web/webui/distr/styles-YY6V3TJU.css",
    "chars": 38029,
    "preview": "html,html.light-theme,html.dark-theme{--mat-sys-corner-extra-large: 28px;--mat-sys-corner-extra-large-top: 28px 28px 0 0"
  },
  {
    "path": "cmd/launcher/web/webui/webui.go",
    "chars": 4504,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/README.md",
    "chars": 979,
    "preview": "# ADK GO samples\nThis folder hosts examples to test different features. The examples are usually minimal and simplistic "
  },
  {
    "path": "examples/a2a/main.go",
    "chars": 3902,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/mcp/main.go",
    "chars": 4164,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/quickstart/main.go",
    "chars": 1930,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/rest/main.go",
    "chars": 2785,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/telemetry/main.go",
    "chars": 2608,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/toolconfirmation/main.go",
    "chars": 12494,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/tools/loadartifacts/main.go",
    "chars": 4078,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/tools/loadmemory/main.go",
    "chars": 6194,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/tools/multipletools/main.go",
    "chars": 3551,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/vertexai/agent.go",
    "chars": 2622,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/vertexai/imagegenerator/main.go",
    "chars": 5468,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/vertexai/vertexengine/create_engine.go",
    "chars": 2733,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/web/agents/image_generator.go",
    "chars": 2929,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/web/agents/llmauditor.go",
    "chars": 11958,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/web/main.go",
    "chars": 3540,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/workflowagents/loop/main.go",
    "chars": 2151,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/workflowagents/parallel/main.go",
    "chars": 2654,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/workflowagents/sequential/main.go",
    "chars": 2511,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "examples/workflowagents/sequentialCode/main.go",
    "chars": 5387,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "go.mod",
    "chars": 4440,
    "preview": "module google.golang.org/adk\n\ngo 1.25.0\n\nrequire (\n\tcloud.google.com/go v0.123.0\n\tcloud.google.com/go/aiplatform v1.105."
  },
  {
    "path": "go.sum",
    "chars": 21205,
    "preview": "cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=\ncel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ"
  },
  {
    "path": "internal/agent/parentmap/map.go",
    "chars": 2200,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/agent/parentmap/map_test.go",
    "chars": 2903,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/agent/remoteagent/a2a_config.go",
    "chars": 2942,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/agent/runconfig/run_config.go",
    "chars": 1160,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/agent/state.go",
    "chars": 1114,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/artifact/artifacts.go",
    "chars": 1934,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/artifact/artifacts_test.go",
    "chars": 3522,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/artifact/tests/service_suite.go",
    "chars": 13681,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/cli/util/doc.go",
    "chars": 841,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/cli/util/flagset_helpers.go",
    "chars": 890,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/cli/util/oscmd.go",
    "chars": 2919,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/cli/util/text_helpers.go",
    "chars": 775,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/configurable/configurable.go",
    "chars": 8602,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/configurable/configurable_utils.go",
    "chars": 14916,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/configurable/conformance/callbacks.go",
    "chars": 3718,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/configurable/conformance/functions.go",
    "chars": 11057,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/configurable/conformance/loader.go",
    "chars": 2033,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/configurable/conformance/replayplugin/invocation_replay_state.go",
    "chars": 2396,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/configurable/conformance/replayplugin/recording/recording.go",
    "chars": 2025,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/configurable/conformance/replayplugin/replay_plugin.go",
    "chars": 18092,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/configurable/conformance/replayplugin/replay_plugin_test.go",
    "chars": 18256,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/configurable/conformance/replayplugin/yaml_utils.go",
    "chars": 2709,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/context/callback_context.go",
    "chars": 3671,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/context/context_test.go",
    "chars": 2018,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/context/invocation_context.go",
    "chars": 2371,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/context/readonly_context.go",
    "chars": 1927,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/converters/map_structure.go",
    "chars": 1643,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/httprr/LICENSE",
    "chars": 1475,
    "preview": "Copyright (c) 2009 The Go Authors. All rights reserved.\nRedistribution and use in source and binary forms, with or witho"
  },
  {
    "path": "internal/httprr/rr.go",
    "chars": 12081,
    "preview": "// Copyright 2024 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "internal/httprr/rr_test.go",
    "chars": 8996,
    "preview": "// Copyright 2024 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "internal/llminternal/agent.go",
    "chars": 1461,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/agent_transfer.go",
    "chars": 9159,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/agent_transfer_test.go",
    "chars": 15187,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/base_flow.go",
    "chars": 28410,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/base_flow_telemetry_test.go",
    "chars": 10954,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/base_flow_test.go",
    "chars": 18537,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/basic_processor.go",
    "chars": 4044,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/clone_test.go",
    "chars": 2699,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/contents_processor.go",
    "chars": 19125,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/contents_processor_test.go",
    "chars": 28297,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/converters/converters.go",
    "chars": 2288,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/file_uploads_processor.go",
    "chars": 1605,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/functions.go",
    "chars": 2909,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/functions_test.go",
    "chars": 6596,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/googlellm/variant.go",
    "chars": 2743,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/googlellm/variant_test.go",
    "chars": 2922,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/handle_function_calls_async_test.go",
    "chars": 5058,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/helpers_test.go",
    "chars": 911,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/identity_request_processor.go",
    "chars": 1461,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/identity_request_processor_test.go",
    "chars": 4223,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/instruction_processor.go",
    "chars": 6542,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/instruction_processor_test.go",
    "chars": 7961,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/other_processors.go",
    "chars": 1913,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/outputschema_processor.go",
    "chars": 4772,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/outputschema_processor_test.go",
    "chars": 10212,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/parallel_function_call_test.go",
    "chars": 13259,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/request_confirmation_processor.go",
    "chars": 5390,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/request_confirmation_processor_test.go",
    "chars": 7723,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/stream_aggregator.go",
    "chars": 9721,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/stream_aggregator_test.go",
    "chars": 22696,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/llminternal/testdata/TestParallelFunctionCalls_test_parallel_function_calls_gemini-2.5-flash.httprr",
    "chars": 14381,
    "preview": "httprr trace v1\n1093 1473\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateCo"
  },
  {
    "path": "internal/llminternal/testdata/TestParallelFunctionCalls_test_parallel_function_calls_gemini-3-flash-preview.httprr",
    "chars": 17051,
    "preview": "httprr trace v1\n1099 2311\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:streamGene"
  },
  {
    "path": "internal/llminternal/testdata/TestParallelFunctionCalls_test_parallel_function_calls_gemini-3.1-pro-preview.httprr",
    "chars": 22335,
    "preview": "httprr trace v1\n1099 3079\nPOST https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-pro-preview:streamGene"
  },
  {
    "path": "internal/llminternal/tools_processor.go",
    "chars": 1616,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/memory/memory.go",
    "chars": 1166,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/memory/memory_test.go",
    "chars": 7102,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/plugininternal/plugin_manager.go",
    "chars": 8214,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/plugininternal/plugincontext/context.go",
    "chars": 665,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/sessionutils/utils.go",
    "chars": 2356,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/style_test.go",
    "chars": 3408,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/telemetry/converters.go",
    "chars": 2815,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/telemetry/converters_test.go",
    "chars": 2037,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/telemetry/logger.go",
    "chars": 6782,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/telemetry/logger_test.go",
    "chars": 15977,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/telemetry/telemetry.go",
    "chars": 8932,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/telemetry/telemetry_test.go",
    "chars": 10908,
    "preview": "// Copyright 2026 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/testutil/genai.go",
    "chars": 2504,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "internal/testutil/test_agent_runner.go",
    "chars": 7611,
    "preview": "// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  }
]

// ... and 174 more files (download for full content)

About this extraction

This page contains the full source code of the google/adk-go GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 374 files (6.6 MB), approximately 1.7M tokens, and a symbol index with 12465 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!