@google/adk 1.4.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 (213) hide show
  1. package/dist/cjs/a2a/a2a_remote_agent.js +12 -2
  2. package/dist/cjs/a2a/agent_to_a2a.js +18 -3
  3. package/dist/cjs/a2a/auth.js +65 -0
  4. package/dist/cjs/a2a/event_converter_utils.js +47 -18
  5. package/dist/cjs/a2a/metadata_converter_utils.js +1 -1
  6. package/dist/cjs/agents/base_agent.js +39 -0
  7. package/dist/cjs/agents/functions.js +26 -28
  8. package/dist/cjs/agents/llm_agent.js +4 -2
  9. package/dist/cjs/agents/loop_agent.js +15 -3
  10. package/dist/cjs/agents/processors/basic_llm_request_processor.js +3 -2
  11. package/dist/cjs/agents/processors/content_processor_utils.js +2 -1
  12. package/dist/cjs/agents/processors/content_request_processor.js +2 -21
  13. package/dist/cjs/agents/processors/instructions_llm_request_processor.js +3 -1
  14. package/dist/cjs/agents/routed_agent.js +31 -0
  15. package/dist/cjs/agents/run_config.js +3 -2
  16. package/dist/cjs/artifacts/in_memory_artifact_service.js +17 -9
  17. package/dist/cjs/auth/credential_service/in_memory_credential_service.js +14 -3
  18. package/dist/cjs/code_executors/unsafe_local_code_executor.js +23 -12
  19. package/dist/cjs/common.js +35 -0
  20. package/dist/cjs/context/agent_controlled_context_compactor.js +2 -11
  21. package/dist/cjs/context/anchored_context_compactor.js +127 -0
  22. package/dist/cjs/context/compaction_utils.js +64 -0
  23. package/dist/cjs/context/token_based_context_compactor.js +13 -44
  24. package/dist/cjs/events/compacted_event.js +9 -3
  25. package/dist/cjs/events/event.js +28 -0
  26. package/dist/cjs/index.js +7 -0
  27. package/dist/cjs/integrations/agent_registry/agent_registry_mcp_toolset.js +9 -1
  28. package/dist/cjs/memory/in_memory_memory_service.js +13 -2
  29. package/dist/cjs/memory/vertex_ai_memory_bank_service.js +3 -0
  30. package/dist/cjs/plugins/base_plugin.js +4 -2
  31. package/dist/cjs/plugins/global_instruction_plugin.js +97 -0
  32. package/dist/cjs/runner/runner.js +69 -23
  33. package/dist/cjs/sessions/base_session_service.js +8 -3
  34. package/dist/cjs/sessions/in_memory_session_service.js +8 -8
  35. package/dist/cjs/sessions/vertex_ai_session_service.js +22 -10
  36. package/dist/cjs/skills/loader.js +40 -6
  37. package/dist/cjs/tools/enterprise_web_search_tool.js +81 -0
  38. package/dist/cjs/tools/example_tool.js +68 -0
  39. package/dist/cjs/tools/get_user_choice_tool.js +53 -0
  40. package/dist/cjs/tools/load_web_page.js +250 -0
  41. package/dist/cjs/tools/mcp/load_mcp_resource_tool.js +140 -0
  42. package/dist/cjs/tools/mcp/mcp_session_manager.js +35 -21
  43. package/dist/cjs/tools/mcp/mcp_toolset.js +63 -0
  44. package/dist/cjs/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +13 -10
  45. package/dist/cjs/tools/request_input_tool.js +54 -0
  46. package/dist/cjs/tools/skill/run_skill_inline_script_tool.js +54 -4
  47. package/dist/cjs/tools/skill/skill_toolset.js +4 -2
  48. package/dist/cjs/utils/branch_trie.js +41 -0
  49. package/dist/cjs/utils/crypto_shim.js +43 -0
  50. package/dist/cjs/utils/env_aware_utils.js +15 -13
  51. package/dist/cjs/utils/error_utils.js +120 -0
  52. package/dist/cjs/utils/file_utils.js +5 -2
  53. package/dist/cjs/utils/output_schema_utils.js +43 -0
  54. package/dist/cjs/utils/streaming_utils.js +5 -5
  55. package/dist/cjs/utils/vertex_ai_utils.js +3 -0
  56. package/dist/cjs/version.js +1 -1
  57. package/dist/esm/a2a/a2a_remote_agent.js +12 -2
  58. package/dist/esm/a2a/agent_to_a2a.js +18 -3
  59. package/dist/esm/a2a/auth.js +37 -0
  60. package/dist/esm/a2a/event_converter_utils.js +47 -18
  61. package/dist/esm/a2a/metadata_converter_utils.js +1 -1
  62. package/dist/esm/agents/base_agent.js +39 -0
  63. package/dist/esm/agents/functions.js +27 -24
  64. package/dist/esm/agents/llm_agent.js +6 -4
  65. package/dist/esm/agents/loop_agent.js +15 -3
  66. package/dist/esm/agents/processors/basic_llm_request_processor.js +3 -2
  67. package/dist/esm/agents/processors/content_processor_utils.js +2 -1
  68. package/dist/esm/agents/processors/content_request_processor.js +2 -21
  69. package/dist/esm/agents/processors/instructions_llm_request_processor.js +3 -1
  70. package/dist/esm/agents/routed_agent.js +31 -0
  71. package/dist/esm/agents/run_config.js +3 -2
  72. package/dist/esm/artifacts/in_memory_artifact_service.js +17 -9
  73. package/dist/esm/auth/credential_service/in_memory_credential_service.js +14 -3
  74. package/dist/esm/code_executors/unsafe_local_code_executor.js +22 -11
  75. package/dist/esm/common.js +29 -1
  76. package/dist/esm/context/agent_controlled_context_compactor.js +2 -11
  77. package/dist/esm/context/anchored_context_compactor.js +99 -0
  78. package/dist/esm/context/compaction_utils.js +38 -0
  79. package/dist/esm/context/token_based_context_compactor.js +16 -44
  80. package/dist/esm/events/compacted_event.js +7 -2
  81. package/dist/esm/events/event.js +24 -0
  82. package/dist/esm/index.js +8 -1
  83. package/dist/esm/integrations/agent_registry/agent_registry_mcp_toolset.js +9 -1
  84. package/dist/esm/memory/in_memory_memory_service.js +13 -2
  85. package/dist/esm/memory/vertex_ai_memory_bank_service.js +7 -1
  86. package/dist/esm/plugins/base_plugin.js +4 -2
  87. package/dist/esm/plugins/global_instruction_plugin.js +69 -0
  88. package/dist/esm/runner/runner.js +69 -23
  89. package/dist/esm/sessions/base_session_service.js +8 -3
  90. package/dist/esm/sessions/in_memory_session_service.js +8 -8
  91. package/dist/esm/sessions/vertex_ai_session_service.js +26 -11
  92. package/dist/esm/skills/loader.js +40 -6
  93. package/dist/esm/tools/enterprise_web_search_tool.js +55 -0
  94. package/dist/esm/tools/example_tool.js +42 -0
  95. package/dist/esm/tools/get_user_choice_tool.js +25 -0
  96. package/dist/esm/tools/load_web_page.js +221 -0
  97. package/dist/esm/tools/mcp/load_mcp_resource_tool.js +114 -0
  98. package/dist/esm/tools/mcp/mcp_session_manager.js +35 -21
  99. package/dist/esm/tools/mcp/mcp_toolset.js +63 -0
  100. package/dist/esm/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +13 -10
  101. package/dist/esm/tools/request_input_tool.js +26 -0
  102. package/dist/esm/tools/skill/run_skill_inline_script_tool.js +53 -4
  103. package/dist/esm/tools/skill/skill_toolset.js +4 -2
  104. package/dist/esm/utils/branch_trie.js +13 -0
  105. package/dist/esm/utils/crypto_shim.js +15 -0
  106. package/dist/esm/utils/env_aware_utils.js +15 -13
  107. package/dist/esm/utils/error_utils.js +92 -0
  108. package/dist/esm/utils/file_utils.js +5 -2
  109. package/dist/esm/utils/output_schema_utils.js +15 -0
  110. package/dist/esm/utils/streaming_utils.js +1 -1
  111. package/dist/esm/utils/vertex_ai_utils.js +2 -0
  112. package/dist/esm/version.js +1 -1
  113. package/dist/types/a2a/a2a_remote_agent.d.ts +5 -1
  114. package/dist/types/a2a/agent_to_a2a.d.ts +38 -0
  115. package/dist/types/a2a/auth.d.ts +30 -0
  116. package/dist/types/a2a/event_converter_utils.d.ts +4 -1
  117. package/dist/types/agents/base_agent.d.ts +29 -1
  118. package/dist/types/agents/functions.d.ts +1 -9
  119. package/dist/types/agents/llm_agent.d.ts +5 -1
  120. package/dist/types/agents/loop_agent.d.ts +2 -2
  121. package/dist/types/agents/routed_agent.d.ts +24 -1
  122. package/dist/types/agents/run_config.d.ts +1 -1
  123. package/dist/types/auth/credential_service/in_memory_credential_service.d.ts +11 -0
  124. package/dist/types/code_executors/unsafe_local_code_executor.d.ts +5 -1
  125. package/dist/types/common.d.ts +11 -2
  126. package/dist/types/context/agent_controlled_context_compactor.d.ts +0 -1
  127. package/dist/types/context/anchored_context_compactor.d.ts +35 -0
  128. package/dist/types/context/compaction_utils.d.ts +23 -0
  129. package/dist/types/context/token_based_context_compactor.d.ts +0 -1
  130. package/dist/types/events/compacted_event.d.ts +10 -0
  131. package/dist/types/events/event.d.ts +13 -0
  132. package/dist/types/index.d.ts +5 -3
  133. package/dist/types/memory/in_memory_memory_service.d.ts +11 -0
  134. package/dist/types/plugins/base_plugin.d.ts +4 -2
  135. package/dist/types/plugins/global_instruction_plugin.d.ts +38 -0
  136. package/dist/types/runner/runner.d.ts +1 -1
  137. package/dist/types/sessions/base_session_service.d.ts +8 -0
  138. package/dist/types/sessions/in_memory_session_service.d.ts +9 -0
  139. package/dist/types/sessions/vertex_ai_session_service.d.ts +19 -1
  140. package/dist/types/skills/loader.d.ts +5 -0
  141. package/dist/types/tools/enterprise_web_search_tool.d.ts +26 -0
  142. package/dist/types/tools/example_tool.d.ts +21 -0
  143. package/dist/types/tools/get_user_choice_tool.d.ts +14 -0
  144. package/dist/types/tools/load_web_page.d.ts +33 -0
  145. package/dist/types/tools/mcp/load_mcp_resource_tool.d.ts +26 -0
  146. package/dist/types/tools/mcp/mcp_toolset.d.ts +27 -0
  147. package/dist/types/tools/request_input_tool.d.ts +15 -0
  148. package/dist/types/tools/skill/run_skill_inline_script_tool.d.ts +25 -0
  149. package/dist/types/tools/skill/skill_toolset.d.ts +9 -0
  150. package/dist/types/utils/branch_trie.d.ts +14 -0
  151. package/dist/types/utils/crypto_shim.d.ts +16 -0
  152. package/dist/types/utils/env_aware_utils.d.ts +23 -0
  153. package/dist/types/utils/error_utils.d.ts +18 -0
  154. package/dist/types/utils/output_schema_utils.d.ts +18 -0
  155. package/dist/types/utils/vertex_ai_utils.d.ts +1 -0
  156. package/dist/types/version.d.ts +1 -1
  157. package/dist/web/a2a/a2a_remote_agent.js +12 -2
  158. package/dist/web/a2a/agent_to_a2a.js +18 -3
  159. package/dist/web/a2a/auth.js +37 -0
  160. package/dist/web/a2a/event_converter_utils.js +47 -18
  161. package/dist/web/a2a/metadata_converter_utils.js +1 -1
  162. package/dist/web/agents/base_agent.js +39 -0
  163. package/dist/web/agents/functions.js +27 -24
  164. package/dist/web/agents/llm_agent.js +6 -4
  165. package/dist/web/agents/loop_agent.js +27 -3
  166. package/dist/web/agents/processors/basic_llm_request_processor.js +3 -2
  167. package/dist/web/agents/processors/content_processor_utils.js +2 -1
  168. package/dist/web/agents/processors/content_request_processor.js +2 -21
  169. package/dist/web/agents/processors/instructions_llm_request_processor.js +3 -1
  170. package/dist/web/agents/routed_agent.js +31 -0
  171. package/dist/web/agents/run_config.js +8 -3
  172. package/dist/web/artifacts/in_memory_artifact_service.js +17 -9
  173. package/dist/web/auth/credential_service/in_memory_credential_service.js +14 -3
  174. package/dist/web/code_executors/unsafe_local_code_executor.js +22 -11
  175. package/dist/web/common.js +29 -1
  176. package/dist/web/context/agent_controlled_context_compactor.js +2 -11
  177. package/dist/web/context/anchored_context_compactor.js +117 -0
  178. package/dist/web/context/compaction_utils.js +38 -0
  179. package/dist/web/context/token_based_context_compactor.js +16 -44
  180. package/dist/web/events/compacted_event.js +7 -2
  181. package/dist/web/events/event.js +24 -0
  182. package/dist/web/index.js +8 -1
  183. package/dist/web/integrations/agent_registry/agent_registry_mcp_toolset.js +9 -1
  184. package/dist/web/memory/in_memory_memory_service.js +13 -2
  185. package/dist/web/memory/vertex_ai_memory_bank_service.js +7 -1
  186. package/dist/web/plugins/base_plugin.js +4 -2
  187. package/dist/web/plugins/global_instruction_plugin.js +67 -0
  188. package/dist/web/runner/runner.js +65 -22
  189. package/dist/web/sessions/base_session_service.js +8 -3
  190. package/dist/web/sessions/in_memory_session_service.js +8 -8
  191. package/dist/web/sessions/vertex_ai_session_service.js +24 -11
  192. package/dist/web/skills/loader.js +40 -6
  193. package/dist/web/tools/enterprise_web_search_tool.js +55 -0
  194. package/dist/web/tools/example_tool.js +42 -0
  195. package/dist/web/tools/get_user_choice_tool.js +25 -0
  196. package/dist/web/tools/load_web_page.js +221 -0
  197. package/dist/web/tools/mcp/load_mcp_resource_tool.js +107 -0
  198. package/dist/web/tools/mcp/mcp_session_manager.js +35 -21
  199. package/dist/web/tools/mcp/mcp_toolset.js +63 -0
  200. package/dist/web/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +13 -10
  201. package/dist/web/tools/request_input_tool.js +26 -0
  202. package/dist/web/tools/skill/run_skill_inline_script_tool.js +51 -4
  203. package/dist/web/tools/skill/skill_toolset.js +4 -2
  204. package/dist/web/utils/branch_trie.js +13 -0
  205. package/dist/web/utils/crypto_shim.js +15 -0
  206. package/dist/web/utils/env_aware_utils.js +15 -13
  207. package/dist/web/utils/error_utils.js +92 -0
  208. package/dist/web/utils/file_utils.js +5 -2
  209. package/dist/web/utils/output_schema_utils.js +15 -0
  210. package/dist/web/utils/streaming_utils.js +1 -1
  211. package/dist/web/utils/vertex_ai_utils.js +2 -0
  212. package/dist/web/version.js +1 -1
  213. package/package.json +1 -1
@@ -0,0 +1,99 @@
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 { isScratchpadEvent } from "../events/compacted_event.js";
9
+ import { getEventTokens } from "../events/event.js";
10
+ import { calculateRetainStartIndex } from "./compaction_utils.js";
11
+ class AnchoredContextCompactor {
12
+ constructor(options) {
13
+ this.tokenThreshold = options.tokenThreshold;
14
+ this.eventRetentionSize = options.eventRetentionSize;
15
+ this.summarizer = options.summarizer;
16
+ }
17
+ getActiveEvents(events) {
18
+ let latestScratchpad = void 0;
19
+ for (let i = events.length - 1; i >= 0; i--) {
20
+ const e = events[i];
21
+ if (isScratchpadEvent(e)) {
22
+ latestScratchpad = e;
23
+ break;
24
+ }
25
+ }
26
+ if (!latestScratchpad) {
27
+ return events;
28
+ }
29
+ const activeRawEvents = events.filter(
30
+ (e) => e.timestamp > latestScratchpad.endTime && !isScratchpadEvent(e)
31
+ );
32
+ return [latestScratchpad, ...activeRawEvents];
33
+ }
34
+ shouldCompact(invocationContext) {
35
+ const events = invocationContext.session.events;
36
+ const activeEvents = this.getActiveEvents(events);
37
+ const hasScratchpad = activeEvents.length > 0 && isScratchpadEvent(activeEvents[0]);
38
+ const rawEvents = hasScratchpad ? activeEvents.slice(1) : activeEvents;
39
+ if (rawEvents.length <= this.eventRetentionSize) {
40
+ return false;
41
+ }
42
+ const retainStartIndex = calculateRetainStartIndex(
43
+ rawEvents,
44
+ this.eventRetentionSize
45
+ );
46
+ if (retainStartIndex === 0) {
47
+ return false;
48
+ }
49
+ const totalTokens = activeEvents.reduce(
50
+ (sum, event) => sum + getEventTokens(event),
51
+ 0
52
+ );
53
+ return totalTokens > this.tokenThreshold;
54
+ }
55
+ async compact(invocationContext) {
56
+ const events = invocationContext.session.events;
57
+ const activeEvents = this.getActiveEvents(events);
58
+ const hasScratchpad = activeEvents.length > 0 && isScratchpadEvent(activeEvents[0]);
59
+ const rawEvents = hasScratchpad ? activeEvents.slice(1) : activeEvents;
60
+ if (rawEvents.length <= this.eventRetentionSize) {
61
+ return;
62
+ }
63
+ const retainStartIndex = calculateRetainStartIndex(
64
+ rawEvents,
65
+ this.eventRetentionSize
66
+ );
67
+ if (retainStartIndex === 0) {
68
+ return;
69
+ }
70
+ const rawEventsToCompact = rawEvents.slice(0, retainStartIndex);
71
+ let scratchpadEvent;
72
+ if (hasScratchpad) {
73
+ const existingScratchpad = activeEvents[0];
74
+ scratchpadEvent = await this.summarizer.summarize([
75
+ existingScratchpad,
76
+ ...rawEventsToCompact
77
+ ]);
78
+ } else {
79
+ scratchpadEvent = await this.summarizer.summarize(rawEventsToCompact);
80
+ }
81
+ const updatedScratchpad = {
82
+ ...scratchpadEvent,
83
+ isScratchpad: true,
84
+ author: "system"
85
+ };
86
+ const inactiveEvents = events.slice(0, events.indexOf(activeEvents[0]));
87
+ const retainedRawEvents = rawEvents.slice(retainStartIndex);
88
+ const newEventsList = [
89
+ ...inactiveEvents,
90
+ updatedScratchpad,
91
+ ...retainedRawEvents
92
+ ];
93
+ events.length = 0;
94
+ events.push(...newEventsList);
95
+ }
96
+ }
97
+ export {
98
+ AnchoredContextCompactor
99
+ };
@@ -0,0 +1,38 @@
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 { isCompactedEvent } from "../events/compacted_event.js";
9
+ import {
10
+ getFunctionCalls,
11
+ getFunctionResponses
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
+ }
22
+ function calculateRetainStartIndex(rawEvents, eventRetentionSize) {
23
+ let retainStartIndex = Math.max(0, rawEvents.length - eventRetentionSize);
24
+ while (retainStartIndex > 0) {
25
+ const eventToRetain = rawEvents[retainStartIndex];
26
+ const previousEvent = rawEvents[retainStartIndex - 1];
27
+ if (getFunctionResponses(eventToRetain).length > 0 && getFunctionCalls(previousEvent).length > 0) {
28
+ retainStartIndex--;
29
+ } else {
30
+ break;
31
+ }
32
+ }
33
+ return retainStartIndex;
34
+ }
35
+ export {
36
+ calculateRetainStartIndex,
37
+ getActiveEvents
38
+ };
@@ -7,6 +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 {
11
+ calculateRetainStartIndex,
12
+ getActiveEvents
13
+ } from "./compaction_utils.js";
10
14
  const CHARS_PER_TOKEN = 4;
11
15
  class TokenBasedContextCompactor {
12
16
  constructor(options) {
@@ -14,31 +18,20 @@ class TokenBasedContextCompactor {
14
18
  this.eventRetentionSize = options.eventRetentionSize;
15
19
  this.summarizer = options.summarizer;
16
20
  }
17
- getActiveEvents(events) {
18
- let latestCompactedEvent = void 0;
19
- for (let i = events.length - 1; i >= 0; i--) {
20
- const e = events[i];
21
- if (isCompactedEvent(e)) {
22
- if (!latestCompactedEvent || e.endTime > latestCompactedEvent.endTime) {
23
- latestCompactedEvent = e;
24
- }
25
- }
26
- }
27
- if (!latestCompactedEvent) {
28
- return events;
29
- }
30
- const activeRawEvents = events.filter(
31
- (e) => !isCompactedEvent(e) && e.timestamp > latestCompactedEvent.endTime
32
- );
33
- return [latestCompactedEvent, ...activeRawEvents];
34
- }
35
21
  shouldCompact(invocationContext) {
36
22
  const events = invocationContext.session.events;
37
- const activeEvents = this.getActiveEvents(events);
23
+ const activeEvents = getActiveEvents(events);
38
24
  const rawEvents = activeEvents.filter((e) => !isCompactedEvent(e));
39
25
  if (rawEvents.length <= this.eventRetentionSize) {
40
26
  return false;
41
27
  }
28
+ const retainStartIndex = calculateRetainStartIndex(
29
+ rawEvents,
30
+ this.eventRetentionSize
31
+ );
32
+ if (retainStartIndex === 0) {
33
+ return false;
34
+ }
42
35
  const promptTokenCount = latestPromptTokenCount(
43
36
  activeEvents,
44
37
  invocationContext
@@ -50,24 +43,15 @@ class TokenBasedContextCompactor {
50
43
  }
51
44
  async compact(invocationContext) {
52
45
  const events = invocationContext.session.events;
53
- const activeEvents = this.getActiveEvents(events);
46
+ const activeEvents = getActiveEvents(events);
54
47
  const rawEvents = activeEvents.filter((e) => !isCompactedEvent(e));
55
48
  if (rawEvents.length <= this.eventRetentionSize) {
56
49
  return;
57
50
  }
58
- let retainStartIndex = Math.max(
59
- 0,
60
- rawEvents.length - this.eventRetentionSize
51
+ const retainStartIndex = calculateRetainStartIndex(
52
+ rawEvents,
53
+ this.eventRetentionSize
61
54
  );
62
- while (retainStartIndex > 0) {
63
- const eventToRetain = rawEvents[retainStartIndex];
64
- const previousEvent = rawEvents[retainStartIndex - 1];
65
- if (hasFunctionResponse(eventToRetain) && hasFunctionCall(previousEvent)) {
66
- retainStartIndex--;
67
- } else {
68
- break;
69
- }
70
- }
71
55
  if (retainStartIndex === 0) {
72
56
  return;
73
57
  }
@@ -122,18 +106,6 @@ function estimatePromptTokenCount(activeEvents, invocationContext) {
122
106
  }
123
107
  return Math.ceil(totalChars / CHARS_PER_TOKEN);
124
108
  }
125
- function hasFunctionCall(event) {
126
- var _a, _b;
127
- return !!((_b = (_a = event.content) == null ? void 0 : _a.parts) == null ? void 0 : _b.some(
128
- (part) => part.functionCall !== void 0
129
- ));
130
- }
131
- function hasFunctionResponse(event) {
132
- var _a, _b;
133
- return !!((_b = (_a = event.content) == null ? void 0 : _a.parts) == null ? void 0 : _b.some(
134
- (part) => part.functionResponse !== void 0
135
- ));
136
- }
137
109
  export {
138
110
  TokenBasedContextCompactor
139
111
  };
@@ -9,16 +9,21 @@ import { createEvent } from "./event.js";
9
9
  function isCompactedEvent(event) {
10
10
  return "isCompacted" in event && event.isCompacted === true;
11
11
  }
12
+ function isScratchpadEvent(event) {
13
+ return isCompactedEvent(event) && event.isScratchpad === true;
14
+ }
12
15
  function createCompactedEvent(params = {}) {
13
16
  return {
14
17
  ...createEvent(params),
15
18
  isCompacted: params.isCompacted || true,
16
19
  startTime: params.startTime,
17
20
  endTime: params.endTime,
18
- compactedContent: params.compactedContent
21
+ compactedContent: params.compactedContent,
22
+ isScratchpad: params.isScratchpad
19
23
  };
20
24
  }
21
25
  export {
22
26
  createCompactedEvent,
23
- isCompactedEvent
27
+ isCompactedEvent,
28
+ isScratchpadEvent
24
29
  };
@@ -5,6 +5,7 @@ const require = topLevelCreateRequire(import.meta.url);
5
5
  * Copyright 2026 Google LLC
6
6
  * SPDX-License-Identifier: Apache-2.0
7
7
  */
8
+ import { randomUUID } from "../utils/env_aware_utils.js";
8
9
  import { toCamelCase, toSnakeCase } from "../utils/object_notation_utils.js";
9
10
  import { createEventActions } from "./event_actions.js";
10
11
  function createEvent(params = {}) {
@@ -36,6 +37,17 @@ function getFunctionCalls(event) {
36
37
  }
37
38
  return funcCalls;
38
39
  }
40
+ const AF_FUNCTION_CALL_ID_PREFIX = "adk-";
41
+ function generateClientFunctionCallId() {
42
+ return `${AF_FUNCTION_CALL_ID_PREFIX}${randomUUID()}`;
43
+ }
44
+ function populateClientFunctionCallId(modelResponseEvent) {
45
+ for (const functionCall of getFunctionCalls(modelResponseEvent)) {
46
+ if (!functionCall.id) {
47
+ functionCall.id = generateClientFunctionCallId();
48
+ }
49
+ }
50
+ }
39
51
  function getFunctionResponses(event) {
40
52
  const funcResponses = [];
41
53
  if (event.content && event.content.parts) {
@@ -65,6 +77,14 @@ function stringifyContent(event) {
65
77
  return (_a2 = part.text) != null ? _a2 : "";
66
78
  }).join("");
67
79
  }
80
+ function getEventTokens(event) {
81
+ var _a;
82
+ if (((_a = event.usageMetadata) == null ? void 0 : _a.promptTokenCount) !== void 0) {
83
+ return event.usageMetadata.promptTokenCount;
84
+ }
85
+ const contentStr = stringifyContent(event);
86
+ return Math.ceil(contentStr.length / 4);
87
+ }
68
88
  function hasThoughts(event) {
69
89
  var _a, _b;
70
90
  return !!((_b = (_a = event.content) == null ? void 0 : _a.parts) == null ? void 0 : _b.some((part) => part.thought === true));
@@ -120,13 +140,17 @@ function transformToSnakeCaseEvent(event) {
120
140
  return toSnakeCase(event, PRESERVE_KEYS_CAMEL_CASE);
121
141
  }
122
142
  export {
143
+ AF_FUNCTION_CALL_ID_PREFIX,
123
144
  createEvent,
124
145
  createNewEventId,
146
+ generateClientFunctionCallId,
147
+ getEventTokens,
125
148
  getFunctionCalls,
126
149
  getFunctionResponses,
127
150
  hasThoughts,
128
151
  hasTrailingCodeExecutionResult,
129
152
  isFinalResponse,
153
+ populateClientFunctionCallId,
130
154
  pruneThoughts,
131
155
  stringifyContent,
132
156
  transformToCamelCaseEvent,
package/dist/esm/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";
@@ -29,11 +30,15 @@ import {
29
30
  loadSkillFromDir,
30
31
  validateSkillDir
31
32
  } from "./skills/loader.js";
32
- import { RunSkillInlineScriptTool } from "./tools/skill/run_skill_inline_script_tool.js";
33
+ import {
34
+ RunSkillInlineScriptErrorCode,
35
+ RunSkillInlineScriptTool
36
+ } from "./tools/skill/run_skill_inline_script_tool.js";
33
37
  import { RunSkillScriptTool } from "./tools/skill/run_skill_script_tool.js";
34
38
  export * from "./integrations/agent_registry/agent_registry.js";
35
39
  export * from "./telemetry/google_cloud.js";
36
40
  export * from "./telemetry/setup.js";
41
+ export * from "./tools/mcp/load_mcp_resource_tool.js";
37
42
  export * from "./tools/mcp/mcp_session_manager.js";
38
43
  export * from "./tools/mcp/mcp_tool.js";
39
44
  export * from "./tools/mcp/mcp_toolset.js";
@@ -47,10 +52,12 @@ export {
47
52
  GcsArtifactService,
48
53
  InvocationContext,
49
54
  RemoteA2AAgent,
55
+ RunSkillInlineScriptErrorCode,
50
56
  RunSkillInlineScriptTool,
51
57
  RunSkillScriptTool,
52
58
  UnsafeLocalCodeExecutor,
53
59
  VertexAiSessionService,
60
+ bearerTokenUserBuilder,
54
61
  getA2AAgentCard,
55
62
  getArtifactServiceFromUri,
56
63
  getSessionServiceFromUri,
@@ -10,6 +10,7 @@ import {
10
10
  MCPSessionManager
11
11
  } from "../../tools/mcp/mcp_session_manager.js";
12
12
  import { MCPTool } from "../../tools/mcp/mcp_tool.js";
13
+ import { logger } from "../../utils/logger.js";
13
14
  import { GCP_MCP_SERVER_DESTINATION_ID } from "./types.js";
14
15
  class AgentRegistrySingleMCPToolset extends BaseToolset {
15
16
  /**
@@ -65,7 +66,14 @@ class AgentRegistrySingleMCPToolset extends BaseToolset {
65
66
  };
66
67
  const sessionManager = new MCPSessionManager(connectionParamsCopy);
67
68
  const session = await sessionManager.createSession();
68
- const listResult = await session.listTools();
69
+ let listResult;
70
+ try {
71
+ listResult = await session.listTools();
72
+ } finally {
73
+ await sessionManager.closeSession(session).catch((e) => {
74
+ logger.warn("Failed to close MCP discovery session", e);
75
+ });
76
+ }
69
77
  const tools = listResult.tools.map((tool) => {
70
78
  const prefixedName = this.prefix ? `${this.prefix}_${tool.name}` : tool.name;
71
79
  const mcpTool = new MCPTool(
@@ -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) => {
@@ -8,7 +8,10 @@ const require = topLevelCreateRequire(import.meta.url);
8
8
  import { Client } from "@google-cloud/vertexai";
9
9
  import { createUserContent } from "@google/genai";
10
10
  import { logger } from "../utils/logger.js";
11
- import { getExpressModeApiKey } from "../utils/vertex_ai_utils.js";
11
+ import {
12
+ EXPRESS_MODE_UNSUPPORTED_MESSAGE,
13
+ getExpressModeApiKey
14
+ } from "../utils/vertex_ai_utils.js";
12
15
  const GENERATE_MEMORIES_KNOWN_FIELDS = [
13
16
  "disableConsolidation",
14
17
  "waitForCompletion",
@@ -89,6 +92,9 @@ class VertexAiMemoryBankService {
89
92
  if (options.client) {
90
93
  this.memories = options.client.agentEnginesInternal.memories;
91
94
  } else {
95
+ if (this.expressModeApiKey && (!this.projectId || !this.location)) {
96
+ throw new Error(EXPRESS_MODE_UNSUPPORTED_MESSAGE);
97
+ }
92
98
  const client = new Client({
93
99
  project: this.projectId,
94
100
  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) {
@@ -0,0 +1,69 @@
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 { injectSessionState } from "../agents/instructions.js";
9
+ import { ReadonlyContext } from "../agents/readonly_context.js";
10
+ import { BasePlugin } from "./base_plugin.js";
11
+ class GlobalInstructionPlugin extends BasePlugin {
12
+ /**
13
+ * Initializes the GlobalInstructionPlugin.
14
+ *
15
+ * @param globalInstruction The instruction to apply globally. Can be a string
16
+ * or an InstructionProvider function that takes ReadonlyContext and
17
+ * returns a string (sync or async).
18
+ * @param name The name of the plugin (defaults to 'global_instruction').
19
+ */
20
+ constructor(globalInstruction, name = "global_instruction") {
21
+ super(name);
22
+ this.globalInstruction = globalInstruction;
23
+ }
24
+ async beforeModelCallback(params) {
25
+ if (!this.globalInstruction) {
26
+ return;
27
+ }
28
+ const readonlyContext = new ReadonlyContext(
29
+ params.callbackContext.invocationContext
30
+ );
31
+ const finalGlobalInstruction = await this.resolveGlobalInstruction(readonlyContext);
32
+ if (!finalGlobalInstruction) {
33
+ return;
34
+ }
35
+ if (!params.llmRequest.config) {
36
+ params.llmRequest.config = {};
37
+ }
38
+ const existingInstruction = params.llmRequest.config.systemInstruction;
39
+ if (!existingInstruction || Array.isArray(existingInstruction) && existingInstruction.length === 0) {
40
+ params.llmRequest.config.systemInstruction = finalGlobalInstruction;
41
+ return;
42
+ }
43
+ if (typeof existingInstruction === "string") {
44
+ params.llmRequest.config.systemInstruction = `${finalGlobalInstruction}
45
+
46
+ ${existingInstruction}`;
47
+ } else if (Array.isArray(existingInstruction)) {
48
+ params.llmRequest.config.systemInstruction = [
49
+ finalGlobalInstruction,
50
+ ...existingInstruction
51
+ ];
52
+ } else {
53
+ params.llmRequest.config.systemInstruction = [
54
+ finalGlobalInstruction,
55
+ existingInstruction
56
+ ];
57
+ }
58
+ return;
59
+ }
60
+ async resolveGlobalInstruction(readonlyContext) {
61
+ if (typeof this.globalInstruction === "string") {
62
+ return await injectSessionState(this.globalInstruction, readonlyContext);
63
+ }
64
+ return await this.globalInstruction(readonlyContext);
65
+ }
66
+ }
67
+ export {
68
+ GlobalInstructionPlugin
69
+ };
@@ -120,7 +120,7 @@ class Runner {
120
120
  ctx,
121
121
  this,
122
122
  async function* () {
123
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
123
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
124
124
  const session = await this.sessionService.getSession({
125
125
  appName: this.appName,
126
126
  userId,
@@ -181,7 +181,7 @@ class Runner {
181
181
  throw new Error("No parts in the newMessage.");
182
182
  }
183
183
  if (runConfig.saveInputBlobsAsArtifacts) {
184
- await this.saveArtifacts(
184
+ newMessage = await this.saveArtifacts(
185
185
  invocationContext.invocationId,
186
186
  session.userId,
187
187
  session.id,
@@ -237,24 +237,31 @@ class Runner {
237
237
  if ((_h = params.abortSignal) == null ? void 0 : _h.aborted) {
238
238
  return;
239
239
  }
240
- if (!event.partial) {
241
- await this.sessionService.appendEvent({ session, event });
242
- }
243
240
  const modifiedEvent = await this.pluginManager.runOnEventCallback({
244
241
  invocationContext,
245
242
  event
246
243
  });
247
- if ((_i = params.abortSignal) == null ? void 0 : _i.aborted) {
248
- return;
244
+ const outputEvent = modifiedEvent ? {
245
+ ...modifiedEvent,
246
+ id: event.id,
247
+ invocationId: event.invocationId,
248
+ timestamp: event.timestamp,
249
+ author: modifiedEvent.author || event.author,
250
+ branch: (_i = modifiedEvent.branch) != null ? _i : event.branch
251
+ } : event;
252
+ if (!event.partial) {
253
+ await this.sessionService.appendEvent({
254
+ session,
255
+ event: outputEvent
256
+ });
249
257
  }
250
- if (modifiedEvent) {
251
- yield modifiedEvent;
252
- } else {
253
- yield event;
258
+ if ((_j = params.abortSignal) == null ? void 0 : _j.aborted) {
259
+ return;
254
260
  }
261
+ yield outputEvent;
255
262
  }
256
263
  await this.pluginManager.runAfterRunCallback({ invocationContext });
257
- if ((_j = params.abortSignal) == null ? void 0 : _j.aborted) {
264
+ if ((_k = params.abortSignal) == null ? void 0 : _k.aborted) {
258
265
  return;
259
266
  }
260
267
  }
@@ -269,7 +276,7 @@ class Runner {
269
276
  }
270
277
  /**
271
278
  * Saves artifacts from the message parts and replaces the inline data with
272
- * a file name placeholder.
279
+ * a file name placeholder and optional file reference.
273
280
  *
274
281
  * @param invocationId The current invocation ID.
275
282
  * @param userId The user ID of the session.
@@ -279,28 +286,67 @@ class Runner {
279
286
  async saveArtifacts(invocationId, userId, sessionId, message) {
280
287
  var _a2;
281
288
  if (!this.artifactService || !((_a2 = message.parts) == null ? void 0 : _a2.length)) {
282
- return;
289
+ return message;
283
290
  }
284
291
  const sessionKey = {
285
292
  appName: this.appName,
286
293
  userId,
287
294
  sessionId
288
295
  };
296
+ const newParts = [];
297
+ let modified = false;
289
298
  for (let i = 0; i < message.parts.length; i++) {
290
299
  const part = message.parts[i];
291
300
  if (!part.inlineData) {
301
+ newParts.push(part);
292
302
  continue;
293
303
  }
294
- const fileName = `artifact_${invocationId}_${i}`;
295
- await this.artifactService.saveArtifact({
296
- ...sessionKey,
297
- filename: fileName,
298
- artifact: part
299
- });
300
- message.parts[i] = createPartFromText(
301
- `Uploaded file: ${fileName}. It is saved into artifacts`
302
- );
304
+ try {
305
+ const inlineData = part.inlineData;
306
+ const fileName = inlineData.displayName || `artifact_${invocationId}_${i}`;
307
+ const version = await this.artifactService.saveArtifact({
308
+ ...sessionKey,
309
+ filename: fileName,
310
+ artifact: part
311
+ });
312
+ newParts.push(createPartFromText(`[Uploaded Artifact: "${fileName}"]`));
313
+ try {
314
+ const artifactVersion = await this.artifactService.getArtifactVersion(
315
+ {
316
+ ...sessionKey,
317
+ filename: fileName,
318
+ version
319
+ }
320
+ );
321
+ if ((artifactVersion == null ? void 0 : artifactVersion.canonicalUri) && /^(gs|https?):/i.test(artifactVersion.canonicalUri)) {
322
+ newParts.push({
323
+ fileData: {
324
+ fileUri: artifactVersion.canonicalUri,
325
+ mimeType: artifactVersion.mimeType || inlineData.mimeType || "",
326
+ displayName: fileName
327
+ }
328
+ });
329
+ }
330
+ } catch (error) {
331
+ logger.warn(
332
+ `Failed to resolve artifact version for ${fileName}:`,
333
+ error
334
+ );
335
+ }
336
+ modified = true;
337
+ logger.info(`Successfully saved artifact: ${fileName}`);
338
+ } catch (error) {
339
+ logger.error(`Failed to save artifact for part ${i}:`, error);
340
+ newParts.push(part);
341
+ }
303
342
  }
343
+ if (!modified) {
344
+ return message;
345
+ }
346
+ return {
347
+ ...message,
348
+ parts: newParts
349
+ };
304
350
  }
305
351
  /**
306
352
  * Determines the next agent to run to continue the session. This is primarily