@google/adk 2.2.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/dist/cjs/a2a/a2a_remote_agent.js +4 -1
  2. package/dist/cjs/a2a/agent_card.js +102 -26
  3. package/dist/cjs/a2a/agent_to_a2a.js +1 -1
  4. package/dist/cjs/agents/functions.js +199 -25
  5. package/dist/cjs/agents/instructions.js +4 -1
  6. package/dist/cjs/agents/invocation_context.js +26 -4
  7. package/dist/cjs/agents/langgraph_agent.js +152 -0
  8. package/dist/cjs/agents/llm_agent.js +175 -101
  9. package/dist/cjs/agents/processors/code_execution_request_processor.js +10 -6
  10. package/dist/cjs/agents/remote_agent.js +187 -0
  11. package/dist/cjs/artifacts/in_memory_artifact_service.js +14 -0
  12. package/dist/cjs/auth/auth_handler.js +37 -5
  13. package/dist/cjs/auth/auth_schemes.js +9 -0
  14. package/dist/cjs/cli/cli_eval.js +532 -0
  15. package/dist/cjs/cli/utils/envs.js +116 -0
  16. package/dist/cjs/cli/utils/evals.js +137 -0
  17. package/dist/cjs/cli/utils/logs.js +150 -0
  18. package/dist/cjs/code_executors/agent_engine_sandbox_code_executor.js +7 -2
  19. package/dist/cjs/code_executors/code_execution_utils.js +48 -16
  20. package/dist/cjs/code_executors/code_executor_context.js +6 -2
  21. package/dist/cjs/common.js +72 -0
  22. package/dist/cjs/context/summarizers/llm_summarizer.js +12 -10
  23. package/dist/cjs/context/token_based_context_compactor.js +2 -1
  24. package/dist/cjs/events/event.js +4 -2
  25. package/dist/cjs/examples/example_util.js +23 -2
  26. package/dist/cjs/flows/llm_flows/audio_transcriber.js +170 -0
  27. package/dist/cjs/index.js +97 -1
  28. package/dist/cjs/integrations/agent_registry/helpers.js +1 -1
  29. package/dist/cjs/models/gemini_llm_connection.js +16 -8
  30. package/dist/cjs/models/google_llm.js +13 -16
  31. package/dist/cjs/models/llm_response.js +9 -1
  32. package/dist/cjs/models/registry.js +1 -1
  33. package/dist/cjs/models/routed_llm.js +9 -8
  34. package/dist/cjs/planners/plan_re_act_planner.js +1 -1
  35. package/dist/cjs/runner/in_memory_runner.js +6 -11
  36. package/dist/cjs/runner/runner.js +105 -33
  37. package/dist/cjs/sessions/db/operations.js +1 -1
  38. package/dist/cjs/sessions/in_memory_session_service.js +3 -1
  39. package/dist/cjs/sessions/state.js +8 -4
  40. package/dist/cjs/sessions/vertex_ai_session_service.js +34 -15
  41. package/dist/cjs/telemetry/tracing.js +97 -66
  42. package/dist/cjs/tools/agent_tool.js +44 -0
  43. package/dist/cjs/tools/apihub_tool/apihub_toolset.js +142 -0
  44. package/dist/cjs/tools/apihub_tool/clients/apihub_client.js +272 -0
  45. package/dist/cjs/tools/apihub_tool/clients/secret_client.js +148 -0
  46. package/dist/cjs/tools/apihub_tool/clients/service_account.js +48 -0
  47. package/dist/cjs/tools/application_integration_tool/application_integration_toolset.js +185 -0
  48. package/dist/cjs/tools/application_integration_tool/clients/cloud_request.js +133 -0
  49. package/dist/cjs/tools/application_integration_tool/clients/connections_client.js +603 -0
  50. package/dist/cjs/tools/application_integration_tool/clients/integration_client.js +219 -0
  51. package/dist/cjs/tools/crewai_tool.js +132 -0
  52. package/dist/cjs/tools/example_tool.js +10 -0
  53. package/dist/cjs/tools/function_tool.js +319 -0
  54. package/dist/cjs/tools/google_api_tool/google_api_tool.js +97 -0
  55. package/dist/cjs/tools/google_api_tool/google_api_tool_set.js +226 -0
  56. package/dist/cjs/tools/google_api_tool/google_api_tool_sets.js +58 -0
  57. package/dist/cjs/tools/google_api_tool/googleapi_to_openapi_converter.js +440 -0
  58. package/dist/cjs/tools/google_api_tool/index.js +64 -0
  59. package/dist/cjs/tools/langchain_tool.js +172 -0
  60. package/dist/cjs/tools/mcp/index.js +12 -0
  61. package/dist/cjs/tools/mcp/mcp_session_manager.js +25 -0
  62. package/dist/cjs/tools/openapi_tool/auth/auth_helpers.js +1 -2
  63. package/dist/cjs/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.js +46 -2
  64. package/dist/cjs/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.js +2 -1
  65. package/dist/cjs/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.js +94 -10
  66. package/dist/cjs/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +14 -2
  67. package/dist/cjs/tools/retrieval/base_retrieval_tool.js +18 -3
  68. package/dist/cjs/tools/toolbox_tool.js +108 -0
  69. package/dist/cjs/utils/env_aware_utils.js +6 -8
  70. package/dist/cjs/utils/error_utils.js +11 -11
  71. package/dist/cjs/utils/file_extension_utils.js +11 -0
  72. package/dist/cjs/utils/file_utils.js +2 -24
  73. package/dist/cjs/utils/gemini_schema_util.js +4 -1
  74. package/dist/cjs/utils/json_utils.js +49 -0
  75. package/dist/cjs/utils/live_connection_utils.js +4 -5
  76. package/dist/cjs/utils/logger_node.js +7 -1
  77. package/dist/cjs/utils/object_notation_utils.js +6 -3
  78. package/dist/cjs/utils/streaming_utils.js +12 -12
  79. package/dist/cjs/version.js +1 -1
  80. package/dist/esm/a2a/a2a_remote_agent.js +4 -1
  81. package/dist/esm/a2a/agent_card.js +103 -27
  82. package/dist/esm/a2a/agent_to_a2a.js +5 -2
  83. package/dist/esm/agents/functions.js +198 -25
  84. package/dist/esm/agents/instructions.js +4 -1
  85. package/dist/esm/agents/invocation_context.js +24 -4
  86. package/dist/esm/agents/langgraph_agent.js +123 -0
  87. package/dist/esm/agents/llm_agent.js +185 -104
  88. package/dist/esm/agents/processors/code_execution_request_processor.js +13 -8
  89. package/dist/esm/agents/remote_agent.js +164 -0
  90. package/dist/esm/artifacts/in_memory_artifact_service.js +14 -0
  91. package/dist/esm/auth/auth_handler.js +37 -5
  92. package/dist/esm/auth/auth_schemes.js +8 -0
  93. package/dist/esm/cli/cli_eval.js +510 -0
  94. package/dist/esm/cli/utils/envs.js +78 -0
  95. package/dist/esm/cli/utils/evals.js +109 -0
  96. package/dist/esm/cli/utils/logs.js +111 -0
  97. package/dist/esm/code_executors/agent_engine_sandbox_code_executor.js +7 -2
  98. package/dist/esm/code_executors/code_execution_utils.js +46 -16
  99. package/dist/esm/code_executors/code_executor_context.js +5 -2
  100. package/dist/esm/common.js +67 -3
  101. package/dist/esm/context/summarizers/llm_summarizer.js +12 -10
  102. package/dist/esm/context/token_based_context_compactor.js +2 -1
  103. package/dist/esm/events/event.js +4 -2
  104. package/dist/esm/examples/example_util.js +21 -1
  105. package/dist/esm/flows/llm_flows/audio_transcriber.js +142 -0
  106. package/dist/esm/index.js +99 -1
  107. package/dist/esm/integrations/agent_registry/helpers.js +1 -1
  108. package/dist/esm/models/gemini_llm_connection.js +16 -8
  109. package/dist/esm/models/google_llm.js +14 -17
  110. package/dist/esm/models/llm_response.js +9 -1
  111. package/dist/esm/models/registry.js +1 -1
  112. package/dist/esm/models/routed_llm.js +9 -8
  113. package/dist/esm/planners/plan_re_act_planner.js +1 -1
  114. package/dist/esm/runner/in_memory_runner.js +6 -11
  115. package/dist/esm/runner/runner.js +105 -33
  116. package/dist/esm/sessions/db/operations.js +1 -1
  117. package/dist/esm/sessions/in_memory_session_service.js +3 -1
  118. package/dist/esm/sessions/state.js +8 -4
  119. package/dist/esm/sessions/vertex_ai_session_service.js +34 -15
  120. package/dist/esm/telemetry/tracing.js +97 -66
  121. package/dist/esm/tools/agent_tool.js +44 -0
  122. package/dist/esm/tools/apihub_tool/apihub_toolset.js +106 -0
  123. package/dist/esm/tools/apihub_tool/clients/apihub_client.js +244 -0
  124. package/dist/esm/tools/apihub_tool/clients/secret_client.js +132 -0
  125. package/dist/esm/tools/apihub_tool/clients/service_account.js +21 -0
  126. package/dist/esm/tools/application_integration_tool/application_integration_toolset.js +163 -0
  127. package/dist/esm/tools/application_integration_tool/clients/cloud_request.js +103 -0
  128. package/dist/esm/tools/application_integration_tool/clients/connections_client.js +561 -0
  129. package/dist/esm/tools/application_integration_tool/clients/integration_client.js +215 -0
  130. package/dist/esm/tools/crewai_tool.js +107 -0
  131. package/dist/esm/tools/example_tool.js +13 -1
  132. package/dist/esm/tools/function_tool.js +316 -0
  133. package/dist/esm/tools/google_api_tool/google_api_tool.js +70 -0
  134. package/dist/esm/tools/google_api_tool/google_api_tool_set.js +188 -0
  135. package/dist/esm/tools/google_api_tool/google_api_tool_sets.js +24 -0
  136. package/dist/esm/tools/google_api_tool/googleapi_to_openapi_converter.js +393 -0
  137. package/dist/esm/tools/google_api_tool/index.js +33 -0
  138. package/dist/esm/tools/langchain_tool.js +148 -0
  139. package/dist/esm/tools/mcp/index.js +6 -0
  140. package/dist/esm/tools/mcp/mcp_session_manager.js +25 -0
  141. package/dist/esm/tools/openapi_tool/auth/auth_helpers.js +1 -2
  142. package/dist/esm/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.js +50 -3
  143. package/dist/esm/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.js +2 -1
  144. package/dist/esm/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.js +94 -10
  145. package/dist/esm/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +15 -2
  146. package/dist/esm/tools/retrieval/base_retrieval_tool.js +16 -2
  147. package/dist/esm/tools/toolbox_tool.js +80 -0
  148. package/dist/esm/utils/env_aware_utils.js +6 -8
  149. package/dist/esm/utils/error_utils.js +9 -10
  150. package/dist/esm/utils/file_extension_utils.js +11 -0
  151. package/dist/esm/utils/file_utils.js +2 -23
  152. package/dist/esm/utils/gemini_schema_util.js +4 -1
  153. package/dist/esm/utils/json_utils.js +21 -0
  154. package/dist/esm/utils/live_connection_utils.js +4 -5
  155. package/dist/esm/utils/logger_node.js +7 -1
  156. package/dist/esm/utils/object_notation_utils.js +4 -2
  157. package/dist/esm/utils/streaming_utils.js +11 -11
  158. package/dist/esm/version.js +1 -1
  159. package/dist/types/a2a/a2a_remote_agent.d.ts +9 -0
  160. package/dist/types/a2a/agent_card.d.ts +44 -1
  161. package/dist/types/a2a/agent_to_a2a.d.ts +9 -0
  162. package/dist/types/a2a/index.d.ts +1 -0
  163. package/dist/types/agents/functions.d.ts +33 -1
  164. package/dist/types/agents/invocation_context.d.ts +20 -1
  165. package/dist/types/agents/langgraph_agent.d.ts +153 -0
  166. package/dist/types/agents/remote_agent.d.ts +68 -0
  167. package/dist/types/auth/auth_handler.d.ts +28 -1
  168. package/dist/types/auth/auth_schemes.d.ts +13 -0
  169. package/dist/types/cli/cli_eval.d.ts +173 -0
  170. package/dist/types/cli/utils/envs.d.ts +23 -0
  171. package/dist/types/cli/utils/evals.d.ts +47 -0
  172. package/dist/types/cli/utils/logs.d.ts +38 -0
  173. package/dist/types/code_executors/code_execution_utils.d.ts +39 -0
  174. package/dist/types/code_executors/code_executor_context.d.ts +1 -0
  175. package/dist/types/common.d.ts +27 -4
  176. package/dist/types/events/event.d.ts +4 -0
  177. package/dist/types/examples/example_util.d.ts +17 -0
  178. package/dist/types/flows/llm_flows/audio_transcriber.d.ts +85 -0
  179. package/dist/types/index.d.ts +16 -1
  180. package/dist/types/models/gemini_llm_connection.d.ts +6 -7
  181. package/dist/types/models/routed_llm.d.ts +1 -1
  182. package/dist/types/runner/in_memory_runner.d.ts +2 -1
  183. package/dist/types/runner/runner.d.ts +34 -0
  184. package/dist/types/sessions/state.d.ts +5 -1
  185. package/dist/types/sessions/vertex_ai_session_service.d.ts +8 -0
  186. package/dist/types/skills/skill.d.ts +1 -1
  187. package/dist/types/telemetry/tracing.d.ts +4 -2
  188. package/dist/types/tools/apihub_tool/apihub_toolset.d.ts +122 -0
  189. package/dist/types/tools/apihub_tool/clients/apihub_client.d.ts +142 -0
  190. package/dist/types/tools/apihub_tool/clients/secret_client.d.ts +55 -0
  191. package/dist/types/tools/apihub_tool/clients/service_account.d.ts +11 -0
  192. package/dist/types/tools/application_integration_tool/application_integration_toolset.d.ts +86 -0
  193. package/dist/types/tools/application_integration_tool/clients/cloud_request.d.ts +53 -0
  194. package/dist/types/tools/application_integration_tool/clients/connections_client.d.ts +215 -0
  195. package/dist/types/tools/application_integration_tool/clients/integration_client.d.ts +72 -0
  196. package/dist/types/tools/crewai_tool.d.ts +85 -0
  197. package/dist/types/tools/example_tool.d.ts +10 -0
  198. package/dist/types/tools/function_tool.d.ts +32 -0
  199. package/dist/types/tools/google_api_tool/google_api_tool.d.ts +30 -0
  200. package/dist/types/tools/google_api_tool/google_api_tool_set.d.ts +78 -0
  201. package/dist/types/tools/google_api_tool/google_api_tool_sets.d.ts +33 -0
  202. package/dist/types/tools/google_api_tool/googleapi_to_openapi_converter.d.ts +164 -0
  203. package/dist/types/tools/google_api_tool/index.d.ts +11 -0
  204. package/dist/types/tools/langchain_tool.d.ts +103 -0
  205. package/dist/types/tools/mcp/index.d.ts +3 -0
  206. package/dist/types/tools/mcp/mcp_session_manager.d.ts +34 -1
  207. package/dist/types/tools/mcp/mcp_toolset.d.ts +15 -0
  208. package/dist/types/tools/openapi_tool/auth/auth_helpers.d.ts +19 -0
  209. package/dist/types/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.d.ts +18 -1
  210. package/dist/types/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.d.ts +2 -1
  211. package/dist/types/tools/retrieval/base_retrieval_tool.d.ts +15 -0
  212. package/dist/types/tools/toolbox_tool.d.ts +73 -0
  213. package/dist/types/utils/env_aware_utils.d.ts +18 -2
  214. package/dist/types/utils/error_utils.d.ts +7 -0
  215. package/dist/types/utils/file_utils.d.ts +6 -1
  216. package/dist/types/utils/gemini_schema_util.d.ts +1 -2
  217. package/dist/types/utils/json_utils.d.ts +11 -0
  218. package/dist/types/utils/object_notation_utils.d.ts +7 -0
  219. package/dist/types/utils/streaming_utils.d.ts +11 -4
  220. package/dist/types/version.d.ts +1 -1
  221. package/dist/web/index_web.js +102 -103
  222. package/dist/web/index_web.js.map +4 -4
  223. package/package.json +8 -3
  224. package/dist/cjs/models/gemini_continuation.js +0 -232
  225. package/dist/esm/models/gemini_continuation.js +0 -205
  226. package/dist/types/models/gemini_continuation.d.ts +0 -59
@@ -19,9 +19,46 @@ var __decorateClass = (decorators, target, key, kind) => {
19
19
  import {
20
20
  AuthCredentialTypes
21
21
  } from "../../../../auth/auth_credential.js";
22
- import { OAuth2CredentialExchanger } from "../../../../auth/oauth2/oauth2_credential_exchanger.js";
22
+ import { OAuthGrantType } from "../../../../auth/auth_schemes.js";
23
+ import {
24
+ determineGrantType,
25
+ OAuth2CredentialExchanger
26
+ } from "../../../../auth/oauth2/oauth2_credential_exchanger.js";
23
27
  import { experimental } from "../../../../utils/experimental.js";
28
+ import { generateAuthToken } from "./oauth2_exchanger.js";
24
29
  import { ServiceAccountCredentialExchanger } from "./service_account_exchanger.js";
30
+ function isPendingAuthorizationCode(authScheme, authCredential) {
31
+ var _a, _b, _c;
32
+ return !!authScheme && determineGrantType(authScheme) === OAuthGrantType.AUTHORIZATION_CODE && !((_a = authCredential.oauth2) == null ? void 0 : _a.accessToken) && !((_b = authCredential.oauth2) == null ? void 0 : _b.authCode) && !((_c = authCredential.oauth2) == null ? void 0 : _c.authResponseUri);
33
+ }
34
+ __name(isPendingAuthorizationCode, "isPendingAuthorizationCode");
35
+ function createDefaultOAuth2Exchanger() {
36
+ const tokenFetcher = new OAuth2CredentialExchanger();
37
+ return {
38
+ async exchange(params) {
39
+ const { authScheme, authCredential } = params;
40
+ if (authScheme && authCredential.http) {
41
+ return {
42
+ credential: authCredential,
43
+ wasExchanged: false
44
+ };
45
+ }
46
+ if (isPendingAuthorizationCode(authScheme, authCredential)) {
47
+ return {
48
+ credential: authCredential,
49
+ wasExchanged: false
50
+ };
51
+ }
52
+ const { credential, wasExchanged } = await tokenFetcher.exchange(params);
53
+ const bearer = generateAuthToken(credential);
54
+ return {
55
+ credential: bearer,
56
+ wasExchanged: wasExchanged || bearer !== credential
57
+ };
58
+ }
59
+ };
60
+ }
61
+ __name(createDefaultOAuth2Exchanger, "createDefaultOAuth2Exchanger");
25
62
  let AutoAuthCredentialExchanger = class {
26
63
  /**
27
64
  * @param customExchangers - Optional exchangers that add to or override the
@@ -29,14 +66,24 @@ let AutoAuthCredentialExchanger = class {
29
66
  * exchanger instance to use for that type.
30
67
  */
31
68
  constructor(customExchangers) {
69
+ /**
70
+ * The exchanger used for each auth credential type.
71
+ *
72
+ * By default `OAUTH2` and `OPEN_ID_CONNECT` run
73
+ * {@link OAuth2CredentialExchanger} and convert any access token with
74
+ * {@link generateAuthToken}, and `SERVICE_ACCOUNT` maps to a
75
+ * {@link ServiceAccountCredentialExchanger}, with any custom exchangers from
76
+ * the constructor merged over them. The map is live: an entry added or
77
+ * replaced after construction is used by the next {@link exchange} call.
78
+ */
32
79
  this.exchangers = /* @__PURE__ */ new Map();
33
80
  this.exchangers.set(
34
81
  AuthCredentialTypes.OAUTH2,
35
- new OAuth2CredentialExchanger()
82
+ createDefaultOAuth2Exchanger()
36
83
  );
37
84
  this.exchangers.set(
38
85
  AuthCredentialTypes.OPEN_ID_CONNECT,
39
- new OAuth2CredentialExchanger()
86
+ createDefaultOAuth2Exchanger()
40
87
  );
41
88
  this.exchangers.set(
42
89
  AuthCredentialTypes.SERVICE_ACCOUNT,
@@ -19,6 +19,7 @@ var __decorateClass = (decorators, target, key, kind) => {
19
19
  import {
20
20
  AuthCredentialTypes
21
21
  } from "../../../../auth/auth_credential.js";
22
+ import { AuthSchemeType } from "../../../../auth/auth_schemes.js";
22
23
  import { experimental } from "../../../../utils/experimental.js";
23
24
  function checkSchemeCredentialType(authScheme, authCredential) {
24
25
  if (!authCredential) {
@@ -26,7 +27,7 @@ function checkSchemeCredentialType(authScheme, authCredential) {
26
27
  "auth_credential is empty. Please create AuthCredential using OAuth2Auth."
27
28
  );
28
29
  }
29
- if (authScheme.type !== "openIdConnect" && authScheme.type !== "oauth2") {
30
+ if (authScheme.type !== AuthSchemeType.OPEN_ID_CONNECT && authScheme.type !== AuthSchemeType.OAUTH2) {
30
31
  throw new Error(
31
32
  `Invalid security scheme, expect AuthSchemeType.openIdConnect or AuthSchemeType.oauth2 auth scheme, but got ${authScheme.type}`
32
33
  );
@@ -17,6 +17,7 @@ var __decorateClass = (decorators, target, key, kind) => {
17
17
  * SPDX-License-Identifier: Apache-2.0
18
18
  */
19
19
  import { GoogleAuth, JWT } from "google-auth-library";
20
+ import { createSign } from "node:crypto";
20
21
  import {
21
22
  AuthCredentialTypes
22
23
  } from "../../../../auth/auth_credential.js";
@@ -24,6 +25,83 @@ import { experimental } from "../../../../utils/experimental.js";
24
25
  import { AuthCredentialMissingError } from "./base_auth_credential_exchanger.js";
25
26
  const DEFAULT_SCOPES = ["https://www.googleapis.com/auth/cloud-platform"];
26
27
  const MISSING_SERVICE_ACCOUNT_CREDENTIALS = "Service account credentials are missing. Please provide them, or set `useDefaultCredential: true` to use application default credentials in a hosted service like Cloud Run.";
28
+ const GOOGLE_TOKEN_URI = "https://oauth2.googleapis.com/token";
29
+ const JWT_BEARER_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer";
30
+ const ASSERTION_LIFETIME_SECONDS = 3600;
31
+ const TOKEN_REQUEST_TIMEOUT_MS = 3e4;
32
+ function hasCustomTokenUri(creds) {
33
+ return !!creds.tokenUri && creds.tokenUri !== GOOGLE_TOKEN_URI;
34
+ }
35
+ __name(hasCustomTokenUri, "hasCustomTokenUri");
36
+ function base64UrlJson(value) {
37
+ return Buffer.from(JSON.stringify(value)).toString("base64url");
38
+ }
39
+ __name(base64UrlJson, "base64UrlJson");
40
+ function signJwtBearerAssertion(creds, scopes, issuedAt) {
41
+ const header = {
42
+ alg: "RS256",
43
+ typ: "JWT",
44
+ ...creds.privateKeyId ? { kid: creds.privateKeyId } : {}
45
+ };
46
+ const payload = {
47
+ iss: creds.clientEmail,
48
+ scope: scopes.join(" "),
49
+ aud: GOOGLE_TOKEN_URI,
50
+ iat: issuedAt,
51
+ exp: issuedAt + ASSERTION_LIFETIME_SECONDS
52
+ };
53
+ const signingInput = `${base64UrlJson(header)}.${base64UrlJson(payload)}`;
54
+ const signature = createSign("RSA-SHA256").update(signingInput).sign(creds.privateKey, "base64url");
55
+ return `${signingInput}.${signature}`;
56
+ }
57
+ __name(signJwtBearerAssertion, "signJwtBearerAssertion");
58
+ async function readTokenErrorDetail(response) {
59
+ try {
60
+ const body = await response.json();
61
+ if (typeof body !== "object" || body === null) {
62
+ return void 0;
63
+ }
64
+ const parts = [];
65
+ if ("error" in body && typeof body.error === "string" && body.error.length > 0) {
66
+ parts.push(body.error);
67
+ }
68
+ if ("error_description" in body && typeof body.error_description === "string" && body.error_description.length > 0) {
69
+ parts.push(body.error_description);
70
+ }
71
+ return parts.length > 0 ? parts.join(": ") : void 0;
72
+ } catch {
73
+ return void 0;
74
+ }
75
+ }
76
+ __name(readTokenErrorDetail, "readTokenErrorDetail");
77
+ async function requestJwtBearerToken(creds, scopes) {
78
+ const assertion = signJwtBearerAssertion(
79
+ creds,
80
+ scopes,
81
+ Math.floor(Date.now() / 1e3)
82
+ );
83
+ const response = await fetch(creds.tokenUri, {
84
+ method: "POST",
85
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
86
+ body: new URLSearchParams({
87
+ grant_type: JWT_BEARER_GRANT_TYPE,
88
+ assertion
89
+ }),
90
+ signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS)
91
+ });
92
+ if (!response.ok) {
93
+ const detail = await readTokenErrorDetail(response);
94
+ throw new Error(
95
+ detail ? `Token endpoint responded with HTTP ${response.status}: ${detail}` : `Token endpoint responded with HTTP ${response.status}`
96
+ );
97
+ }
98
+ const body = await response.json();
99
+ if (typeof body === "object" && body !== null && "access_token" in body && typeof body.access_token === "string") {
100
+ return body.access_token;
101
+ }
102
+ return void 0;
103
+ }
104
+ __name(requestJwtBearerToken, "requestJwtBearerToken");
27
105
  let ServiceAccountCredentialExchanger = class {
28
106
  async exchange(params) {
29
107
  const { authCredential } = params;
@@ -64,21 +142,27 @@ let ServiceAccountCredentialExchanger = class {
64
142
  }
65
143
  }
66
144
  async exchangeForExplicitCredential(saConfig) {
145
+ var _a;
67
146
  const creds = saConfig.serviceAccountCredential;
68
147
  if (!creds) {
69
148
  throw new AuthCredentialMissingError(MISSING_SERVICE_ACCOUNT_CREDENTIALS);
70
149
  }
71
150
  try {
72
- const client = new JWT({
73
- email: creds.clientEmail,
74
- key: creds.privateKey,
75
- keyId: creds.privateKeyId,
76
- projectId: creds.projectId,
77
- universeDomain: creds.universeDomain,
78
- scopes: saConfig.scopes
79
- });
80
- const tokens = await client.authorize();
81
- const token = tokens.access_token;
151
+ let token;
152
+ if (hasCustomTokenUri(creds)) {
153
+ token = await requestJwtBearerToken(creds, (_a = saConfig.scopes) != null ? _a : []);
154
+ } else {
155
+ const client = new JWT({
156
+ email: creds.clientEmail,
157
+ key: creds.privateKey,
158
+ keyId: creds.privateKeyId,
159
+ projectId: creds.projectId,
160
+ universeDomain: creds.universeDomain,
161
+ scopes: saConfig.scopes
162
+ });
163
+ const tokens = await client.authorize();
164
+ token = tokens.access_token;
165
+ }
82
166
  if (!token) {
83
167
  throw new Error("Failed to get access token from explicit credentials");
84
168
  }
@@ -18,6 +18,7 @@ var __decorateClass = (decorators, target, key, kind) => {
18
18
  */
19
19
  import { cloneDeep } from "lodash-es";
20
20
  import {
21
+ AuthCredentialTypes,
21
22
  isAuthCredential
22
23
  } from "../../../auth/auth_credential.js";
23
24
  import { experimental } from "../../../utils/experimental.js";
@@ -26,6 +27,16 @@ import { logger } from "../../../utils/logger.js";
26
27
  import { AutoAuthCredentialExchanger } from "../auth/credential_exchangers/auto_auth_credential_exchanger.js";
27
28
  import { AuthCredentialMissingError } from "../auth/credential_exchangers/base_auth_credential_exchanger.js";
28
29
  const DEFAULT_CREDENTIAL_KEY = "default_openapi_key";
30
+ const INTERACTIVE_CREDENTIAL_TYPES = /* @__PURE__ */ new Set([
31
+ AuthCredentialTypes.OAUTH2,
32
+ AuthCredentialTypes.OPEN_ID_CONNECT
33
+ ]);
34
+ function isMissingInteractiveToken(result) {
35
+ var _a, _b;
36
+ const { credential, wasExchanged } = result;
37
+ return !wasExchanged && INTERACTIVE_CREDENTIAL_TYPES.has(credential.authType) && !credential.http && !((_a = credential.oauth2) == null ? void 0 : _a.accessToken) && !((_b = credential.oauth2) == null ? void 0 : _b.refreshToken);
38
+ }
39
+ __name(isMissingInteractiveToken, "isMissingInteractiveToken");
29
40
  const _ToolContextCredentialStore = class _ToolContextCredentialStore {
30
41
  constructor(context) {
31
42
  this.context = context;
@@ -141,7 +152,8 @@ let ToolAuthHandler = class {
141
152
  };
142
153
  }
143
154
  /**
144
- * Exchanges `credential`, or returns `undefined` when the exchange failed.
155
+ * Exchanges `credential`, or returns `undefined` when the exchange failed or
156
+ * produced an interactive credential that still holds no token.
145
157
  *
146
158
  * An exchange failure is transient far more often than it is fatal, so it
147
159
  * becomes a `pending` result the client can resume from rather than an
@@ -151,10 +163,11 @@ let ToolAuthHandler = class {
151
163
  var _a;
152
164
  const exchanger = (_a = this.credentialExchanger) != null ? _a : new AutoAuthCredentialExchanger();
153
165
  try {
154
- return await exchanger.exchange({
166
+ const result = await exchanger.exchange({
155
167
  authScheme: this.authScheme,
156
168
  authCredential: credential
157
169
  });
170
+ return isMissingInteractiveToken(result) ? void 0 : result;
158
171
  } catch (e) {
159
172
  logger.error(
160
173
  `Failed to exchange credential: ${e instanceof Error ? e.message : e}`
@@ -7,9 +7,22 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
7
7
  * Copyright 2026 Google LLC
8
8
  * SPDX-License-Identifier: Apache-2.0
9
9
  */
10
+ var _a, _b;
10
11
  import { Type } from "@google/genai";
11
12
  import { BaseTool } from "../base_tool.js";
12
- const _BaseRetrievalTool = class _BaseRetrievalTool extends BaseTool {
13
+ const BASE_RETRIEVAL_TOOL_SIGNATURE_SYMBOL = /* @__PURE__ */ Symbol.for(
14
+ "google.adk.baseRetrievalTool"
15
+ );
16
+ function isBaseRetrievalTool(obj) {
17
+ return typeof obj === "object" && obj !== null && BASE_RETRIEVAL_TOOL_SIGNATURE_SYMBOL in obj && obj[BASE_RETRIEVAL_TOOL_SIGNATURE_SYMBOL] === true;
18
+ }
19
+ __name(isBaseRetrievalTool, "isBaseRetrievalTool");
20
+ const _BaseRetrievalTool = class _BaseRetrievalTool extends (_b = BaseTool, _a = BASE_RETRIEVAL_TOOL_SIGNATURE_SYMBOL, _b) {
21
+ constructor() {
22
+ super(...arguments);
23
+ /** Unique symbol to identify `BaseRetrievalTool` class. */
24
+ this[_a] = true;
25
+ }
13
26
  _getDeclaration() {
14
27
  return {
15
28
  name: this.name,
@@ -29,5 +42,6 @@ const _BaseRetrievalTool = class _BaseRetrievalTool extends BaseTool {
29
42
  __name(_BaseRetrievalTool, "BaseRetrievalTool");
30
43
  let BaseRetrievalTool = _BaseRetrievalTool;
31
44
  export {
32
- BaseRetrievalTool
45
+ BaseRetrievalTool,
46
+ isBaseRetrievalTool
33
47
  };
@@ -0,0 +1,80 @@
1
+ import {createRequire as topLevelCreateRequire} from 'module';
2
+ const require = topLevelCreateRequire(import.meta.url);
3
+ var __defProp = Object.defineProperty;
4
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
+ /**
6
+ * @license
7
+ * Copyright 2026 Google LLC
8
+ * SPDX-License-Identifier: Apache-2.0
9
+ */
10
+ var _a;
11
+ import { LangchainTool } from "./langchain_tool.js";
12
+ const TOOLBOX_TOOL_SIGNATURE_SYMBOL = /* @__PURE__ */ Symbol.for("google.adk.toolboxTool");
13
+ function isToolboxTool(obj) {
14
+ return typeof obj === "object" && obj !== null && TOOLBOX_TOOL_SIGNATURE_SYMBOL in obj && obj[TOOLBOX_TOOL_SIGNATURE_SYMBOL] === true;
15
+ }
16
+ __name(isToolboxTool, "isToolboxTool");
17
+ function createUnconfiguredToolboxClient(url) {
18
+ const endpoint = url != null ? url : "unspecified URL";
19
+ const throwMissingClient = /* @__PURE__ */ __name(() => {
20
+ throw new Error(
21
+ `ToolboxTool requires a ToolboxClientLike instance (for endpoint "${endpoint}"). Pass {url, client} to the ToolboxTool constructor.`
22
+ );
23
+ }, "throwMissingClient");
24
+ return {
25
+ loadTool: throwMissingClient,
26
+ loadToolset: throwMissingClient
27
+ };
28
+ }
29
+ __name(createUnconfiguredToolboxClient, "createUnconfiguredToolboxClient");
30
+ _a = TOOLBOX_TOOL_SIGNATURE_SYMBOL;
31
+ const _ToolboxTool = class _ToolboxTool {
32
+ constructor(urlOrOptions) {
33
+ /** A unique symbol to identify ADK ToolboxTool class. */
34
+ this[_a] = true;
35
+ var _a2;
36
+ if (typeof urlOrOptions === "string") {
37
+ this.url = urlOrOptions;
38
+ this.toolboxClient = createUnconfiguredToolboxClient(urlOrOptions);
39
+ } else {
40
+ this.url = urlOrOptions.url;
41
+ this.toolboxClient = (_a2 = urlOrOptions.client) != null ? _a2 : createUnconfiguredToolboxClient(urlOrOptions.url);
42
+ }
43
+ }
44
+ /**
45
+ * Loads a single tool from the Toolbox client and wraps it in a
46
+ * {@link LangchainTool}.
47
+ */
48
+ getTool(toolName) {
49
+ var _a2, _b, _c;
50
+ const loader = (_c = (_a2 = this.toolboxClient.loadTool) == null ? void 0 : _a2.bind(this.toolboxClient)) != null ? _c : (_b = this.toolboxClient.load_tool) == null ? void 0 : _b.bind(this.toolboxClient);
51
+ if (!loader) {
52
+ throw new Error(
53
+ "ToolboxClient does not implement loadTool or load_tool."
54
+ );
55
+ }
56
+ const tool = loader(toolName);
57
+ return new LangchainTool(tool);
58
+ }
59
+ /**
60
+ * Loads a toolset from the Toolbox client and wraps each tool in a
61
+ * {@link LangchainTool}.
62
+ */
63
+ getToolset(toolsetName) {
64
+ var _a2, _b, _c;
65
+ const loader = (_c = (_a2 = this.toolboxClient.loadToolset) == null ? void 0 : _a2.bind(this.toolboxClient)) != null ? _c : (_b = this.toolboxClient.load_toolset) == null ? void 0 : _b.bind(this.toolboxClient);
66
+ if (!loader) {
67
+ throw new Error(
68
+ "ToolboxClient does not implement loadToolset or load_toolset."
69
+ );
70
+ }
71
+ const tools = loader(toolsetName);
72
+ return tools.map((tool) => new LangchainTool(tool));
73
+ }
74
+ };
75
+ __name(_ToolboxTool, "ToolboxTool");
76
+ let ToolboxTool = _ToolboxTool;
77
+ export {
78
+ ToolboxTool,
79
+ isToolboxTool
80
+ };
@@ -38,14 +38,10 @@ function randomUUID() {
38
38
  __name(randomUUID, "randomUUID");
39
39
  function base64Encode(data) {
40
40
  if (isBrowser()) {
41
+ const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
41
42
  let strData = "";
42
- if (typeof data === "string") {
43
- strData = data;
44
- } else {
45
- const len = data.byteLength;
46
- for (let i = 0; i < len; i++) {
47
- strData += String.fromCharCode(data[i]);
48
- }
43
+ for (let i = 0; i < bytes.length; i++) {
44
+ strData += String.fromCharCode(bytes[i]);
49
45
  }
50
46
  return window.btoa(strData);
51
47
  }
@@ -54,7 +50,9 @@ function base64Encode(data) {
54
50
  __name(base64Encode, "base64Encode");
55
51
  function base64Decode(data) {
56
52
  if (isBrowser()) {
57
- return window.atob(data);
53
+ const binary = window.atob(data);
54
+ const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
55
+ return new TextDecoder("utf-8", { ignoreBOM: true }).decode(bytes);
58
56
  }
59
57
  return Buffer.from(data, "base64").toString();
60
58
  }
@@ -29,16 +29,14 @@ function truncateBody(body) {
29
29
  return body.length > MAX_RESPONSE_BODY_LENGTH ? body.slice(0, MAX_RESPONSE_BODY_LENGTH) + TRUNCATION_MARKER : body;
30
30
  }
31
31
  __name(truncateBody, "truncateBody");
32
- function baseMessage(err) {
33
- if (err instanceof Error) {
34
- return err.message;
35
- }
36
- if (typeof err === "string") {
37
- return err;
32
+ function getErrorMessage(err) {
33
+ const record = asRecord(err);
34
+ if (record !== void 0 && typeof record["message"] === "string") {
35
+ return record["message"];
38
36
  }
39
37
  return String(err);
40
38
  }
41
- __name(baseMessage, "baseMessage");
39
+ __name(getErrorMessage, "getErrorMessage");
42
40
  function extractHttpDetails(err) {
43
41
  var _a, _b;
44
42
  const record = asRecord(err);
@@ -71,7 +69,7 @@ function formatErrorRecursive(err, seen) {
71
69
  }
72
70
  if (typeof err === "object") {
73
71
  if (seen.has(err)) {
74
- return baseMessage(err);
72
+ return getErrorMessage(err);
75
73
  }
76
74
  seen.add(err);
77
75
  }
@@ -79,7 +77,7 @@ function formatErrorRecursive(err, seen) {
79
77
  return err.errors.map((sub) => formatErrorRecursive(sub, seen)).join(" | ");
80
78
  }
81
79
  const http = extractHttpDetails(err);
82
- const base = baseMessage(err);
80
+ const base = getErrorMessage(err);
83
81
  const cause = (_a = asRecord(err)) == null ? void 0 : _a["cause"];
84
82
  const causeMessage = cause !== void 0 ? formatErrorRecursive(cause, seen) : void 0;
85
83
  let message = base.length > 0 ? base : UNKNOWN_ERROR;
@@ -97,5 +95,6 @@ function formatError(err) {
97
95
  }
98
96
  __name(formatError, "formatError");
99
97
  export {
100
- formatError
98
+ formatError,
99
+ getErrorMessage
101
100
  };
@@ -13,7 +13,17 @@ import {
13
13
  } from "../code_executors/code_execution_utils.js";
14
14
  const MIME_TYPE_MAP = {
15
15
  ".js": { mimeType: "text/javascript", encoding: FileContentEncoding.UTF8 },
16
+ ".cjs": { mimeType: "text/javascript", encoding: FileContentEncoding.UTF8 },
17
+ ".mjs": { mimeType: "text/javascript", encoding: FileContentEncoding.UTF8 },
18
+ ".ts": { mimeType: "text/javascript", encoding: FileContentEncoding.UTF8 },
19
+ ".cts": { mimeType: "text/javascript", encoding: FileContentEncoding.UTF8 },
20
+ ".mts": { mimeType: "text/javascript", encoding: FileContentEncoding.UTF8 },
16
21
  ".py": { mimeType: "text/x-python", encoding: FileContentEncoding.UTF8 },
22
+ ".sh": { mimeType: "text/x-shellscript", encoding: FileContentEncoding.UTF8 },
23
+ ".bash": {
24
+ mimeType: "text/x-shellscript",
25
+ encoding: FileContentEncoding.UTF8
26
+ },
17
27
  ".md": { mimeType: "text/markdown", encoding: FileContentEncoding.UTF8 },
18
28
  ".txt": { mimeType: "text/plain", encoding: FileContentEncoding.UTF8 },
19
29
  ".html": { mimeType: "text/html", encoding: FileContentEncoding.UTF8 },
@@ -27,6 +37,7 @@ const MIME_TYPE_MAP = {
27
37
  ".png": { mimeType: "image/png", encoding: FileContentEncoding.BASE64 },
28
38
  ".jpg": { mimeType: "image/jpeg", encoding: FileContentEncoding.BASE64 },
29
39
  ".jpeg": { mimeType: "image/jpeg", encoding: FileContentEncoding.BASE64 },
40
+ ".gif": { mimeType: "image/gif", encoding: FileContentEncoding.BASE64 },
30
41
  ".pdf": { mimeType: "application/pdf", encoding: FileContentEncoding.BASE64 }
31
42
  };
32
43
  const EXTENSION_TO_LANGUAGE = {
@@ -9,6 +9,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
9
9
  */
10
10
  import * as fs from "node:fs/promises";
11
11
  import * as path from "node:path";
12
+ import { getMimeTypeAndEncoding } from "./file_extension_utils.js";
12
13
  function isInsideDir(resolvedPath, resolvedBaseDir) {
13
14
  return resolvedPath === resolvedBaseDir || resolvedPath.startsWith(resolvedBaseDir + path.sep);
14
15
  }
@@ -59,33 +60,11 @@ async function materializeFiles(files, dir) {
59
60
  return createdFiles;
60
61
  }
61
62
  __name(materializeFiles, "materializeFiles");
62
- const EXTENSION_TO_MIME_TYPE = {
63
- "pdf": "application/pdf",
64
- "jpg": "image/jpeg",
65
- "jpeg": "image/jpeg",
66
- "png": "image/png",
67
- "gif": "image/gif",
68
- "csv": "text/csv",
69
- "json": "application/json",
70
- "xml": "application/xml",
71
- "sh": "text/x-shellscript",
72
- "bash": "text/x-shellscript",
73
- "py": "text/x-python",
74
- "js": "text/javascript",
75
- "cjs": "text/javascript",
76
- "mjs": "text/javascript",
77
- "ts": "text/javascript",
78
- "cts": "text/javascript",
79
- "mts": "text/javascript"
80
- };
81
63
  function guessMimeType(filePath) {
82
- var _a;
83
- const ext = ((_a = filePath.split(".").pop()) == null ? void 0 : _a.toLowerCase()) || "";
84
- return EXTENSION_TO_MIME_TYPE[ext] || "application/octet-stream";
64
+ return getMimeTypeAndEncoding(path.extname(filePath)).mimeType;
85
65
  }
86
66
  __name(guessMimeType, "guessMimeType");
87
67
  export {
88
- EXTENSION_TO_MIME_TYPE,
89
68
  guessMimeType,
90
69
  materializeFiles
91
70
  };
@@ -45,6 +45,9 @@ function toGeminiSchema(mcpSchema) {
45
45
  }
46
46
  function recursiveConvert(mcp) {
47
47
  var _a;
48
+ if (typeof mcp === "boolean") {
49
+ mcp = { type: "object" };
50
+ }
48
51
  const sourceType = (_a = mcp.anyOf) != null ? _a : mcp.type;
49
52
  let isNullable = false;
50
53
  let nonNullTypes;
@@ -135,7 +138,7 @@ function toGeminiSchema(mcpSchema) {
135
138
  geminiSchema.required = mcp.required;
136
139
  }
137
140
  } else if (geminiType === Type.ARRAY) {
138
- if (mcp.items) {
141
+ if (mcp.items || mcp.items === false) {
139
142
  geminiSchema.items = recursiveConvert(mcp.items);
140
143
  }
141
144
  }
@@ -0,0 +1,21 @@
1
+ import {createRequire as topLevelCreateRequire} from 'module';
2
+ const require = topLevelCreateRequire(import.meta.url);
3
+ var __defProp = Object.defineProperty;
4
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
+ /**
6
+ * @license
7
+ * Copyright 2026 Google LLC
8
+ * SPDX-License-Identifier: Apache-2.0
9
+ */
10
+ function isJsonObject(value) {
11
+ return typeof value === "object" && value !== null && !Array.isArray(value);
12
+ }
13
+ __name(isJsonObject, "isJsonObject");
14
+ function toJsonObject(value) {
15
+ return isJsonObject(value) ? value : {};
16
+ }
17
+ __name(toJsonObject, "toJsonObject");
18
+ export {
19
+ isJsonObject,
20
+ toJsonObject
21
+ };
@@ -178,12 +178,11 @@ const _LiveResponseAggregator = class _LiveResponseAggregator {
178
178
  yield this.buildFullTextResponse(this.text, this.isThought);
179
179
  this.text = "";
180
180
  this.isThought = false;
181
- } else {
182
- yield {
183
- interrupted: serverContent.interrupted,
184
- ...this.modelVersion ? { modelVersion: this.modelVersion } : {}
185
- };
186
181
  }
182
+ yield {
183
+ interrupted: serverContent.interrupted,
184
+ ...this.modelVersion ? { modelVersion: this.modelVersion } : {}
185
+ };
187
186
  }
188
187
  }
189
188
  if (message.toolCall) {
@@ -9,6 +9,12 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
9
9
  */
10
10
  import * as winston from "winston";
11
11
  import { LogLevel, setLogger } from "./logger.js";
12
+ const WINSTON_LEVEL_NAMES = {
13
+ [LogLevel.DEBUG]: "debug",
14
+ [LogLevel.INFO]: "info",
15
+ [LogLevel.WARN]: "warn",
16
+ [LogLevel.ERROR]: "error"
17
+ };
12
18
  const _WinstonLogger = class _WinstonLogger {
13
19
  constructor() {
14
20
  this.logLevel = LogLevel.INFO;
@@ -42,7 +48,7 @@ const _WinstonLogger = class _WinstonLogger {
42
48
  if (this.logLevel > level) {
43
49
  return;
44
50
  }
45
- this.logger.log(level.toString(), messages.join(" "));
51
+ this.logger.log(WINSTON_LEVEL_NAMES[level], messages.join(" "));
46
52
  }
47
53
  debug(...messages) {
48
54
  if (this.logLevel > LogLevel.DEBUG) {
@@ -19,7 +19,8 @@ const toCamelCaseKey = /* @__PURE__ */ __name((key) => key.replace(
19
19
  /_([a-z])/g,
20
20
  (_match, letter) => letter.toUpperCase()
21
21
  ), "toCamelCaseKey");
22
- const toSnakeCaseKey = /* @__PURE__ */ __name((key) => key.replace(/[A-Z]/g, (g) => "_" + g.toLowerCase()), "toSnakeCaseKey");
22
+ const CAMEL_BOUNDARY = /(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g;
23
+ const toSnakeCaseKey = /* @__PURE__ */ __name((key) => key.replace(CAMEL_BOUNDARY, "_").toLowerCase().replace(/-/g, "_"), "toSnakeCaseKey");
23
24
  function toNotation(obj, converter, parentKey = "", preserveKeys = []) {
24
25
  if (Array.isArray(obj)) {
25
26
  return obj.map(
@@ -50,5 +51,6 @@ function toNotation(obj, converter, parentKey = "", preserveKeys = []) {
50
51
  __name(toNotation, "toNotation");
51
52
  export {
52
53
  toCamelCase,
53
- toSnakeCase
54
+ toSnakeCase,
55
+ toSnakeCaseKey
54
56
  };