@google/adk 1.5.0 → 1.6.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 (129) hide show
  1. package/dist/cjs/a2a/a2a_remote_agent.js +12 -2
  2. package/dist/cjs/a2a/agent_to_a2a.js +0 -1
  3. package/dist/cjs/a2a/auth.js +65 -0
  4. package/dist/cjs/a2a/event_converter_utils.js +40 -15
  5. package/dist/cjs/agents/functions.js +20 -7
  6. package/dist/cjs/agents/llm_agent.js +2 -1
  7. package/dist/cjs/agents/processors/basic_llm_request_processor.js +3 -2
  8. package/dist/cjs/agents/processors/content_request_processor.js +2 -21
  9. package/dist/cjs/agents/processors/instructions_llm_request_processor.js +3 -1
  10. package/dist/cjs/artifacts/in_memory_artifact_service.js +10 -9
  11. package/dist/cjs/auth/credential_service/in_memory_credential_service.js +14 -3
  12. package/dist/cjs/code_executors/unsafe_local_code_executor.js +23 -12
  13. package/dist/cjs/common.js +6 -0
  14. package/dist/cjs/context/agent_controlled_context_compactor.js +2 -11
  15. package/dist/cjs/context/compaction_utils.js +14 -2
  16. package/dist/cjs/context/token_based_context_compactor.js +2 -20
  17. package/dist/cjs/index.js +3 -0
  18. package/dist/cjs/memory/in_memory_memory_service.js +13 -2
  19. package/dist/cjs/memory/vertex_ai_memory_bank_service.js +3 -0
  20. package/dist/cjs/plugins/base_plugin.js +4 -2
  21. package/dist/cjs/runner/runner.js +18 -11
  22. package/dist/cjs/sessions/base_session_service.js +8 -3
  23. package/dist/cjs/sessions/in_memory_session_service.js +8 -8
  24. package/dist/cjs/sessions/vertex_ai_session_service.js +22 -10
  25. package/dist/cjs/skills/loader.js +40 -6
  26. package/dist/cjs/tools/get_user_choice_tool.js +53 -0
  27. package/dist/cjs/tools/mcp/mcp_session_manager.js +35 -21
  28. package/dist/cjs/tools/request_input_tool.js +54 -0
  29. package/dist/cjs/utils/crypto_shim.js +43 -0
  30. package/dist/cjs/utils/env_aware_utils.js +15 -13
  31. package/dist/cjs/utils/error_utils.js +120 -0
  32. package/dist/cjs/utils/file_utils.js +5 -2
  33. package/dist/cjs/utils/output_schema_utils.js +43 -0
  34. package/dist/cjs/utils/vertex_ai_utils.js +3 -0
  35. package/dist/cjs/version.js +1 -1
  36. package/dist/esm/a2a/a2a_remote_agent.js +12 -2
  37. package/dist/esm/a2a/agent_to_a2a.js +0 -1
  38. package/dist/esm/a2a/auth.js +37 -0
  39. package/dist/esm/a2a/event_converter_utils.js +40 -15
  40. package/dist/esm/agents/functions.js +20 -7
  41. package/dist/esm/agents/llm_agent.js +2 -1
  42. package/dist/esm/agents/processors/basic_llm_request_processor.js +3 -2
  43. package/dist/esm/agents/processors/content_request_processor.js +2 -21
  44. package/dist/esm/agents/processors/instructions_llm_request_processor.js +3 -1
  45. package/dist/esm/artifacts/in_memory_artifact_service.js +10 -9
  46. package/dist/esm/auth/credential_service/in_memory_credential_service.js +14 -3
  47. package/dist/esm/code_executors/unsafe_local_code_executor.js +22 -11
  48. package/dist/esm/common.js +4 -0
  49. package/dist/esm/context/agent_controlled_context_compactor.js +2 -11
  50. package/dist/esm/context/compaction_utils.js +12 -1
  51. package/dist/esm/context/token_based_context_compactor.js +6 -21
  52. package/dist/esm/index.js +2 -0
  53. package/dist/esm/memory/in_memory_memory_service.js +13 -2
  54. package/dist/esm/memory/vertex_ai_memory_bank_service.js +7 -1
  55. package/dist/esm/plugins/base_plugin.js +4 -2
  56. package/dist/esm/runner/runner.js +18 -11
  57. package/dist/esm/sessions/base_session_service.js +8 -3
  58. package/dist/esm/sessions/in_memory_session_service.js +8 -8
  59. package/dist/esm/sessions/vertex_ai_session_service.js +26 -11
  60. package/dist/esm/skills/loader.js +40 -6
  61. package/dist/esm/tools/get_user_choice_tool.js +25 -0
  62. package/dist/esm/tools/mcp/mcp_session_manager.js +35 -21
  63. package/dist/esm/tools/request_input_tool.js +26 -0
  64. package/dist/esm/utils/crypto_shim.js +15 -0
  65. package/dist/esm/utils/env_aware_utils.js +15 -13
  66. package/dist/esm/utils/error_utils.js +92 -0
  67. package/dist/esm/utils/file_utils.js +5 -2
  68. package/dist/esm/utils/output_schema_utils.js +15 -0
  69. package/dist/esm/utils/vertex_ai_utils.js +2 -0
  70. package/dist/esm/version.js +1 -1
  71. package/dist/types/a2a/auth.d.ts +30 -0
  72. package/dist/types/a2a/event_converter_utils.d.ts +4 -1
  73. package/dist/types/auth/credential_service/in_memory_credential_service.d.ts +11 -0
  74. package/dist/types/code_executors/unsafe_local_code_executor.d.ts +5 -1
  75. package/dist/types/common.d.ts +2 -0
  76. package/dist/types/context/agent_controlled_context_compactor.d.ts +0 -1
  77. package/dist/types/context/compaction_utils.d.ts +8 -0
  78. package/dist/types/context/token_based_context_compactor.d.ts +0 -1
  79. package/dist/types/index.d.ts +2 -1
  80. package/dist/types/memory/in_memory_memory_service.d.ts +11 -0
  81. package/dist/types/plugins/base_plugin.d.ts +4 -2
  82. package/dist/types/sessions/base_session_service.d.ts +8 -0
  83. package/dist/types/sessions/in_memory_session_service.d.ts +9 -0
  84. package/dist/types/sessions/vertex_ai_session_service.d.ts +19 -1
  85. package/dist/types/skills/loader.d.ts +5 -0
  86. package/dist/types/tools/get_user_choice_tool.d.ts +14 -0
  87. package/dist/types/tools/request_input_tool.d.ts +15 -0
  88. package/dist/types/utils/crypto_shim.d.ts +16 -0
  89. package/dist/types/utils/env_aware_utils.d.ts +23 -0
  90. package/dist/types/utils/error_utils.d.ts +18 -0
  91. package/dist/types/utils/output_schema_utils.d.ts +18 -0
  92. package/dist/types/utils/vertex_ai_utils.d.ts +1 -0
  93. package/dist/types/version.d.ts +1 -1
  94. package/dist/web/a2a/a2a_remote_agent.js +12 -2
  95. package/dist/web/a2a/agent_to_a2a.js +0 -1
  96. package/dist/web/a2a/auth.js +37 -0
  97. package/dist/web/a2a/event_converter_utils.js +40 -15
  98. package/dist/web/agents/functions.js +20 -7
  99. package/dist/web/agents/llm_agent.js +2 -1
  100. package/dist/web/agents/processors/basic_llm_request_processor.js +3 -2
  101. package/dist/web/agents/processors/content_request_processor.js +2 -21
  102. package/dist/web/agents/processors/instructions_llm_request_processor.js +3 -1
  103. package/dist/web/artifacts/in_memory_artifact_service.js +10 -9
  104. package/dist/web/auth/credential_service/in_memory_credential_service.js +14 -3
  105. package/dist/web/code_executors/unsafe_local_code_executor.js +22 -11
  106. package/dist/web/common.js +4 -0
  107. package/dist/web/context/agent_controlled_context_compactor.js +2 -11
  108. package/dist/web/context/compaction_utils.js +12 -1
  109. package/dist/web/context/token_based_context_compactor.js +6 -21
  110. package/dist/web/index.js +2 -0
  111. package/dist/web/memory/in_memory_memory_service.js +13 -2
  112. package/dist/web/memory/vertex_ai_memory_bank_service.js +7 -1
  113. package/dist/web/plugins/base_plugin.js +4 -2
  114. package/dist/web/runner/runner.js +17 -11
  115. package/dist/web/sessions/base_session_service.js +8 -3
  116. package/dist/web/sessions/in_memory_session_service.js +8 -8
  117. package/dist/web/sessions/vertex_ai_session_service.js +24 -11
  118. package/dist/web/skills/loader.js +40 -6
  119. package/dist/web/tools/get_user_choice_tool.js +25 -0
  120. package/dist/web/tools/mcp/mcp_session_manager.js +35 -21
  121. package/dist/web/tools/request_input_tool.js +26 -0
  122. package/dist/web/utils/crypto_shim.js +15 -0
  123. package/dist/web/utils/env_aware_utils.js +15 -13
  124. package/dist/web/utils/error_utils.js +92 -0
  125. package/dist/web/utils/file_utils.js +5 -2
  126. package/dist/web/utils/output_schema_utils.js +15 -0
  127. package/dist/web/utils/vertex_ai_utils.js +2 -0
  128. package/dist/web/version.js +1 -1
  129. package/package.json +1 -1
@@ -5,9 +5,9 @@ const require = topLevelCreateRequire(import.meta.url);
5
5
  * Copyright 2026 Google LLC
6
6
  * SPDX-License-Identifier: Apache-2.0
7
7
  */
8
- import { isCompactedEvent } from "../events/compacted_event.js";
9
8
  import { createEvent } from "../events/event.js";
10
9
  import { ContextCompactionTrigger } from "../plugins/base_plugin.js";
10
+ import { getActiveEvents } from "./compaction_utils.js";
11
11
  class AgentControlledContextCompactor {
12
12
  constructor(options) {
13
13
  this.trigger = ContextCompactionTrigger.AgentControlled;
@@ -18,7 +18,7 @@ class AgentControlledContextCompactor {
18
18
  }
19
19
  async compact(invocationContext) {
20
20
  const events = invocationContext.session.events;
21
- const activeEvents = this.getActiveEvents(events);
21
+ const activeEvents = getActiveEvents(events);
22
22
  const consolidateToolCallIndex = activeEvents.reduce(
23
23
  (acc, e, idx) => {
24
24
  var _a, _b;
@@ -66,15 +66,6 @@ class AgentControlledContextCompactor {
66
66
  delete invocationContext.session.state["temp:consolidate_context"];
67
67
  delete invocationContext.session.state["temp:consolidate_context_detail"];
68
68
  }
69
- getActiveEvents(events) {
70
- const latest = events.filter(isCompactedEvent).pop();
71
- return latest ? [
72
- latest,
73
- ...events.filter(
74
- (e) => !isCompactedEvent(e) && e.timestamp > latest.endTime
75
- )
76
- ] : events;
77
- }
78
69
  }
79
70
  export {
80
71
  AgentControlledContextCompactor
@@ -5,10 +5,20 @@ const require = topLevelCreateRequire(import.meta.url);
5
5
  * Copyright 2026 Google LLC
6
6
  * SPDX-License-Identifier: Apache-2.0
7
7
  */
8
+ import { isCompactedEvent } from "../events/compacted_event.js";
8
9
  import {
9
10
  getFunctionCalls,
10
11
  getFunctionResponses
11
12
  } from "../events/event.js";
13
+ function getActiveEvents(events) {
14
+ const latest = events.filter(isCompactedEvent).pop();
15
+ return latest ? [
16
+ latest,
17
+ ...events.filter(
18
+ (e) => !isCompactedEvent(e) && e.timestamp > latest.endTime
19
+ )
20
+ ] : events;
21
+ }
12
22
  function calculateRetainStartIndex(rawEvents, eventRetentionSize) {
13
23
  let retainStartIndex = Math.max(0, rawEvents.length - eventRetentionSize);
14
24
  while (retainStartIndex > 0) {
@@ -23,5 +33,6 @@ function calculateRetainStartIndex(rawEvents, eventRetentionSize) {
23
33
  return retainStartIndex;
24
34
  }
25
35
  export {
26
- calculateRetainStartIndex
36
+ calculateRetainStartIndex,
37
+ getActiveEvents
27
38
  };
@@ -7,7 +7,10 @@ const require = topLevelCreateRequire(import.meta.url);
7
7
  */
8
8
  import { getContents } from "../agents/processors/content_processor_utils.js";
9
9
  import { isCompactedEvent } from "../events/compacted_event.js";
10
- import { calculateRetainStartIndex } from "./compaction_utils.js";
10
+ import {
11
+ calculateRetainStartIndex,
12
+ getActiveEvents
13
+ } from "./compaction_utils.js";
11
14
  const CHARS_PER_TOKEN = 4;
12
15
  class TokenBasedContextCompactor {
13
16
  constructor(options) {
@@ -15,27 +18,9 @@ class TokenBasedContextCompactor {
15
18
  this.eventRetentionSize = options.eventRetentionSize;
16
19
  this.summarizer = options.summarizer;
17
20
  }
18
- getActiveEvents(events) {
19
- let latestCompactedEvent = void 0;
20
- for (let i = events.length - 1; i >= 0; i--) {
21
- const e = events[i];
22
- if (isCompactedEvent(e)) {
23
- if (!latestCompactedEvent || e.endTime > latestCompactedEvent.endTime) {
24
- latestCompactedEvent = e;
25
- }
26
- }
27
- }
28
- if (!latestCompactedEvent) {
29
- return events;
30
- }
31
- const activeRawEvents = events.filter(
32
- (e) => !isCompactedEvent(e) && e.timestamp > latestCompactedEvent.endTime
33
- );
34
- return [latestCompactedEvent, ...activeRawEvents];
35
- }
36
21
  shouldCompact(invocationContext) {
37
22
  const events = invocationContext.session.events;
38
- const activeEvents = this.getActiveEvents(events);
23
+ const activeEvents = getActiveEvents(events);
39
24
  const rawEvents = activeEvents.filter((e) => !isCompactedEvent(e));
40
25
  if (rawEvents.length <= this.eventRetentionSize) {
41
26
  return false;
@@ -58,7 +43,7 @@ class TokenBasedContextCompactor {
58
43
  }
59
44
  async compact(invocationContext) {
60
45
  const events = invocationContext.session.events;
61
- const activeEvents = this.getActiveEvents(events);
46
+ const activeEvents = getActiveEvents(events);
62
47
  const rawEvents = activeEvents.filter((e) => !isCompactedEvent(e));
63
48
  if (rawEvents.length <= this.eventRetentionSize) {
64
49
  return;
package/dist/web/index.js CHANGED
@@ -9,6 +9,7 @@ import { AGENT_CARD_PATH, RemoteA2AAgent } from "./a2a/a2a_remote_agent.js";
9
9
  import { getA2AAgentCard } from "./a2a/agent_card.js";
10
10
  import { A2AAgentExecutor } from "./a2a/agent_executor.js";
11
11
  import { toA2a } from "./a2a/agent_to_a2a.js";
12
+ import { bearerTokenUserBuilder } from "./a2a/auth.js";
12
13
  import { InvocationContext } from "./agents/invocation_context.js";
13
14
  import { FileArtifactService } from "./artifacts/file_artifact_service.js";
14
15
  import { GcsArtifactService } from "./artifacts/gcs_artifact_service.js";
@@ -56,6 +57,7 @@ export {
56
57
  RunSkillScriptTool,
57
58
  UnsafeLocalCodeExecutor,
58
59
  VertexAiSessionService,
60
+ bearerTokenUserBuilder,
59
61
  getA2AAgentCard,
60
62
  getArtifactServiceFromUri,
61
63
  getSessionServiceFromUri,
@@ -8,12 +8,23 @@ const require = topLevelCreateRequire(import.meta.url);
8
8
  class InMemoryMemoryService {
9
9
  constructor() {
10
10
  this.memories = [];
11
- this.sessionEvents = {};
11
+ /**
12
+ * A map from user key to a map from session ID to events.
13
+ *
14
+ * The inner map is keyed by `session.id`, which arrives off the request path
15
+ * and contains no `/`, so it can be exactly `__proto__`. On a plain object
16
+ * literal that key would reach the inherited `__proto__` setter and
17
+ * re-parent the map instead of creating an own property, silently dropping
18
+ * the session from the `Object.values` scan in `searchMemory`. The outer key
19
+ * always contains a `/` (see `getUserKey`) and cannot collide, but is
20
+ * created the same way for consistency.
21
+ */
22
+ this.sessionEvents = /* @__PURE__ */ Object.create(null);
12
23
  }
13
24
  async addSessionToMemory(session) {
14
25
  const userKey = getUserKey(session.appName, session.userId);
15
26
  if (!this.sessionEvents[userKey]) {
16
- this.sessionEvents[userKey] = {};
27
+ this.sessionEvents[userKey] = /* @__PURE__ */ Object.create(null);
17
28
  }
18
29
  this.sessionEvents[userKey][session.id] = session.events.filter(
19
30
  (event) => {
@@ -24,7 +24,10 @@ var __spreadValues = (a, b) => {
24
24
  import { Client } from "@google-cloud/vertexai";
25
25
  import { createUserContent } from "@google/genai";
26
26
  import { logger } from "../utils/logger.js";
27
- import { getExpressModeApiKey } from "../utils/vertex_ai_utils.js";
27
+ import {
28
+ EXPRESS_MODE_UNSUPPORTED_MESSAGE,
29
+ getExpressModeApiKey
30
+ } from "../utils/vertex_ai_utils.js";
28
31
  const GENERATE_MEMORIES_KNOWN_FIELDS = [
29
32
  "disableConsolidation",
30
33
  "waitForCompletion",
@@ -105,6 +108,9 @@ class VertexAiMemoryBankService {
105
108
  if (options.client) {
106
109
  this.memories = options.client.agentEnginesInternal.memories;
107
110
  } else {
111
+ if (this.expressModeApiKey && (!this.projectId || !this.location)) {
112
+ throw new Error(EXPRESS_MODE_UNSUPPORTED_MESSAGE);
113
+ }
108
114
  const client = new Client({
109
115
  project: this.projectId,
110
116
  location: this.location
@@ -73,8 +73,10 @@ class BasePlugin {
73
73
  * @param params.invocationContext The context for the entire invocation.
74
74
  * @param params.event The event raised by the runner.
75
75
  * @returns An optional value. A non-`undefined` return may be used by the
76
- * framework to modify or replace the response. Returning `undefined`
77
- * allows the original response to be used.
76
+ * framework to modify or replace the response. Copy `params.event` when
77
+ * constructing a replacement to preserve fields that are not being
78
+ * modified, such as event actions. Returning `undefined` allows the
79
+ * original response to be used.
78
80
  */
79
81
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
80
82
  async onEventCallback(params) {
@@ -191,7 +191,7 @@ class Runner {
191
191
  this,
192
192
  function() {
193
193
  return __asyncGenerator(this, null, function* () {
194
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
194
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
195
195
  const session = yield new __await(this.sessionService.getSession({
196
196
  appName: this.appName,
197
197
  userId,
@@ -310,21 +310,27 @@ class Runner {
310
310
  if ((_h = params.abortSignal) == null ? void 0 : _h.aborted) {
311
311
  return;
312
312
  }
313
- if (!event.partial) {
314
- yield new __await(this.sessionService.appendEvent({ session, event }));
315
- }
316
313
  const modifiedEvent = yield new __await(this.pluginManager.runOnEventCallback({
317
314
  invocationContext,
318
315
  event
319
316
  }));
320
- if ((_i = params.abortSignal) == null ? void 0 : _i.aborted) {
321
- return;
317
+ const outputEvent = modifiedEvent ? __spreadProps(__spreadValues({}, modifiedEvent), {
318
+ id: event.id,
319
+ invocationId: event.invocationId,
320
+ timestamp: event.timestamp,
321
+ author: modifiedEvent.author || event.author,
322
+ branch: (_i = modifiedEvent.branch) != null ? _i : event.branch
323
+ }) : event;
324
+ if (!event.partial) {
325
+ yield new __await(this.sessionService.appendEvent({
326
+ session,
327
+ event: outputEvent
328
+ }));
322
329
  }
323
- if (modifiedEvent) {
324
- yield modifiedEvent;
325
- } else {
326
- yield event;
330
+ if ((_j = params.abortSignal) == null ? void 0 : _j.aborted) {
331
+ return;
327
332
  }
333
+ yield outputEvent;
328
334
  }
329
335
  } catch (temp) {
330
336
  error = [temp];
@@ -337,7 +343,7 @@ class Runner {
337
343
  }
338
344
  }
339
345
  yield new __await(this.pluginManager.runAfterRunCallback({ invocationContext }));
340
- if ((_j = params.abortSignal) == null ? void 0 : _j.aborted) {
346
+ if ((_k = params.abortSignal) == null ? void 0 : _k.aborted) {
341
347
  return;
342
348
  }
343
349
  }
@@ -61,7 +61,12 @@ class BaseSessionService {
61
61
  if (key.startsWith(State.TEMP_PREFIX)) {
62
62
  continue;
63
63
  }
64
- session.state[key] = value;
64
+ Object.defineProperty(session.state, key, {
65
+ value,
66
+ writable: true,
67
+ enumerable: true,
68
+ configurable: true
69
+ });
65
70
  }
66
71
  }
67
72
  }
@@ -70,7 +75,7 @@ function trimTempDeltaState(event) {
70
75
  return event;
71
76
  }
72
77
  const stateDelta = event.actions.stateDelta;
73
- const filteredStateDelta = {};
78
+ const filteredStateDelta = /* @__PURE__ */ Object.create(null);
74
79
  for (const [key, value] of Object.entries(stateDelta)) {
75
80
  if (!key.startsWith(State.TEMP_PREFIX)) {
76
81
  filteredStateDelta[key] = value;
@@ -80,7 +85,7 @@ function trimTempDeltaState(event) {
80
85
  return event;
81
86
  }
82
87
  function trimTempState(state) {
83
- const filteredState = {};
88
+ const filteredState = /* @__PURE__ */ Object.create(null);
84
89
  for (const [key, value] of Object.entries(state)) {
85
90
  if (!key.startsWith(State.TEMP_PREFIX)) {
86
91
  filteredState[key] = value;
@@ -25,15 +25,15 @@ class InMemorySessionService extends BaseSessionService {
25
25
  * A map from app name to a map from user ID to a map from session ID to
26
26
  * session.
27
27
  */
28
- this.sessions = {};
28
+ this.sessions = /* @__PURE__ */ Object.create(null);
29
29
  /**
30
30
  * A map from app name to a map from user ID to a map from key to the value.
31
31
  */
32
- this.userState = {};
32
+ this.userState = /* @__PURE__ */ Object.create(null);
33
33
  /**
34
34
  * A map from app name to a map from key to the value.
35
35
  */
36
- this.appState = {};
36
+ this.appState = /* @__PURE__ */ Object.create(null);
37
37
  }
38
38
  async createSession({
39
39
  appName,
@@ -52,10 +52,10 @@ class InMemorySessionService extends BaseSessionService {
52
52
  lastUpdateTime: Date.now()
53
53
  });
54
54
  if (!this.sessions[appName]) {
55
- this.sessions[appName] = {};
55
+ this.sessions[appName] = /* @__PURE__ */ Object.create(null);
56
56
  }
57
57
  if (!this.sessions[appName][userId]) {
58
- this.sessions[appName][userId] = {};
58
+ this.sessions[appName][userId] = /* @__PURE__ */ Object.create(null);
59
59
  }
60
60
  this.sessions[appName][userId][session.id] = session;
61
61
  const copiedSession = cloneDeep(session);
@@ -220,12 +220,12 @@ class InMemorySessionService extends BaseSessionService {
220
220
  if (event.actions && event.actions.stateDelta) {
221
221
  for (const key of Object.keys(event.actions.stateDelta)) {
222
222
  if (key.startsWith(State.APP_PREFIX)) {
223
- this.appState[appName] = this.appState[appName] || {};
223
+ this.appState[appName] = this.appState[appName] || /* @__PURE__ */ Object.create(null);
224
224
  this.appState[appName][key.replace(State.APP_PREFIX, "")] = event.actions.stateDelta[key];
225
225
  }
226
226
  if (key.startsWith(State.USER_PREFIX)) {
227
- this.userState[appName] = this.userState[appName] || {};
228
- this.userState[appName][userId] = this.userState[appName][userId] || {};
227
+ this.userState[appName] = this.userState[appName] || /* @__PURE__ */ Object.create(null);
228
+ this.userState[appName][userId] = this.userState[appName][userId] || /* @__PURE__ */ Object.create(null);
229
229
  this.userState[appName][userId][key.replace(State.USER_PREFIX, "")] = event.actions.stateDelta[key];
230
230
  }
231
231
  }
@@ -37,7 +37,10 @@ import { Client } from "@google-cloud/vertexai/build/src/genai/client.js";
37
37
  import { isCompactedEvent } from "../events/compacted_event.js";
38
38
  import { experimental } from "../utils/experimental.js";
39
39
  import { logger } from "../utils/logger.js";
40
- import { getExpressModeApiKey } from "../utils/vertex_ai_utils.js";
40
+ import {
41
+ EXPRESS_MODE_UNSUPPORTED_MESSAGE,
42
+ getExpressModeApiKey
43
+ } from "../utils/vertex_ai_utils.js";
41
44
  import { partialCopy } from "../utils/partial_copy.js";
42
45
  import {
43
46
  BaseSessionService,
@@ -65,16 +68,14 @@ let VertexAiSessionService = class extends BaseSessionService {
65
68
  this.location,
66
69
  options.expressModeApiKey
67
70
  );
68
- if (!options.sessions) {
69
- if (!this.expressModeApiKey && (!this.projectId || !this.location)) {
70
- throw new Error(
71
- "Either (Project ID and Location) or an expressModeApiKey is required."
72
- );
73
- }
74
- }
75
71
  if (options.sessions) {
76
72
  this.sessions = options.sessions;
77
73
  } else {
74
+ if (!this.projectId || !this.location) {
75
+ throw new Error(
76
+ this.expressModeApiKey ? EXPRESS_MODE_UNSUPPORTED_MESSAGE : "Project ID and Location are required."
77
+ );
78
+ }
78
79
  const client = new Client({
79
80
  project: this.projectId,
80
81
  location: this.location
@@ -98,19 +99,31 @@ let VertexAiSessionService = class extends BaseSessionService {
98
99
  }
99
100
  return match[3];
100
101
  }
102
+ /**
103
+ * Creates a session on Vertex AI Agent Engine.
104
+ *
105
+ * @throws if both `ttl` and `expireTime` are specified.
106
+ */
101
107
  async createSession({
102
108
  appName,
103
109
  userId,
104
110
  state,
105
- sessionId
111
+ sessionId,
112
+ ttl,
113
+ expireTime
106
114
  }) {
107
115
  var _a;
116
+ if (ttl != null && expireTime != null) {
117
+ throw new Error(
118
+ "Cannot specify both 'ttl' and 'expireTime' simultaneously."
119
+ );
120
+ }
108
121
  const reasoningEngineId = this.getReasoningEngineId(appName);
109
122
  const filteredState = state ? trimTempState(state) : void 0;
110
123
  let apiResponse = await this.sessions.createInternal({
111
124
  name: "reasoningEngines/".concat(reasoningEngineId),
112
125
  userId,
113
- config: __spreadValues(__spreadValues({}, filteredState ? { sessionState: filteredState } : {}), sessionId ? { sessionId } : {})
126
+ config: __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, filteredState ? { sessionState: filteredState } : {}), sessionId ? { sessionId } : {}), ttl != null ? { ttl } : {}), expireTime != null ? { expireTime } : {})
114
127
  });
115
128
  const operationName = apiResponse.name;
116
129
  let attempts = 0;
@@ -195,7 +208,7 @@ let VertexAiSessionService = class extends BaseSessionService {
195
208
  return session;
196
209
  } catch (error) {
197
210
  const err = error;
198
- if (err.code === GRPC_NOT_FOUND || err.code === HTTP_NOT_FOUND) {
211
+ if (err.code === GRPC_NOT_FOUND || err.code === HTTP_NOT_FOUND || err.status === HTTP_NOT_FOUND) {
199
212
  return void 0;
200
213
  }
201
214
  logger.error("Error getting session from Vertex AI: ".concat(err.message));
@@ -37,6 +37,9 @@ const ALLOWED_FRONTMATTER_KEYS = /* @__PURE__ */ new Set([
37
37
  "description",
38
38
  "license",
39
39
  "allowed-tools",
40
+ // Camel-case alias: FrontmatterSchema's preprocessor derives `allowedTools`
41
+ // from `allowed-tools`, and `.loose()` passes either spelling through.
42
+ "allowedTools",
40
43
  "metadata",
41
44
  "compatibility"
42
45
  ]);
@@ -99,7 +102,7 @@ async function loadDir(directoryPath) {
99
102
  }
100
103
  return files;
101
104
  }
102
- function parseSkillMdContent(content) {
105
+ function parseFrontmatterYaml(content) {
103
106
  if (!content.startsWith("---")) {
104
107
  throw new Error("SKILL.md must start with YAML frontmatter (---)");
105
108
  }
@@ -111,15 +114,34 @@ function parseSkillMdContent(content) {
111
114
  const body = parts.filter((_, i) => i >= 2).join("---").trim();
112
115
  try {
113
116
  const parsed = yaml.load(frontmatterStr);
114
- if (typeof parsed !== "object" || parsed === null) {
117
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
115
118
  throw new Error("SKILL.md frontmatter must be a YAML mapping");
116
119
  }
117
- const frontmatter = FrontmatterSchema.parse(parsed);
118
- return { frontmatter, body };
120
+ return { raw: parsed, body };
119
121
  } catch (e) {
120
122
  throw new Error("Invalid YAML in frontmatter: ".concat(e.message));
121
123
  }
122
124
  }
125
+ function validateFrontmatter(raw) {
126
+ try {
127
+ return FrontmatterSchema.parse(raw);
128
+ } catch (e) {
129
+ throw new Error("Invalid YAML in frontmatter: ".concat(e.message));
130
+ }
131
+ }
132
+ function parseSkillMdContent(content) {
133
+ const { raw, body } = parseFrontmatterYaml(content);
134
+ return { frontmatter: validateFrontmatter(raw), body };
135
+ }
136
+ function isDangerousZipEntryName(entryName) {
137
+ if (path.posix.isAbsolute(entryName) || path.win32.isAbsolute(entryName)) {
138
+ return true;
139
+ }
140
+ return entryName.split(/[/\\]/).some((segment) => segment === "..");
141
+ }
142
+ function isBareSkillName(name) {
143
+ return name !== "." && name !== ".." && path.basename(name) === name;
144
+ }
123
145
  async function loadSkillFromDir(skillDir) {
124
146
  const resolvedDir = path.resolve(skillDir);
125
147
  const skill = await loadSkillFile(skillDir);
@@ -258,6 +280,11 @@ async function loadAllSkillsInDir(skillsBasePath) {
258
280
  function loadSkillFromZipBuffer(zipBuffer) {
259
281
  const zip = new AdmZip(zipBuffer);
260
282
  const entries = zip.getEntries();
283
+ for (const entry of entries) {
284
+ if (isDangerousZipEntryName(entry.entryName)) {
285
+ throw new Error("Dangerous zip entry ignored: ".concat(entry.entryName));
286
+ }
287
+ }
261
288
  let skillMdContent = "";
262
289
  for (const entry of entries) {
263
290
  if (entry.isDirectory) continue;
@@ -269,8 +296,15 @@ function loadSkillFromZipBuffer(zipBuffer) {
269
296
  if (!skillMdContent) {
270
297
  throw new Error("SKILL.md not found in zipped filesystem.");
271
298
  }
272
- const { frontmatter: parsed, body } = parseSkillMdContent(skillMdContent);
273
- const frontmatter = FrontmatterSchema.parse(parsed);
299
+ const { raw, body } = parseFrontmatterYaml(skillMdContent);
300
+ const skillName = raw["name"];
301
+ if (!skillName) {
302
+ throw new Error("SKILL.md frontmatter must contain 'name'");
303
+ }
304
+ if (typeof skillName !== "string" || !isBareSkillName(skillName)) {
305
+ throw new Error("Invalid skill name in SKILL.md: ".concat(String(skillName)));
306
+ }
307
+ const frontmatter = validateFrontmatter(raw);
274
308
  const references = {};
275
309
  const assets = {};
276
310
  const scripts = {};
@@ -0,0 +1,25 @@
1
+ import {createRequire as topLevelCreateRequire} from 'module';
2
+ const require = topLevelCreateRequire(import.meta.url);
3
+ /**
4
+ * @license
5
+ * Copyright 2026 Google LLC
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+ import { z } from "zod";
9
+ import { LongRunningFunctionTool } from "./long_running_tool.js";
10
+ const getUserChoiceTool = new LongRunningFunctionTool({
11
+ name: "get_user_choice",
12
+ description: "Presents a list of options to the user and awaits their selection.",
13
+ parameters: z.object({
14
+ options: z.array(z.string()).describe("List of options to present to the user.")
15
+ }),
16
+ execute: async (input, context) => {
17
+ if (context) {
18
+ context.actions.skipSummarization = true;
19
+ }
20
+ return null;
21
+ }
22
+ });
23
+ export {
24
+ getUserChoiceTool
25
+ };
@@ -12,6 +12,11 @@ import {
12
12
  import {
13
13
  StreamableHTTPClientTransport
14
14
  } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
15
+ import { formatError } from "../../utils/error_utils.js";
16
+ import { logger } from "../../utils/logger.js";
17
+ function logTransportError(err) {
18
+ logger.error("MCP transport error: " + formatError(err));
19
+ }
15
20
  class MCPSessionManager {
16
21
  constructor(connectionParams) {
17
22
  this.activeSessions = /* @__PURE__ */ new Set();
@@ -20,31 +25,40 @@ class MCPSessionManager {
20
25
  async createSession() {
21
26
  var _a;
22
27
  const client = new Client({ name: "MCPClient", version: "1.0.0" });
23
- switch (this.connectionParams.type) {
24
- case "StdioConnectionParams":
25
- await client.connect(
26
- new StdioClientTransport(this.connectionParams.serverParams)
27
- );
28
- break;
29
- case "StreamableHTTPConnectionParams": {
30
- const options = (_a = this.connectionParams.transportOptions) != null ? _a : {};
31
- if (!options.requestInit && this.connectionParams.header !== void 0) {
32
- options.requestInit = {
33
- headers: this.connectionParams.header
34
- };
28
+ try {
29
+ switch (this.connectionParams.type) {
30
+ case "StdioConnectionParams": {
31
+ const transport = new StdioClientTransport(
32
+ this.connectionParams.serverParams
33
+ );
34
+ transport.onerror = logTransportError;
35
+ await client.connect(transport);
36
+ break;
35
37
  }
36
- await client.connect(
37
- new StreamableHTTPClientTransport(
38
+ case "StreamableHTTPConnectionParams": {
39
+ const options = (_a = this.connectionParams.transportOptions) != null ? _a : {};
40
+ if (!options.requestInit && this.connectionParams.header !== void 0) {
41
+ options.requestInit = {
42
+ headers: this.connectionParams.header
43
+ };
44
+ }
45
+ const transport = new StreamableHTTPClientTransport(
38
46
  new URL(this.connectionParams.url),
39
47
  options
40
- )
41
- );
42
- break;
43
- }
44
- default: {
45
- const _exhaustiveCheck = this.connectionParams;
46
- break;
48
+ );
49
+ transport.onerror = logTransportError;
50
+ await client.connect(transport);
51
+ break;
52
+ }
53
+ default: {
54
+ const _exhaustiveCheck = this.connectionParams;
55
+ break;
56
+ }
47
57
  }
58
+ } catch (err) {
59
+ throw new Error("Failed to create MCP session: " + formatError(err), {
60
+ cause: err
61
+ });
48
62
  }
49
63
  this.activeSessions.add(client);
50
64
  return client;
@@ -0,0 +1,26 @@
1
+ import {createRequire as topLevelCreateRequire} from 'module';
2
+ const require = topLevelCreateRequire(import.meta.url);
3
+ /**
4
+ * @license
5
+ * Copyright 2026 Google LLC
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+ import { z } from "zod";
9
+ import { LongRunningFunctionTool } from "./long_running_tool.js";
10
+ const requestInputTool = new LongRunningFunctionTool({
11
+ name: "adk_request_input",
12
+ description: "Presents a custom message to the user and awaits unstructured or structured input.",
13
+ parameters: z.object({
14
+ message: z.string().describe("The prompt for the user."),
15
+ responseSchema: z.record(z.string(), z.unknown()).optional().describe("Expected schema of the response.")
16
+ }),
17
+ execute: async (input, context) => {
18
+ if (context) {
19
+ context.actions.skipSummarization = true;
20
+ }
21
+ return null;
22
+ }
23
+ });
24
+ export {
25
+ requestInputTool
26
+ };
@@ -0,0 +1,15 @@
1
+ import {createRequire as topLevelCreateRequire} from 'module';
2
+ const require = topLevelCreateRequire(import.meta.url);
3
+ /**
4
+ * @license
5
+ * Copyright 2026 Google LLC
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+ function randomUUID() {
9
+ throw new Error(
10
+ "randomUUID: no cryptographically secure source of randomness is available. Neither crypto.randomUUID() nor crypto.getRandomValues() is present in this environment."
11
+ );
12
+ }
13
+ export {
14
+ randomUUID
15
+ };