@google/adk 2.3.0 → 2.4.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 (162) hide show
  1. package/dist/cjs/agents/agent_engine_client.js +172 -0
  2. package/dist/cjs/agents/base_agent.js +20 -4
  3. package/dist/cjs/agents/functions.js +28 -0
  4. package/dist/cjs/agents/instructions.js +2 -1
  5. package/dist/cjs/agents/llm_agent.js +19 -6
  6. package/dist/cjs/agents/processors/basic_llm_request_processor.js +1 -1
  7. package/dist/cjs/agents/processors/code_execution_request_processor.js +8 -0
  8. package/dist/cjs/agents/processors/content_processor_utils.js +38 -10
  9. package/dist/cjs/agents/processors/content_request_processor.js +34 -2
  10. package/dist/cjs/agents/processors/instructions_llm_request_processor.js +1 -1
  11. package/dist/cjs/agents/processors/nl_planning_processor.js +12 -3
  12. package/dist/cjs/cli/utils/logs.js +6 -6
  13. package/dist/cjs/code_executors/container_code_executor.js +27 -16
  14. package/dist/cjs/code_executors/unsafe_local_code_executor.js +6 -1
  15. package/dist/cjs/common.js +9 -20
  16. package/dist/cjs/errors/input_validation_error.js +3 -2
  17. package/dist/cjs/index.js +9 -2
  18. package/dist/cjs/plugins/base_plugin.js +13 -23
  19. package/dist/cjs/sessions/base_session_service.js +14 -8
  20. package/dist/cjs/sessions/database_session_service.js +50 -28
  21. package/dist/cjs/sessions/stale_session_error.js +59 -0
  22. package/dist/cjs/skills/loader.js +52 -18
  23. package/dist/cjs/telemetry/setup.js +0 -1
  24. package/dist/cjs/telemetry/tracing.js +53 -10
  25. package/dist/cjs/tools/apihub_tool/apihub_toolset.js +18 -23
  26. package/dist/cjs/tools/application_integration_tool/application_integration_toolset.js +120 -42
  27. package/dist/cjs/tools/application_integration_tool/clients/connections_client.js +163 -95
  28. package/dist/cjs/tools/application_integration_tool/clients/integration_client.js +13 -9
  29. package/dist/cjs/tools/application_integration_tool/integration_connector_tool.js +184 -0
  30. package/dist/cjs/tools/google_api_tool/google_api_tool.js +4 -1
  31. package/dist/cjs/tools/google_api_tool/google_api_toolset.js +173 -0
  32. package/dist/cjs/tools/google_api_tool/google_api_toolsets.js +124 -0
  33. package/dist/cjs/tools/google_api_tool/googleapi_to_openapi_converter.js +2 -2
  34. package/dist/cjs/tools/google_api_tool/index.js +20 -23
  35. package/dist/cjs/tools/load_artifacts_tool.js +12 -6
  36. package/dist/cjs/tools/load_memory_tool.js +12 -10
  37. package/dist/cjs/tools/mcp/mcp_toolset.js +1 -14
  38. package/dist/cjs/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.js +2 -2
  39. package/dist/cjs/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.js +20 -6
  40. package/dist/cjs/tools/openapi_tool/openapi_spec_parser/operation_parser.js +17 -6
  41. package/dist/cjs/tools/openapi_tool/openapi_toolset.js +7 -13
  42. package/dist/cjs/tools/openapi_tool/rest_api_tool.js +17 -1
  43. package/dist/cjs/tools/toolbox_toolset.js +174 -0
  44. package/dist/cjs/tools/webmcp/webmcp_toolset.js +1 -14
  45. package/dist/cjs/utils/client_labels.js +19 -2
  46. package/dist/cjs/utils/failover_utils.js +1 -1
  47. package/dist/cjs/utils/gemini_schema_util.js +24 -6
  48. package/dist/cjs/utils/logger_node.js +4 -0
  49. package/dist/cjs/utils/output_schema_utils.js +5 -2
  50. package/dist/cjs/utils/task.js +1 -1
  51. package/dist/cjs/version.js +1 -1
  52. package/dist/esm/agents/agent_engine_client.js +144 -0
  53. package/dist/esm/agents/base_agent.js +20 -4
  54. package/dist/esm/agents/functions.js +28 -0
  55. package/dist/esm/agents/instructions.js +2 -1
  56. package/dist/esm/agents/llm_agent.js +19 -6
  57. package/dist/esm/agents/processors/basic_llm_request_processor.js +1 -1
  58. package/dist/esm/agents/processors/code_execution_request_processor.js +8 -0
  59. package/dist/esm/agents/processors/content_processor_utils.js +38 -10
  60. package/dist/esm/agents/processors/content_request_processor.js +34 -2
  61. package/dist/esm/agents/processors/instructions_llm_request_processor.js +1 -1
  62. package/dist/esm/agents/processors/nl_planning_processor.js +12 -3
  63. package/dist/esm/cli/utils/logs.js +4 -4
  64. package/dist/esm/code_executors/container_code_executor.js +27 -16
  65. package/dist/esm/code_executors/unsafe_local_code_executor.js +6 -1
  66. package/dist/esm/common.js +10 -13
  67. package/dist/esm/errors/input_validation_error.js +3 -2
  68. package/dist/esm/index.js +17 -3
  69. package/dist/esm/plugins/base_plugin.js +13 -23
  70. package/dist/esm/sessions/base_session_service.js +12 -7
  71. package/dist/esm/sessions/database_session_service.js +49 -28
  72. package/dist/esm/sessions/stale_session_error.js +31 -0
  73. package/dist/esm/skills/loader.js +51 -17
  74. package/dist/esm/telemetry/setup.js +1 -2
  75. package/dist/esm/telemetry/tracing.js +57 -11
  76. package/dist/esm/tools/apihub_tool/apihub_toolset.js +17 -22
  77. package/dist/esm/tools/application_integration_tool/application_integration_toolset.js +124 -42
  78. package/dist/esm/tools/application_integration_tool/clients/connections_client.js +163 -95
  79. package/dist/esm/tools/application_integration_tool/clients/integration_client.js +13 -9
  80. package/dist/esm/tools/application_integration_tool/integration_connector_tool.js +158 -0
  81. package/dist/esm/tools/google_api_tool/google_api_tool.js +4 -1
  82. package/dist/esm/tools/google_api_tool/google_api_toolset.js +146 -0
  83. package/dist/esm/tools/google_api_tool/google_api_toolsets.js +94 -0
  84. package/dist/esm/tools/google_api_tool/googleapi_to_openapi_converter.js +2 -2
  85. package/dist/esm/tools/google_api_tool/index.js +18 -20
  86. package/dist/esm/tools/load_artifacts_tool.js +10 -5
  87. package/dist/esm/tools/load_memory_tool.js +12 -10
  88. package/dist/esm/tools/mcp/mcp_toolset.js +1 -14
  89. package/dist/esm/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.js +2 -2
  90. package/dist/esm/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.js +20 -6
  91. package/dist/esm/tools/openapi_tool/openapi_spec_parser/operation_parser.js +17 -6
  92. package/dist/esm/tools/openapi_tool/openapi_toolset.js +6 -12
  93. package/dist/esm/tools/openapi_tool/rest_api_tool.js +17 -1
  94. package/dist/esm/tools/toolbox_toolset.js +148 -0
  95. package/dist/esm/tools/webmcp/webmcp_toolset.js +1 -14
  96. package/dist/esm/utils/client_labels.js +19 -2
  97. package/dist/esm/utils/failover_utils.js +1 -1
  98. package/dist/esm/utils/gemini_schema_util.js +23 -6
  99. package/dist/esm/utils/logger_node.js +4 -0
  100. package/dist/esm/utils/output_schema_utils.js +5 -2
  101. package/dist/esm/utils/task.js +1 -1
  102. package/dist/esm/version.js +1 -1
  103. package/dist/types/agents/agent_engine_client.d.ts +37 -0
  104. package/dist/types/agents/base_agent.d.ts +12 -0
  105. package/dist/types/agents/llm_agent.d.ts +5 -1
  106. package/dist/types/agents/processors/content_processor_utils.d.ts +4 -2
  107. package/dist/types/agents/processors/nl_planning_processor.d.ts +2 -1
  108. package/dist/types/cli/utils/logs.d.ts +1 -1
  109. package/dist/types/code_executors/container_code_executor.d.ts +17 -5
  110. package/dist/types/common.d.ts +5 -9
  111. package/dist/types/errors/input_validation_error.d.ts +2 -1
  112. package/dist/types/index.d.ts +4 -2
  113. package/dist/types/plugins/base_plugin.d.ts +0 -10
  114. package/dist/types/sessions/base_session_service.d.ts +5 -0
  115. package/dist/types/sessions/database_session_service.d.ts +17 -1
  116. package/dist/types/sessions/stale_session_error.d.ts +21 -0
  117. package/dist/types/skills/loader.d.ts +3 -2
  118. package/dist/types/telemetry/tracing.d.ts +17 -3
  119. package/dist/types/tools/apihub_tool/apihub_toolset.d.ts +14 -21
  120. package/dist/types/tools/application_integration_tool/application_integration_toolset.d.ts +32 -9
  121. package/dist/types/tools/application_integration_tool/clients/connections_client.d.ts +22 -8
  122. package/dist/types/tools/application_integration_tool/clients/integration_client.d.ts +3 -3
  123. package/dist/types/tools/application_integration_tool/integration_connector_tool.d.ts +70 -0
  124. package/dist/types/tools/base_toolset.d.ts +6 -5
  125. package/dist/types/tools/google_api_tool/google_api_tool.d.ts +10 -3
  126. package/dist/types/tools/google_api_tool/google_api_toolset.d.ts +55 -0
  127. package/dist/types/tools/google_api_tool/google_api_toolsets.d.ts +48 -0
  128. package/dist/types/tools/google_api_tool/googleapi_to_openapi_converter.d.ts +5 -4
  129. package/dist/types/tools/google_api_tool/index.d.ts +4 -5
  130. package/dist/types/tools/load_artifacts_tool.d.ts +14 -1
  131. package/dist/types/tools/load_memory_tool.d.ts +23 -1
  132. package/dist/types/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.d.ts +12 -0
  133. package/dist/types/tools/openapi_tool/openapi_spec_parser/operation_parser.d.ts +8 -0
  134. package/dist/types/tools/openapi_tool/openapi_toolset.d.ts +5 -0
  135. package/dist/types/tools/openapi_tool/rest_api_tool.d.ts +10 -0
  136. package/dist/types/tools/toolbox_toolset.d.ts +159 -0
  137. package/dist/types/utils/client_labels.d.ts +2 -1
  138. package/dist/types/utils/gemini_schema_util.d.ts +8 -0
  139. package/dist/types/utils/output_schema_utils.d.ts +3 -2
  140. package/dist/types/utils/simple_zod_to_json.d.ts +1 -2
  141. package/dist/types/version.d.ts +1 -1
  142. package/dist/web/index_web.js +74 -66
  143. package/dist/web/index_web.js.map +4 -4
  144. package/package.json +34 -27
  145. package/dist/cjs/agents/remote_agent.js +0 -187
  146. package/dist/cjs/tools/crewai_tool.js +0 -132
  147. package/dist/cjs/tools/google_api_tool/google_api_tool_set.js +0 -226
  148. package/dist/cjs/tools/google_api_tool/google_api_tool_sets.js +0 -58
  149. package/dist/cjs/tools/langchain_tool.js +0 -172
  150. package/dist/cjs/tools/toolbox_tool.js +0 -108
  151. package/dist/esm/agents/remote_agent.js +0 -164
  152. package/dist/esm/tools/crewai_tool.js +0 -107
  153. package/dist/esm/tools/google_api_tool/google_api_tool_set.js +0 -188
  154. package/dist/esm/tools/google_api_tool/google_api_tool_sets.js +0 -24
  155. package/dist/esm/tools/langchain_tool.js +0 -148
  156. package/dist/esm/tools/toolbox_tool.js +0 -80
  157. package/dist/types/agents/remote_agent.d.ts +0 -68
  158. package/dist/types/tools/crewai_tool.d.ts +0 -85
  159. package/dist/types/tools/google_api_tool/google_api_tool_set.d.ts +0 -78
  160. package/dist/types/tools/google_api_tool/google_api_tool_sets.d.ts +0 -33
  161. package/dist/types/tools/langchain_tool.d.ts +0 -103
  162. package/dist/types/tools/toolbox_tool.d.ts +0 -73
package/dist/esm/index.js CHANGED
@@ -30,7 +30,11 @@ import {
30
30
  DebugLoggingPlugin,
31
31
  isDebugLoggingPlugin
32
32
  } from "./plugins/debug_logging_plugin.js";
33
- import { DatabaseSessionService } from "./sessions/database_session_service.js";
33
+ import {
34
+ DatabaseSessionService,
35
+ isStaleSessionError,
36
+ StaleSessionError
37
+ } from "./sessions/database_session_service.js";
34
38
  import { getSessionServiceFromUri } from "./sessions/registry.js";
35
39
  import { VertexAiSessionService } from "./sessions/vertex_ai_session_service.js";
36
40
  import { GCPSkillRegistry } from "./skills/gcp_skill_registry.js";
@@ -74,6 +78,9 @@ import {
74
78
  import {
75
79
  IntegrationClient
76
80
  } from "./tools/application_integration_tool/clients/integration_client.js";
81
+ import {
82
+ IntegrationConnectorTool
83
+ } from "./tools/application_integration_tool/integration_connector_tool.js";
77
84
  import { LOAD_WEB_PAGE, loadWebPage } from "./tools/load_web_page.js";
78
85
  import {
79
86
  credentialToParam,
@@ -141,7 +148,11 @@ import {
141
148
  tryGetResetFunc
142
149
  } from "./cli/cli_eval.js";
143
150
  import { loadDotenvForAgent, walkToRootUntilFound } from "./cli/utils/envs.js";
144
- import { LOGGING_FORMAT, logToStderr, logToTmpFolder } from "./cli/utils/logs.js";
151
+ import {
152
+ LOGGING_FORMAT,
153
+ logToTmpFolder,
154
+ setupAdkLogger
155
+ } from "./cli/utils/logs.js";
145
156
  export * from "./tools/mcp/index.js";
146
157
  export {
147
158
  APIHubClient,
@@ -166,6 +177,7 @@ export {
166
177
  GcsArtifactService,
167
178
  INTERNAL_AUTH_PREFIX,
168
179
  IntegrationClient,
180
+ IntegrationConnectorTool,
169
181
  InvocationContext,
170
182
  LOAD_WEB_PAGE,
171
183
  LOGGING_FORMAT,
@@ -185,6 +197,7 @@ export {
185
197
  SecretManagerClient,
186
198
  ServiceAccountCredentialExchanger,
187
199
  SkillToolset,
200
+ StaleSessionError,
188
201
  TOOL_TRAJECTORY_SCORE_KEY,
189
202
  ToolAuthHandler,
190
203
  ToolContextCredentialStore,
@@ -218,6 +231,7 @@ export {
218
231
  getSessionServiceFromUri,
219
232
  getTypeHint,
220
233
  isDebugLoggingPlugin,
234
+ isStaleSessionError,
221
235
  listOperation,
222
236
  listOperationRequest,
223
237
  loadAllSkillsInDir,
@@ -225,7 +239,6 @@ export {
225
239
  loadSkillFromDir,
226
240
  loadSkillFromZipBuffer,
227
241
  loadWebPage,
228
- logToStderr,
229
242
  logToTmpFolder,
230
243
  openidDictToSchemeCredential,
231
244
  openidUrlToSchemeCredential,
@@ -233,6 +246,7 @@ export {
233
246
  runEvals,
234
247
  serviceAccountDictToSchemeCredential,
235
248
  serviceAccountSchemeCredential,
249
+ setupAdkLogger,
236
250
  tokenToSchemeCredential,
237
251
  tryGetResetFunc,
238
252
  updateOperation,
@@ -246,29 +246,19 @@ const _BasePlugin = class _BasePlugin {
246
246
  return;
247
247
  }
248
248
  /**
249
- * Callback executed when a tool call encounters an error.
250
- tool: BaseTool;
251
- toolArgs: Record<string, unknown>;
252
- toolContext: Context;
253
- result: Record<string, unknown>;
254
- }): Promise<Record<string, unknown> | undefined> {
255
- return;
256
- }
257
-
258
- /**
259
- * Callback executed when a tool call encounters an error.
260
- *
261
- * This callback provides an opportunity to handle tool errors gracefully,
262
- * potentially providing alternative responses or recovery mechanisms.
263
- *
264
- * @param _params.tool The tool instance that encountered an error.
265
- * @param _params.toolArgs The arguments that were passed to the tool.
266
- * @param _params.toolContext The context specific to the tool execution.
267
- * @param _params.error The exception that was raised during tool execution.
268
- * @returns An optional dictionary. If a dictionary is returned, it will be
269
- * used as the tool response instead of propagating the error. Returning
270
- * `undefined` allows the original error to be raised.
271
- */
249
+ * Callback executed when a tool call encounters an error.
250
+ *
251
+ * This callback provides an opportunity to handle tool errors gracefully,
252
+ * potentially providing alternative responses or recovery mechanisms.
253
+ *
254
+ * @param _params.tool The tool instance that encountered an error.
255
+ * @param _params.toolArgs The arguments that were passed to the tool.
256
+ * @param _params.toolContext The context specific to the tool execution.
257
+ * @param _params.error The exception that was raised during tool execution.
258
+ * @returns An optional dictionary. If a dictionary is returned, it will be
259
+ * used as the tool response instead of propagating the error. Returning
260
+ * `undefined` allows the original error to be raised.
261
+ */
272
262
  async onToolErrorCallback(_params) {
273
263
  return;
274
264
  }
@@ -43,12 +43,7 @@ const _BaseSessionService = class _BaseSessionService {
43
43
  }
44
44
  event = trimTempDeltaState(event);
45
45
  this.updateSessionState({ session, event });
46
- const index = session.events.findIndex((e) => e.id === event.id);
47
- if (index >= 0) {
48
- session.events[index] = event;
49
- } else {
50
- session.events.push(event);
51
- }
46
+ upsertSessionEvent(session, event);
52
47
  return event;
53
48
  }
54
49
  /**
@@ -78,6 +73,15 @@ const _BaseSessionService = class _BaseSessionService {
78
73
  };
79
74
  __name(_BaseSessionService, "BaseSessionService");
80
75
  let BaseSessionService = _BaseSessionService;
76
+ function upsertSessionEvent(session, event) {
77
+ const index = session.events.findIndex((e) => e.id === event.id);
78
+ if (index >= 0) {
79
+ session.events[index] = event;
80
+ } else {
81
+ session.events.push(event);
82
+ }
83
+ }
84
+ __name(upsertSessionEvent, "upsertSessionEvent");
81
85
  function trimTempDeltaState(event) {
82
86
  if (!event.actions || !event.actions.stateDelta) {
83
87
  return event;
@@ -119,5 +123,6 @@ export {
119
123
  BaseSessionService,
120
124
  mergeStates,
121
125
  trimTempDeltaState,
122
- trimTempState
126
+ trimTempState,
127
+ upsertSessionEvent
123
128
  };
@@ -29,12 +29,15 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  * SPDX-License-Identifier: Apache-2.0
30
30
  */
31
31
  import { randomUUID } from "../utils/env_aware_utils.js";
32
+ import { logger } from "../utils/logger.js";
32
33
  import {
33
34
  BaseSessionService,
34
35
  mergeStates,
35
- trimTempDeltaState
36
+ trimTempDeltaState,
37
+ upsertSessionEvent
36
38
  } from "./base_session_service.js";
37
39
  import { createSession } from "./session.js";
40
+ import { StaleSessionError } from "./stale_session_error.js";
38
41
  import { State } from "./state.js";
39
42
  let MikroORM;
40
43
  let LockMode;
@@ -67,6 +70,12 @@ async function importMikroOrm() {
67
70
  } = operations);
68
71
  }
69
72
  __name(importMikroOrm, "importMikroOrm");
73
+ import { isStaleSessionError, StaleSessionError as StaleSessionError2 } from "./stale_session_error.js";
74
+ function formatDateTime(dateOrEpochMs) {
75
+ const date = typeof dateOrEpochMs === "number" ? new Date(dateOrEpochMs) : dateOrEpochMs;
76
+ return date.toISOString().replace("T", " ").slice(0, 19);
77
+ }
78
+ __name(formatDateTime, "formatDateTime");
70
79
  function isDatabaseConnectionString(uri) {
71
80
  if (!uri) {
72
81
  return false;
@@ -75,16 +84,20 @@ function isDatabaseConnectionString(uri) {
75
84
  }
76
85
  __name(isDatabaseConnectionString, "isDatabaseConnectionString");
77
86
  const _DatabaseSessionService = class _DatabaseSessionService extends BaseSessionService {
78
- constructor(connectionStringOrOptions) {
87
+ constructor(connectionStringOrOptions, options) {
88
+ var _a;
79
89
  super();
80
90
  this.initialized = false;
81
91
  if (typeof connectionStringOrOptions === "string") {
82
92
  this.connectionString = connectionStringOrOptions;
93
+ this.staleSession = (_a = options == null ? void 0 : options.staleSession) != null ? _a : "reject";
83
94
  } else {
84
95
  if (!connectionStringOrOptions.driver) {
85
96
  throw new Error("Driver is required when passing options object.");
86
97
  }
87
- this.options = connectionStringOrOptions;
98
+ const { staleSession, ...mikroOptions } = connectionStringOrOptions;
99
+ this.options = mikroOptions;
100
+ this.staleSession = staleSession != null ? staleSession : "reject";
88
101
  }
89
102
  }
90
103
  async init() {
@@ -330,6 +343,7 @@ const _DatabaseSessionService = class _DatabaseSessionService extends BaseSessio
330
343
  return event;
331
344
  }
332
345
  const trimmedEvent = trimTempDeltaState(event);
346
+ let sessionWasStale = false;
333
347
  await em.transactional(async (txEm) => {
334
348
  const storageSession = await txEm.findOne(
335
349
  StorageSession,
@@ -343,6 +357,14 @@ const _DatabaseSessionService = class _DatabaseSessionService extends BaseSessio
343
357
  if (!storageSession) {
344
358
  throw new Error(`Session ${session.id} not found for appendEvent`);
345
359
  }
360
+ if (storageSession.updateTime.getTime() > session.lastUpdateTime) {
361
+ if (this.staleSession === "reject") {
362
+ throw new StaleSessionError(
363
+ `The last_update_time provided in the session object ${formatDateTime(session.lastUpdateTime)} is earlier than the update_time in the storage_session ${formatDateTime(storageSession.updateTime)}. Please check if it is a stale session.`
364
+ );
365
+ }
366
+ sessionWasStale = true;
367
+ }
346
368
  let appStateModel = await txEm.findOne(StorageAppState, {
347
369
  appName: session.appName
348
370
  });
@@ -366,24 +388,6 @@ const _DatabaseSessionService = class _DatabaseSessionService extends BaseSessio
366
388
  });
367
389
  txEm.persist(userStateModel);
368
390
  }
369
- if (storageSession.updateTime.getTime() > session.lastUpdateTime) {
370
- const events = await txEm.find(
371
- StorageEvent,
372
- {
373
- appName: session.appName,
374
- userId: session.userId,
375
- sessionId: session.id
376
- },
377
- { orderBy: { timestamp: "ASC" } }
378
- );
379
- const mergedState = mergeStates(
380
- appStateModel.state,
381
- userStateModel.state,
382
- storageSession.state
383
- );
384
- session.state = mergedState;
385
- session.events = events.map((e) => e.eventData);
386
- }
387
391
  if (event.actions && event.actions.stateDelta) {
388
392
  const appDelta = {};
389
393
  const userDelta = {};
@@ -437,14 +441,29 @@ const _DatabaseSessionService = class _DatabaseSessionService extends BaseSessio
437
441
  storageSession.state
438
442
  );
439
443
  session.state = newMergedState;
440
- const index = session.events.findIndex((e) => e.id === event.id);
441
- if (index >= 0) {
442
- session.events[index] = event;
443
- } else {
444
- session.events.push(event);
445
- }
444
+ upsertSessionEvent(session, event);
446
445
  session.lastUpdateTime = storageSession.updateTime.getTime();
447
446
  });
447
+ if (sessionWasStale) {
448
+ try {
449
+ const storageEvents = await em.find(
450
+ StorageEvent,
451
+ {
452
+ appName: session.appName,
453
+ userId: session.userId,
454
+ sessionId: session.id
455
+ },
456
+ { orderBy: { timestamp: "ASC" } }
457
+ );
458
+ session.events = storageEvents.map((se) => se.eventData);
459
+ upsertSessionEvent(session, event);
460
+ } catch (e) {
461
+ const message = e instanceof Error ? e.message : String(e);
462
+ logger.warn(
463
+ `Failed to reload events for stale session ${session.id} after appendEvent; the event was persisted but session.events may be missing concurrent appends: ${message}`
464
+ );
465
+ }
466
+ }
448
467
  return event;
449
468
  }
450
469
  };
@@ -452,5 +471,7 @@ __name(_DatabaseSessionService, "DatabaseSessionService");
452
471
  let DatabaseSessionService = _DatabaseSessionService;
453
472
  export {
454
473
  DatabaseSessionService,
455
- isDatabaseConnectionString
474
+ StaleSessionError2 as StaleSessionError,
475
+ isDatabaseConnectionString,
476
+ isStaleSessionError
456
477
  };
@@ -0,0 +1,31 @@
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, _b;
11
+ const STALE_SESSION_ERROR_SIGNATURE_SYMBOL = /* @__PURE__ */ Symbol.for(
12
+ "google.adk.staleSessionError"
13
+ );
14
+ const _StaleSessionError = class _StaleSessionError extends (_b = Error, _a = STALE_SESSION_ERROR_SIGNATURE_SYMBOL, _b) {
15
+ constructor(message) {
16
+ super(message);
17
+ this[_a] = true;
18
+ this.name = "StaleSessionError";
19
+ Object.setPrototypeOf(this, _StaleSessionError.prototype);
20
+ }
21
+ };
22
+ __name(_StaleSessionError, "StaleSessionError");
23
+ let StaleSessionError = _StaleSessionError;
24
+ function isStaleSessionError(obj) {
25
+ return typeof obj === "object" && obj !== null && (STALE_SESSION_ERROR_SIGNATURE_SYMBOL in obj || obj instanceof Error && obj.name === "StaleSessionError");
26
+ }
27
+ __name(isStaleSessionError, "isStaleSessionError");
28
+ export {
29
+ StaleSessionError,
30
+ isStaleSessionError
31
+ };
@@ -8,10 +8,12 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
8
8
  * SPDX-License-Identifier: Apache-2.0
9
9
  */
10
10
  import AdmZip from "adm-zip";
11
- import yaml from "js-yaml";
11
+ import * as yaml from "js-yaml";
12
12
  import { isUtf8 } from "node:buffer";
13
13
  import * as fs from "node:fs/promises";
14
14
  import * as path from "node:path";
15
+ import { InputValidationError } from "../errors/input_validation_error.js";
16
+ import { NotFoundError } from "../errors/not_found_error.js";
15
17
  import { logger } from "../utils/logger.js";
16
18
  import {
17
19
  FrontmatterSchema
@@ -88,24 +90,37 @@ async function loadDir(directoryPath) {
88
90
  return files;
89
91
  }
90
92
  __name(loadDir, "loadDir");
93
+ const FRONTMATTER_BOM = "\uFEFF";
94
+ const FRONTMATTER_PATTERN = /^---[ \t]*\r?\n(?:([\s\S]*?)\r?\n)??---[ \t]*(?:\r?\n|$)/;
91
95
  function parseFrontmatterYaml(content) {
92
- if (!content.startsWith("---")) {
93
- throw new Error("SKILL.md must start with YAML frontmatter (---)");
96
+ var _a;
97
+ const text = content.startsWith(FRONTMATTER_BOM) ? content.slice(FRONTMATTER_BOM.length) : content;
98
+ if (!text.startsWith("---")) {
99
+ throw new InputValidationError(
100
+ "SKILL.md must start with YAML frontmatter (---)"
101
+ );
94
102
  }
95
- const parts = content.split("---");
96
- if (parts.length < 3) {
97
- throw new Error("SKILL.md frontmatter not properly closed with ---");
103
+ const match = FRONTMATTER_PATTERN.exec(text);
104
+ if (!match) {
105
+ throw new InputValidationError(
106
+ "SKILL.md frontmatter not properly closed with ---"
107
+ );
98
108
  }
99
- const frontmatterStr = parts[1];
100
- const body = parts.filter((_, i) => i >= 2).join("---").trim();
109
+ const frontmatterStr = (_a = match[1]) != null ? _a : "";
110
+ const body = text.slice(match[0].length).trim();
101
111
  try {
102
112
  const parsed = yaml.load(frontmatterStr);
103
113
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
104
- throw new Error("SKILL.md frontmatter must be a YAML mapping");
114
+ throw new InputValidationError(
115
+ "SKILL.md frontmatter must be a YAML mapping"
116
+ );
105
117
  }
106
118
  return { raw: parsed, body };
107
119
  } catch (e) {
108
- throw new Error(`Invalid YAML in frontmatter: ${e.message}`);
120
+ throw new InputValidationError(
121
+ `Invalid YAML in frontmatter: ${e.message}`,
122
+ { cause: e }
123
+ );
109
124
  }
110
125
  }
111
126
  __name(parseFrontmatterYaml, "parseFrontmatterYaml");
@@ -113,7 +128,10 @@ function validateFrontmatter(raw) {
113
128
  try {
114
129
  return FrontmatterSchema.parse(raw);
115
130
  } catch (e) {
116
- throw new Error(`Invalid YAML in frontmatter: ${e.message}`);
131
+ throw new InputValidationError(
132
+ `Invalid YAML in frontmatter: ${e.message}`,
133
+ { cause: e }
134
+ );
117
135
  }
118
136
  }
119
137
  __name(validateFrontmatter, "validateFrontmatter");
@@ -160,6 +178,18 @@ __name(loadSkillFromDir, "loadSkillFromDir");
160
178
  async function validateSkillDir(skillDir) {
161
179
  const problems = [];
162
180
  const resolvedDir = path.resolve(skillDir);
181
+ try {
182
+ const stats = await fs.stat(resolvedDir);
183
+ if (!stats.isDirectory()) {
184
+ return [`'${resolvedDir}' is not a directory.`];
185
+ }
186
+ } catch (e) {
187
+ const code = e.code;
188
+ if (code === "ENOENT" || code === "ENOTDIR") {
189
+ return [`Directory '${resolvedDir}' does not exist.`];
190
+ }
191
+ return [`Failed to access '${resolvedDir}': ${e.message}`];
192
+ }
163
193
  let skill;
164
194
  try {
165
195
  skill = await loadSkillFile(resolvedDir);
@@ -209,7 +239,7 @@ async function loadSkillFile(skillDir) {
209
239
  );
210
240
  }
211
241
  if (!skillMdPath) {
212
- throw new Error(
242
+ throw new NotFoundError(
213
243
  `SKILL.md (or any case variation like skill.md) not found in '${skillDir}'.`
214
244
  );
215
245
  }
@@ -217,7 +247,7 @@ async function loadSkillFile(skillDir) {
217
247
  const frontmatter = FrontmatterSchema.parse(parsed);
218
248
  const dirName = path.basename(resolvedDir);
219
249
  if (dirName !== frontmatter.name) {
220
- throw new Error(
250
+ throw new InputValidationError(
221
251
  `Skill name '${frontmatter.name}' does not match directory name '${dirName}'.`
222
252
  );
223
253
  }
@@ -279,7 +309,9 @@ function loadSkillFromZipBuffer(zipBuffer) {
279
309
  const entries = zip.getEntries();
280
310
  for (const entry of entries) {
281
311
  if (isDangerousZipEntryName(entry.entryName)) {
282
- throw new Error(`Dangerous zip entry ignored: ${entry.entryName}`);
312
+ throw new InputValidationError(
313
+ `Dangerous zip entry ignored: ${entry.entryName}`
314
+ );
283
315
  }
284
316
  }
285
317
  let skillMdContent = "";
@@ -291,15 +323,17 @@ function loadSkillFromZipBuffer(zipBuffer) {
291
323
  }
292
324
  }
293
325
  if (!skillMdContent) {
294
- throw new Error("SKILL.md not found in zipped filesystem.");
326
+ throw new NotFoundError("SKILL.md not found in zipped filesystem.");
295
327
  }
296
328
  const { raw, body } = parseFrontmatterYaml(skillMdContent);
297
329
  const skillName = raw["name"];
298
330
  if (!skillName) {
299
- throw new Error("SKILL.md frontmatter must contain 'name'");
331
+ throw new InputValidationError("SKILL.md frontmatter must contain 'name'");
300
332
  }
301
333
  if (typeof skillName !== "string" || !isBareSkillName(skillName)) {
302
- throw new Error(`Invalid skill name in SKILL.md: ${String(skillName)}`);
334
+ throw new InputValidationError(
335
+ `Invalid skill name in SKILL.md: ${String(skillName)}`
336
+ );
303
337
  }
304
338
  const frontmatter = validateFrontmatter(raw);
305
339
  const references = {};
@@ -7,7 +7,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
7
7
  * Copyright 2025 Google LLC
8
8
  * SPDX-License-Identifier: Apache-2.0
9
9
  */
10
- import { metrics, trace } from "@opentelemetry/api";
10
+ import { metrics } from "@opentelemetry/api";
11
11
  import { logs } from "@opentelemetry/api-logs";
12
12
  import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
13
13
  import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
@@ -39,7 +39,6 @@ function maybeSetOtelProviders(otelHooksToSetup = [], otelResource) {
39
39
  spanProcessors
40
40
  });
41
41
  tracerProvider.register();
42
- trace.setGlobalTracerProvider(tracerProvider);
43
42
  }
44
43
  if (metricReaders.length > 0) {
45
44
  const meterProvider = new MeterProvider({
@@ -7,7 +7,12 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
7
7
  * Copyright 2025 Google LLC
8
8
  * SPDX-License-Identifier: Apache-2.0
9
9
  */
10
- import { context, trace } from "@opentelemetry/api";
10
+ import { ApiError } from "@google/genai";
11
+ import {
12
+ context,
13
+ SpanStatusCode,
14
+ trace
15
+ } from "@opentelemetry/api";
11
16
  import { version } from "../version.js";
12
17
  var GenAiAttr = /* @__PURE__ */ ((GenAiAttr2) => {
13
18
  GenAiAttr2["AGENT_DESCRIPTION"] = "gen_ai.agent.description";
@@ -106,15 +111,55 @@ function traceNodeExecution({
106
111
  });
107
112
  }
108
113
  __name(traceNodeExecution, "traceNodeExecution");
109
- function traceToolCall({
110
- tool,
111
- args,
112
- functionResponseEvent,
113
- invocationContext
114
- }) {
114
+ function resolveErrorType(error) {
115
115
  var _a, _b;
116
- const span = trace.getActiveSpan();
116
+ if (error !== null && (typeof error === "object" || typeof error === "function")) {
117
+ try {
118
+ const errorObject = error;
119
+ const customErrorType = (_a = errorObject.errorType) != null ? _a : errorObject.error_type;
120
+ if (typeof customErrorType === "string" || typeof customErrorType === "number") {
121
+ return String(customErrorType);
122
+ }
123
+ if (error instanceof ApiError) {
124
+ return String(error.status);
125
+ }
126
+ const constructorName = (_b = errorObject.constructor) == null ? void 0 : _b.name;
127
+ if (typeof constructorName === "string" && constructorName.length > 0) {
128
+ return constructorName;
129
+ }
130
+ } catch {
131
+ }
132
+ }
133
+ return typeof error;
134
+ }
135
+ __name(resolveErrorType, "resolveErrorType");
136
+ function traceToolCall(params) {
137
+ var _a, _b, _c;
138
+ const {
139
+ tool,
140
+ args,
141
+ functionResponseEvent,
142
+ invocationContext,
143
+ error,
144
+ errorType
145
+ } = params;
146
+ const span = (_a = params.span) != null ? _a : trace.getActiveSpan();
117
147
  if (!span) return;
148
+ const hasError = Object.hasOwn(params, "error");
149
+ const failureType = hasError ? resolveErrorType(error) : errorType;
150
+ if (hasError) {
151
+ let exception;
152
+ try {
153
+ exception = error instanceof Error ? error : resolveErrorType(error);
154
+ } catch {
155
+ exception = resolveErrorType(error);
156
+ }
157
+ span.recordException(exception);
158
+ }
159
+ if (failureType !== void 0) {
160
+ span.setAttribute("error.type", failureType);
161
+ span.setStatus({ code: SpanStatusCode.ERROR, message: failureType });
162
+ }
118
163
  span.setAttributes({
119
164
  ["gen_ai.operation.name" /* OPERATION_NAME */]: "execute_tool",
120
165
  ["gen_ai.system" /* SYSTEM */]: GEN_AI_SYSTEM_VALUE,
@@ -131,9 +176,9 @@ function traceToolCall({
131
176
  });
132
177
  let toolCallId = "<not specified>";
133
178
  let toolResponse = "<not specified>";
134
- if ((_a = functionResponseEvent.content) == null ? void 0 : _a.parts) {
179
+ if ((_b = functionResponseEvent == null ? void 0 : functionResponseEvent.content) == null ? void 0 : _b.parts) {
135
180
  const responseParts = functionResponseEvent.content.parts;
136
- const functionResponse = (_b = responseParts[0]) == null ? void 0 : _b.functionResponse;
181
+ const functionResponse = (_c = responseParts[0]) == null ? void 0 : _c.functionResponse;
137
182
  if (functionResponse == null ? void 0 : functionResponse.id) {
138
183
  toolCallId = functionResponse.id;
139
184
  }
@@ -146,7 +191,7 @@ function traceToolCall({
146
191
  }
147
192
  span.setAttributes({
148
193
  ["gen_ai.tool.call.id" /* TOOL_CALL_ID */]: toolCallId,
149
- ["gcp.vertex.agent.event_id" /* EVENT_ID */]: functionResponseEvent.id,
194
+ ...functionResponseEvent ? { ["gcp.vertex.agent.event_id" /* EVENT_ID */]: functionResponseEvent.id } : {},
150
195
  ["gcp.vertex.agent.tool_response" /* TOOL_RESPONSE */]: shouldAddRequestResponseToSpans() ? safeJsonSerialize(toolResponse) : "{}"
151
196
  });
152
197
  }
@@ -303,6 +348,7 @@ function shouldAddRequestResponseToSpans() {
303
348
  }
304
349
  __name(shouldAddRequestResponseToSpans, "shouldAddRequestResponseToSpans");
305
350
  export {
351
+ resolveErrorType,
306
352
  runAsyncGeneratorWithOtelContext,
307
353
  traceAgentInvocation,
308
354
  traceCallLlm,
@@ -16,7 +16,7 @@ var __decorateClass = (decorators, target, key, kind) => {
16
16
  * Copyright 2026 Google LLC
17
17
  * SPDX-License-Identifier: Apache-2.0
18
18
  */
19
- import yaml from "js-yaml";
19
+ import * as yaml from "js-yaml";
20
20
  import { toSnakeCaseName } from "../../utils/case_utils.js";
21
21
  import { experimental } from "../../utils/experimental.js";
22
22
  import { BaseToolset } from "../base_toolset.js";
@@ -24,15 +24,15 @@ import { OpenAPIToolset } from "../openapi_tool/openapi_toolset.js";
24
24
  import { APIHubClient } from "./clients/apihub_client.js";
25
25
  let APIHubToolset = class extends BaseToolset {
26
26
  constructor(options) {
27
- var _a, _b, _c, _d;
28
- super([]);
29
- this.name = (_a = options.name) != null ? _a : "";
30
- this.description = (_b = options.description) != null ? _b : "";
27
+ var _a, _b, _c, _d, _e;
28
+ super((_a = options.toolFilter) != null ? _a : []);
29
+ this.name = (_b = options.name) != null ? _b : "";
30
+ this.description = (_c = options.description) != null ? _c : "";
31
31
  this.apihubResourceName = options.apihubResourceName;
32
- this.lazyLoadSpec = (_c = options.lazyLoadSpec) != null ? _c : false;
32
+ this.lazyLoadSpec = (_d = options.lazyLoadSpec) != null ? _d : false;
33
33
  this.authScheme = options.authScheme;
34
34
  this.authCredential = options.authCredential;
35
- this.apihubClient = (_d = options.apihubClient) != null ? _d : new APIHubClient({
35
+ this.apihubClient = (_e = options.apihubClient) != null ? _e : new APIHubClient({
36
36
  accessToken: options.accessToken,
37
37
  serviceAccountJson: options.serviceAccountJson
38
38
  });
@@ -51,21 +51,12 @@ let APIHubToolset = class extends BaseToolset {
51
51
  const toolset = await this.loadToolset();
52
52
  return toolset ? toolset.getTools(context) : [];
53
53
  }
54
- /**
55
- * Returns the tool with the given name, or `undefined` when the spec
56
- * produced no such tool.
57
- *
58
- * Unlike `OpenAPIToolset.getTool`, the result is a Promise, because the spec
59
- * may still be loading.
60
- *
61
- * @param name The tool name, which is the operation ID in snake_case.
62
- * @throws When the spec cannot be fetched or is not valid YAML or JSON.
63
- */
64
- async getTool(name) {
65
- const toolset = await this.loadToolset();
66
- return toolset == null ? void 0 : toolset.getTool(name);
67
- }
68
54
  async close() {
55
+ if (!this.toolsetPromise) {
56
+ return;
57
+ }
58
+ const toolset = await this.toolsetPromise.catch(() => void 0);
59
+ await (toolset == null ? void 0 : toolset.close());
69
60
  }
70
61
  loadToolset() {
71
62
  if (!this.toolsetPromise) {
@@ -84,6 +75,9 @@ let APIHubToolset = class extends BaseToolset {
84
75
  const spec = await this.apihubClient.getSpecContent(
85
76
  this.apihubResourceName
86
77
  );
78
+ if (!spec.trim()) {
79
+ return void 0;
80
+ }
87
81
  const specDict = yaml.load(spec);
88
82
  if (!specDict) {
89
83
  return void 0;
@@ -93,7 +87,8 @@ let APIHubToolset = class extends BaseToolset {
93
87
  return new OpenAPIToolset({
94
88
  specDict,
95
89
  authScheme: this.authScheme,
96
- authCredential: this.authCredential
90
+ authCredential: this.authCredential,
91
+ toolFilter: this.toolFilter
97
92
  });
98
93
  }
99
94
  };