@google/adk 1.3.0 → 1.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 (165) hide show
  1. package/dist/cjs/agents/active_streaming_tool.js +6 -1
  2. package/dist/cjs/agents/context.js +1 -11
  3. package/dist/cjs/agents/functions.js +35 -16
  4. package/dist/cjs/agents/instructions.js +23 -5
  5. package/dist/cjs/agents/invocation_context.js +2 -5
  6. package/dist/cjs/agents/llm_agent.js +8 -6
  7. package/dist/cjs/agents/processors/code_execution_request_processor.js +0 -3
  8. package/dist/cjs/agents/processors/content_processor_utils.js +16 -3
  9. package/dist/cjs/agents/processors/context_compactor_request_processor.js +4 -2
  10. package/dist/cjs/agents/processors/interactions_request_processor.js +63 -0
  11. package/dist/cjs/apps/app.js +79 -0
  12. package/dist/cjs/apps/resumability_config.js +44 -0
  13. package/dist/cjs/artifacts/file_artifact_service.js +14 -1
  14. package/dist/cjs/artifacts/gcs_artifact_service.js +57 -15
  15. package/dist/cjs/artifacts/in_memory_artifact_service.js +5 -1
  16. package/dist/cjs/artifacts/scoped_artifact_service.js +101 -0
  17. package/dist/cjs/artifacts/session_artifact_service.js +27 -0
  18. package/dist/cjs/auth/oauth2/oauth2_discovery.js +17 -5
  19. package/dist/cjs/auth/oauth2/oauth2_utils.js +12 -1
  20. package/dist/cjs/common.js +47 -0
  21. package/dist/cjs/context/agent_controlled_context_compactor.js +109 -0
  22. package/dist/cjs/context/token_based_context_compactor.js +42 -10
  23. package/dist/cjs/context/trajectory_thought_pruning_compactor.js +71 -0
  24. package/dist/cjs/events/event.js +24 -0
  25. package/dist/cjs/models/google_llm.js +25 -10
  26. package/dist/cjs/models/interactions_utils.js +732 -0
  27. package/dist/cjs/plugins/base_plugin.js +1 -0
  28. package/dist/cjs/runner/in_memory_runner.js +13 -2
  29. package/dist/cjs/runner/runner.js +93 -72
  30. package/dist/cjs/sessions/base_session_service.js +6 -1
  31. package/dist/cjs/sessions/database_session_service.js +24 -7
  32. package/dist/cjs/sessions/vertex_ai_session_service.js +19 -4
  33. package/dist/cjs/skills/loader.js +2 -2
  34. package/dist/cjs/tools/base_toolset.js +1 -1
  35. package/dist/cjs/tools/consolidate_context_tool.js +79 -0
  36. package/dist/cjs/tools/forwarding_artifact_service.js +16 -28
  37. package/dist/cjs/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +2 -12
  38. package/dist/cjs/utils/async_hooks_shim.js +52 -0
  39. package/dist/cjs/utils/client_labels.js +41 -3
  40. package/dist/cjs/utils/env_aware_utils.js +10 -1
  41. package/dist/cjs/utils/streaming_utils.js +10 -4
  42. package/dist/cjs/utils/task.js +62 -0
  43. package/dist/cjs/version.js +1 -1
  44. package/dist/esm/agents/active_streaming_tool.js +6 -1
  45. package/dist/esm/agents/context.js +1 -11
  46. package/dist/esm/agents/functions.js +36 -15
  47. package/dist/esm/agents/instructions.js +23 -5
  48. package/dist/esm/agents/invocation_context.js +2 -5
  49. package/dist/esm/agents/llm_agent.js +8 -6
  50. package/dist/esm/agents/processors/code_execution_request_processor.js +0 -3
  51. package/dist/esm/agents/processors/content_processor_utils.js +14 -2
  52. package/dist/esm/agents/processors/context_compactor_request_processor.js +4 -2
  53. package/dist/esm/agents/processors/interactions_request_processor.js +34 -0
  54. package/dist/esm/apps/app.js +49 -0
  55. package/dist/esm/apps/resumability_config.js +16 -0
  56. package/dist/esm/artifacts/file_artifact_service.js +14 -1
  57. package/dist/esm/artifacts/gcs_artifact_service.js +57 -15
  58. package/dist/esm/artifacts/in_memory_artifact_service.js +5 -1
  59. package/dist/esm/artifacts/scoped_artifact_service.js +73 -0
  60. package/dist/esm/artifacts/session_artifact_service.js +7 -0
  61. package/dist/esm/auth/oauth2/oauth2_discovery.js +14 -4
  62. package/dist/esm/auth/oauth2/oauth2_utils.js +12 -1
  63. package/dist/esm/common.js +42 -2
  64. package/dist/esm/context/agent_controlled_context_compactor.js +81 -0
  65. package/dist/esm/context/token_based_context_compactor.js +42 -10
  66. package/dist/esm/context/trajectory_thought_pruning_compactor.js +43 -0
  67. package/dist/esm/events/event.js +22 -0
  68. package/dist/esm/models/google_llm.js +23 -9
  69. package/dist/esm/models/interactions_utils.js +697 -0
  70. package/dist/esm/plugins/base_plugin.js +1 -0
  71. package/dist/esm/runner/in_memory_runner.js +13 -2
  72. package/dist/esm/runner/runner.js +91 -73
  73. package/dist/esm/sessions/base_session_service.js +6 -1
  74. package/dist/esm/sessions/database_session_service.js +24 -7
  75. package/dist/esm/sessions/vertex_ai_session_service.js +17 -3
  76. package/dist/esm/skills/loader.js +2 -2
  77. package/dist/esm/tools/base_toolset.js +1 -1
  78. package/dist/esm/tools/consolidate_context_tool.js +51 -0
  79. package/dist/esm/tools/forwarding_artifact_service.js +16 -28
  80. package/dist/esm/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +2 -12
  81. package/dist/esm/utils/async_hooks_shim.js +24 -0
  82. package/dist/esm/utils/client_labels.js +38 -2
  83. package/dist/esm/utils/env_aware_utils.js +10 -1
  84. package/dist/esm/utils/streaming_utils.js +10 -4
  85. package/dist/esm/utils/task.js +34 -0
  86. package/dist/esm/version.js +1 -1
  87. package/dist/types/agents/active_streaming_tool.d.ts +3 -4
  88. package/dist/types/agents/functions.d.ts +12 -9
  89. package/dist/types/agents/invocation_context.d.ts +7 -3
  90. package/dist/types/agents/processors/content_processor_utils.d.ts +8 -0
  91. package/dist/types/agents/processors/interactions_request_processor.d.ts +17 -0
  92. package/dist/types/apps/app.d.ts +52 -0
  93. package/dist/types/apps/resumability_config.d.ts +27 -0
  94. package/dist/types/artifacts/base_artifact_service.d.ts +6 -36
  95. package/dist/types/artifacts/gcs_artifact_service.d.ts +2 -1
  96. package/dist/types/artifacts/scoped_artifact_service.d.ts +25 -0
  97. package/dist/types/artifacts/session_artifact_service.d.ts +25 -0
  98. package/dist/types/auth/oauth2/oauth2_discovery.d.ts +11 -0
  99. package/dist/types/common.d.ts +20 -3
  100. package/dist/types/context/agent_controlled_context_compactor.d.ts +24 -0
  101. package/dist/types/context/base_context_compactor.d.ts +3 -0
  102. package/dist/types/context/token_based_context_compactor.d.ts +6 -1
  103. package/dist/types/context/trajectory_thought_pruning_compactor.d.ts +27 -0
  104. package/dist/types/events/event.d.ts +8 -0
  105. package/dist/types/models/google_llm.d.ts +15 -1
  106. package/dist/types/models/interactions_utils.d.ts +92 -0
  107. package/dist/types/models/llm_request.d.ts +4 -0
  108. package/dist/types/models/llm_response.d.ts +4 -0
  109. package/dist/types/plugins/base_plugin.d.ts +2 -1
  110. package/dist/types/runner/in_memory_runner.d.ts +7 -1
  111. package/dist/types/runner/runner.d.ts +43 -9
  112. package/dist/types/sessions/base_session_service.d.ts +3 -16
  113. package/dist/types/sessions/session.d.ts +11 -0
  114. package/dist/types/sessions/vertex_ai_session_service.d.ts +9 -1
  115. package/dist/types/tools/consolidate_context_tool.d.ts +19 -0
  116. package/dist/types/tools/forwarding_artifact_service.d.ts +3 -2
  117. package/dist/types/utils/async_hooks_shim.d.ts +10 -0
  118. package/dist/types/utils/client_labels.d.ts +10 -0
  119. package/dist/types/utils/env_aware_utils.d.ts +3 -3
  120. package/dist/types/utils/task.d.ts +24 -0
  121. package/dist/types/version.d.ts +1 -1
  122. package/dist/web/agents/active_streaming_tool.js +6 -1
  123. package/dist/web/agents/context.js +1 -11
  124. package/dist/web/agents/functions.js +36 -15
  125. package/dist/web/agents/instructions.js +23 -5
  126. package/dist/web/agents/invocation_context.js +2 -5
  127. package/dist/web/agents/llm_agent.js +8 -6
  128. package/dist/web/agents/processors/code_execution_request_processor.js +0 -3
  129. package/dist/web/agents/processors/content_processor_utils.js +14 -2
  130. package/dist/web/agents/processors/context_compactor_request_processor.js +4 -2
  131. package/dist/web/agents/processors/interactions_request_processor.js +52 -0
  132. package/dist/web/apps/app.js +49 -0
  133. package/dist/web/apps/resumability_config.js +31 -0
  134. package/dist/web/artifacts/file_artifact_service.js +14 -1
  135. package/dist/web/artifacts/gcs_artifact_service.js +55 -15
  136. package/dist/web/artifacts/in_memory_artifact_service.js +5 -1
  137. package/dist/web/artifacts/scoped_artifact_service.js +86 -0
  138. package/dist/web/artifacts/session_artifact_service.js +7 -0
  139. package/dist/web/auth/oauth2/oauth2_discovery.js +14 -4
  140. package/dist/web/auth/oauth2/oauth2_utils.js +12 -1
  141. package/dist/web/common.js +42 -2
  142. package/dist/web/context/agent_controlled_context_compactor.js +81 -0
  143. package/dist/web/context/token_based_context_compactor.js +42 -10
  144. package/dist/web/context/trajectory_thought_pruning_compactor.js +43 -0
  145. package/dist/web/events/event.js +20 -0
  146. package/dist/web/models/google_llm.js +54 -9
  147. package/dist/web/models/interactions_utils.js +728 -0
  148. package/dist/web/plugins/base_plugin.js +1 -0
  149. package/dist/web/runner/in_memory_runner.js +13 -2
  150. package/dist/web/runner/runner.js +111 -75
  151. package/dist/web/sessions/base_session_service.js +6 -1
  152. package/dist/web/sessions/database_session_service.js +24 -7
  153. package/dist/web/sessions/vertex_ai_session_service.js +17 -3
  154. package/dist/web/skills/loader.js +2 -2
  155. package/dist/web/tools/base_toolset.js +1 -1
  156. package/dist/web/tools/consolidate_context_tool.js +51 -0
  157. package/dist/web/tools/forwarding_artifact_service.js +16 -28
  158. package/dist/web/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +2 -12
  159. package/dist/web/utils/async_hooks_shim.js +24 -0
  160. package/dist/web/utils/client_labels.js +38 -2
  161. package/dist/web/utils/env_aware_utils.js +10 -1
  162. package/dist/web/utils/streaming_utils.js +10 -4
  163. package/dist/web/utils/task.js +34 -0
  164. package/dist/web/version.js +1 -1
  165. package/package.json +2 -2
@@ -8,12 +8,16 @@ const require = topLevelCreateRequire(import.meta.url);
8
8
  import { Storage } from "@google-cloud/storage";
9
9
  import { createPartFromBase64, createPartFromText } from "@google/genai";
10
10
  import { logger } from "../utils/logger.js";
11
+ const GCS_FILE_URI_METADATA_KEY = "adkFileUri";
12
+ const GCS_FILE_MIME_TYPE_METADATA_KEY = "adkFileMimeType";
13
+ const GCS_DISPLAY_NAME_METADATA_KEY = "adkDisplayName";
14
+ const GCS_IS_TEXT_METADATA_KEY = "adkIsText";
11
15
  class GcsArtifactService {
12
- constructor(bucket) {
13
- this.bucket = new Storage().bucket(bucket);
16
+ constructor(bucket, options) {
17
+ this.bucket = new Storage(options).bucket(bucket);
14
18
  }
15
19
  async saveArtifact(request) {
16
- if (!request.artifact.inlineData && !request.artifact.text) {
20
+ if (!request.artifact.inlineData && !request.artifact.text && !request.artifact.fileData) {
17
21
  throw new Error("Artifact must have either inlineData or text content.");
18
22
  }
19
23
  const versions = await this.listVersions(request);
@@ -24,24 +28,48 @@ class GcsArtifactService {
24
28
  version
25
29
  })
26
30
  );
27
- const metadata = request.customMetadata || {};
31
+ const customMetadata = {
32
+ ...request.customMetadata
33
+ };
28
34
  if (request.artifact.inlineData) {
35
+ if (request.artifact.inlineData.displayName) {
36
+ customMetadata[GCS_DISPLAY_NAME_METADATA_KEY] = request.artifact.inlineData.displayName;
37
+ }
29
38
  await file.save(
30
39
  Buffer.from(request.artifact.inlineData.data || "", "base64"),
31
40
  {
32
41
  contentType: request.artifact.inlineData.mimeType,
33
- metadata
42
+ metadata: { metadata: customMetadata }
34
43
  }
35
44
  );
36
45
  return version;
46
+ } else if (request.artifact.text !== void 0) {
47
+ await file.save(request.artifact.text, {
48
+ contentType: "text/plain",
49
+ metadata: {
50
+ metadata: { ...customMetadata, [GCS_IS_TEXT_METADATA_KEY]: "true" }
51
+ }
52
+ });
53
+ return version;
54
+ } else {
55
+ const fileData = request.artifact.fileData;
56
+ const fileUri = fileData == null ? void 0 : fileData.fileUri;
57
+ if (!fileUri) {
58
+ throw new Error("Artifact fileData must have a fileUri.");
59
+ }
60
+ customMetadata[GCS_FILE_URI_METADATA_KEY] = fileUri;
61
+ if (fileData.mimeType) {
62
+ customMetadata[GCS_FILE_MIME_TYPE_METADATA_KEY] = fileData.mimeType;
63
+ }
64
+ await file.save("", {
65
+ contentType: fileData.mimeType || void 0,
66
+ metadata: { metadata: customMetadata }
67
+ });
68
+ return version;
37
69
  }
38
- await file.save(request.artifact.text, {
39
- contentType: "text/plain",
40
- metadata
41
- });
42
- return version;
43
70
  }
44
71
  async loadArtifact(request) {
72
+ var _a, _b, _c;
45
73
  try {
46
74
  let version = request.version;
47
75
  if (version === void 0) {
@@ -57,11 +85,25 @@ class GcsArtifactService {
57
85
  version
58
86
  })
59
87
  );
60
- const [[metadata], [rawDataBuffer]] = await Promise.all([
61
- file.getMetadata(),
62
- file.download()
63
- ]);
64
- if (metadata.contentType === "text/plain") {
88
+ const [metadata] = await file.getMetadata();
89
+ const customMeta = (_a = metadata.metadata) != null ? _a : {};
90
+ const fileUri = customMeta[GCS_FILE_URI_METADATA_KEY];
91
+ if (fileUri) {
92
+ const mimeType = (_c = (_b = customMeta[GCS_FILE_MIME_TYPE_METADATA_KEY]) != null ? _b : metadata.contentType) != null ? _c : void 0;
93
+ return { fileData: { fileUri, mimeType } };
94
+ }
95
+ const [rawDataBuffer] = await file.download();
96
+ const displayName = customMeta[GCS_DISPLAY_NAME_METADATA_KEY];
97
+ if (displayName) {
98
+ return {
99
+ inlineData: {
100
+ data: rawDataBuffer.toString("base64"),
101
+ mimeType: metadata.contentType,
102
+ displayName
103
+ }
104
+ };
105
+ }
106
+ if (customMeta[GCS_IS_TEXT_METADATA_KEY] === "true" || metadata.contentType === "text/plain") {
65
107
  return createPartFromText(rawDataBuffer.toString("utf-8"));
66
108
  }
67
109
  return createPartFromBase64(
@@ -20,7 +20,7 @@ class InMemoryArtifactService {
20
20
  artifact,
21
21
  customMetadata
22
22
  }) {
23
- if (!artifact.inlineData && !artifact.text) {
23
+ if (!artifact.inlineData && !artifact.text && !artifact.fileData) {
24
24
  return Promise.reject(
25
25
  new Error("Artifact must have either inlineData or text content.")
26
26
  );
@@ -34,6 +34,10 @@ class InMemoryArtifactService {
34
34
  version,
35
35
  customMetadata
36
36
  };
37
+ if (!artifact.inlineData && artifact.text === void 0) {
38
+ const fileData = artifact.fileData;
39
+ metadata.mimeType = fileData.mimeType;
40
+ }
37
41
  this.artifacts[path].push({ part: artifact, metadata });
38
42
  return Promise.resolve(version);
39
43
  }
@@ -0,0 +1,73 @@
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
+ class ScopedArtifactService {
9
+ constructor(delegate, appName, userId, sessionId) {
10
+ this.delegate = delegate;
11
+ this.appName = appName;
12
+ this.userId = userId;
13
+ this.sessionId = sessionId;
14
+ }
15
+ async saveArtifact(request) {
16
+ return this.delegate.saveArtifact({
17
+ appName: this.appName,
18
+ userId: this.userId,
19
+ sessionId: this.sessionId,
20
+ ...request
21
+ });
22
+ }
23
+ async loadArtifact(request) {
24
+ return this.delegate.loadArtifact({
25
+ appName: this.appName,
26
+ userId: this.userId,
27
+ sessionId: this.sessionId,
28
+ ...request
29
+ });
30
+ }
31
+ async listArtifactKeys() {
32
+ return this.delegate.listArtifactKeys({
33
+ appName: this.appName,
34
+ userId: this.userId,
35
+ sessionId: this.sessionId
36
+ });
37
+ }
38
+ async deleteArtifact(filename) {
39
+ return this.delegate.deleteArtifact({
40
+ appName: this.appName,
41
+ userId: this.userId,
42
+ sessionId: this.sessionId,
43
+ filename
44
+ });
45
+ }
46
+ async listVersions(filename) {
47
+ return this.delegate.listVersions({
48
+ appName: this.appName,
49
+ userId: this.userId,
50
+ sessionId: this.sessionId,
51
+ filename
52
+ });
53
+ }
54
+ async listArtifactVersions(filename) {
55
+ return this.delegate.listArtifactVersions({
56
+ appName: this.appName,
57
+ userId: this.userId,
58
+ sessionId: this.sessionId,
59
+ filename
60
+ });
61
+ }
62
+ async getArtifactVersion(request) {
63
+ return this.delegate.getArtifactVersion({
64
+ appName: this.appName,
65
+ userId: this.userId,
66
+ sessionId: this.sessionId,
67
+ ...request
68
+ });
69
+ }
70
+ }
71
+ export {
72
+ ScopedArtifactService
73
+ };
@@ -0,0 +1,7 @@
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
+ */
@@ -55,7 +55,11 @@ class OAuth2DiscoveryManager {
55
55
  method: "GET",
56
56
  headers: {
57
57
  Accept: "application/json"
58
- }
58
+ },
59
+ // Never follow redirects: validateDiscoveryUrl only checks the
60
+ // initial URL, so following a 3xx would let a validated host
61
+ // redirect discovery to a private/cloud-metadata address (CWE-918).
62
+ redirect: "error"
59
63
  });
60
64
  if (!response.ok) {
61
65
  continue;
@@ -103,7 +107,11 @@ class OAuth2DiscoveryManager {
103
107
  method: "GET",
104
108
  headers: {
105
109
  Accept: "application/json"
106
- }
110
+ },
111
+ // Never follow redirects: validateDiscoveryUrl only checks the
112
+ // initial URL, so following a 3xx would let a validated host
113
+ // redirect discovery to a private/cloud-metadata address (CWE-918).
114
+ redirect: "error"
107
115
  });
108
116
  if (!response.ok) {
109
117
  return void 0;
@@ -143,7 +151,7 @@ function validateDiscoveryUrl(urlStr) {
143
151
  return false;
144
152
  }
145
153
  const host = normaliseHostname(url.hostname.toLowerCase());
146
- if (host === "localhost" || host === "metadata.google.internal" || host === "metadata.goog" || host.startsWith("127.") || host === "[::1]" || host === "0.0.0.0" || host.startsWith("10.") || host.startsWith("192.168.") || host.startsWith("169.254.")) {
154
+ if (host === "localhost" || host === "metadata.google.internal" || host === "metadata.goog" || host.startsWith("127.") || host === "[::1]" || host === "[::]" || host === "0.0.0.0" || host.startsWith("10.") || host.startsWith("192.168.") || host.startsWith("169.254.")) {
147
155
  logger.warn(`Unsafe host for discovery URL: ${host}`);
148
156
  return false;
149
157
  }
@@ -176,5 +184,7 @@ function validateDiscoveryUrl(urlStr) {
176
184
  export {
177
185
  AuthorizationServerMetadataSchema,
178
186
  OAuth2DiscoveryManager,
179
- ProtectedResourceMetadataSchema
187
+ ProtectedResourceMetadataSchema,
188
+ normaliseHostname,
189
+ validateDiscoveryUrl
180
190
  };
@@ -6,6 +6,7 @@ const require = topLevelCreateRequire(import.meta.url);
6
6
  * SPDX-License-Identifier: Apache-2.0
7
7
  */
8
8
  import { logger } from "../../utils/logger.js";
9
+ import { validateDiscoveryUrl } from "./oauth2_discovery.js";
9
10
  function getTokenEndpoint(authScheme) {
10
11
  if (authScheme.type === "openIdConnect" && authScheme.tokenEndpoint) {
11
12
  return authScheme.tokenEndpoint;
@@ -20,13 +21,23 @@ function getTokenEndpoint(authScheme) {
20
21
  return void 0;
21
22
  }
22
23
  async function fetchOAuth2Tokens(endpoint, body) {
24
+ if (!validateDiscoveryUrl(endpoint)) {
25
+ throw new Error(
26
+ `SSRF protection: OAuth2 token endpoint '${endpoint}' is not allowed. Must use HTTPS and must not target private/loopback/cloud-metadata addresses.`
27
+ );
28
+ }
23
29
  try {
24
30
  const response = await fetch(endpoint, {
25
31
  method: "POST",
26
32
  headers: {
27
33
  "Content-Type": "application/x-www-form-urlencoded"
28
34
  },
29
- body: body.toString()
35
+ body: body.toString(),
36
+ // Never follow redirects: the SSRF blocklist only validates `endpoint`,
37
+ // so a validated host that responds with a 3xx could otherwise redirect
38
+ // this credential-bearing POST (client_secret/refresh_token) to a
39
+ // private/cloud-metadata address (CWE-918).
40
+ redirect: "error"
30
41
  });
31
42
  if (!response.ok) {
32
43
  throw new Error(`Token request failed with status ${response.status}`);
@@ -8,7 +8,11 @@ const require = topLevelCreateRequire(import.meta.url);
8
8
  import { ActiveStreamingTool } from "./agents/active_streaming_tool.js";
9
9
  import { BaseAgent, isBaseAgent } from "./agents/base_agent.js";
10
10
  import { Context } from "./agents/context.js";
11
- import { functionsExportedForTestingOnly } from "./agents/functions.js";
11
+ import {
12
+ findEventByFunctionCallId,
13
+ findMatchingFunctionCall,
14
+ functionsExportedForTestingOnly
15
+ } from "./agents/functions.js";
12
16
  import { InvocationContext } from "./agents/invocation_context.js";
13
17
  import { LiveRequestQueue } from "./agents/live_request_queue.js";
14
18
  import { LlmAgent, LlmAgent as LlmAgent2, isLlmAgent } from "./agents/llm_agent.js";
@@ -24,10 +28,15 @@ import {
24
28
  ContentRequestProcessor
25
29
  } from "./agents/processors/content_request_processor.js";
26
30
  import { ContextCompactorRequestProcessor } from "./agents/processors/context_compactor_request_processor.js";
31
+ import {
32
+ INTERACTIONS_REQUEST_PROCESSOR,
33
+ InteractionsRequestProcessor
34
+ } from "./agents/processors/interactions_request_processor.js";
27
35
  import { ReadonlyContext } from "./agents/readonly_context.js";
28
36
  import { RoutedAgent, isRoutedAgent } from "./agents/routed_agent.js";
29
37
  import { StreamingMode } from "./agents/run_config.js";
30
38
  import { SequentialAgent, isSequentialAgent } from "./agents/sequential_agent.js";
39
+ import { createResumabilityConfig } from "./apps/resumability_config.js";
31
40
  import { InMemoryArtifactService } from "./artifacts/in_memory_artifact_service.js";
32
41
  import { AuthCredentialTypes } from "./auth/auth_credential.js";
33
42
  import { AuthHandler } from "./auth/auth_handler.js";
@@ -46,8 +55,10 @@ import {
46
55
  CodeExecutionLanguage,
47
56
  FileContentEncoding
48
57
  } from "./code_executors/code_execution_utils.js";
58
+ import { AgentControlledContextCompactor } from "./context/agent_controlled_context_compactor.js";
49
59
  import { LlmSummarizer } from "./context/summarizers/llm_summarizer.js";
50
60
  import { TokenBasedContextCompactor } from "./context/token_based_context_compactor.js";
61
+ import { TrajectoryThoughtPruningCompactor } from "./context/trajectory_thought_pruning_compactor.js";
51
62
  import { TruncatingContextCompactor } from "./context/truncating_context_compactor.js";
52
63
  import { isCompactedEvent } from "./events/compacted_event.js";
53
64
  import {
@@ -82,7 +93,13 @@ import {
82
93
  getAskUserConfirmationFunctionCalls
83
94
  } from "./plugins/security_plugin.js";
84
95
  import { InMemoryRunner } from "./runner/in_memory_runner.js";
85
- import { Runner, isRunner } from "./runner/runner.js";
96
+ import {
97
+ Runner,
98
+ determineAgentForResumption,
99
+ findEventByLastFunctionResponseId,
100
+ isRoutableLlmAgent,
101
+ isRunner
102
+ } from "./runner/runner.js";
86
103
  import { BaseSessionService } from "./sessions/base_session_service.js";
87
104
  import { InMemorySessionService } from "./sessions/in_memory_session_service.js";
88
105
  import { createSession } from "./sessions/session.js";
@@ -90,6 +107,7 @@ import { State } from "./sessions/state.js";
90
107
  import { AgentTool, isAgentTool } from "./tools/agent_tool.js";
91
108
  import { BaseTool, isBaseTool } from "./tools/base_tool.js";
92
109
  import { BaseToolset, isBaseToolset } from "./tools/base_toolset.js";
110
+ import { ConsolidateContextTool } from "./tools/consolidate_context_tool.js";
93
111
  import { EXIT_LOOP, ExitLoopTool } from "./tools/exit_loop_tool.js";
94
112
  import { FunctionTool, isFunctionTool } from "./tools/function_tool.js";
95
113
  import {
@@ -111,9 +129,11 @@ import { ToolConfirmation } from "./tools/tool_confirmation.js";
111
129
  import { URL_CONTEXT, UrlContextTool } from "./tools/url_context_tool.js";
112
130
  import { VertexAiSearchTool } from "./tools/vertex_ai_search_tool.js";
113
131
  import { VertexRagRetrievalTool } from "./tools/vertex_rag_retrieval_tool.js";
132
+ import { getClientLabels, runWithClientLabel } from "./utils/client_labels.js";
114
133
  import { LogLevel, getLogger, setLogLevel, setLogger } from "./utils/logger.js";
115
134
  import { isGemini2OrAbove, isGemini3xFlashLive } from "./utils/model_name.js";
116
135
  import { zodObjectToSchema } from "./utils/simple_zod_to_json.js";
136
+ import { Task } from "./utils/task.js";
117
137
  import { GoogleLLMVariant } from "./utils/variant_utils.js";
118
138
  import { version } from "./version.js";
119
139
  import { GCPSkillRegistry } from "./skills/gcp_skill_registry.js";
@@ -128,6 +148,11 @@ import { LoadSkillResourceTool } from "./tools/skill/load_skill_resource_tool.js
128
148
  import { LoadSkillTool } from "./tools/skill/load_skill_tool.js";
129
149
  import { SearchSkillsTool } from "./tools/skill/search_skills_tool.js";
130
150
  import { SkillToolset } from "./tools/skill/skill_toolset.js";
151
+ export * from "./artifacts/base_artifact_service.js";
152
+ export * from "./features/feature_registry.js";
153
+ export * from "./memory/base_memory_service.js";
154
+ export * from "./sessions/base_session_service.js";
155
+ export * from "./tools/base_tool.js";
131
156
  import { OpenApiSpecParser } from "./tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.js";
132
157
  import { OperationParser } from "./tools/openapi_tool/openapi_spec_parser/operation_parser.js";
133
158
  import { ToolAuthHandler } from "./tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js";
@@ -136,6 +161,7 @@ import {
136
161
  RestApiTool,
137
162
  createRestApiTool
138
163
  } from "./tools/openapi_tool/rest_api_tool.js";
164
+ export * from "./apps/app.js";
139
165
  export * from "./artifacts/base_artifact_service.js";
140
166
  export * from "./features/feature_registry.js";
141
167
  export * from "./memory/base_memory_service.js";
@@ -145,6 +171,7 @@ export {
145
171
  AUTH_PREPROCESSOR,
146
172
  ActiveStreamingTool,
147
173
  LlmAgent as Agent,
174
+ AgentControlledContextCompactor,
148
175
  AgentTool,
149
176
  AgentTransferLlmRequestProcessor,
150
177
  ApigeeLlm,
@@ -165,6 +192,7 @@ export {
165
192
  BuiltInCodeExecutor,
166
193
  CONTENT_REQUEST_PROCESSOR,
167
194
  CodeExecutionLanguage,
195
+ ConsolidateContextTool,
168
196
  ContentRequestProcessor,
169
197
  Context,
170
198
  ContextCompactionTrigger,
@@ -183,12 +211,14 @@ export {
183
211
  GoogleLLMVariant,
184
212
  GoogleMapsGroundingTool,
185
213
  GoogleSearchTool,
214
+ INTERACTIONS_REQUEST_PROCESSOR,
186
215
  InMemoryArtifactService,
187
216
  InMemoryCredentialService,
188
217
  InMemoryMemoryService,
189
218
  InMemoryPolicyEngine,
190
219
  InMemoryRunner,
191
220
  InMemorySessionService,
221
+ InteractionsRequestProcessor,
192
222
  InvocationContext,
193
223
  LLMRegistry,
194
224
  LOAD_ARTIFACTS,
@@ -229,9 +259,11 @@ export {
229
259
  SkillToolset,
230
260
  State,
231
261
  StreamingMode,
262
+ Task,
232
263
  TokenBasedContextCompactor,
233
264
  ToolAuthHandler,
234
265
  ToolConfirmation,
266
+ TrajectoryThoughtPruningCompactor,
235
267
  TruncatingContextCompactor,
236
268
  URL_CONTEXT,
237
269
  UrlContextTool,
@@ -241,10 +273,16 @@ export {
241
273
  createEvent,
242
274
  createEventActions,
243
275
  createRestApiTool,
276
+ createResumabilityConfig,
244
277
  createSession,
278
+ determineAgentForResumption,
279
+ findEventByFunctionCallId,
280
+ findEventByLastFunctionResponseId,
281
+ findMatchingFunctionCall,
245
282
  functionsExportedForTestingOnly,
246
283
  geminiInitParams,
247
284
  getAskUserConfirmationFunctionCalls,
285
+ getClientLabels,
248
286
  getFunctionCalls,
249
287
  getFunctionResponses,
250
288
  getLogger,
@@ -263,12 +301,14 @@ export {
263
301
  isLlmAgent,
264
302
  isLoopAgent,
265
303
  isParallelAgent,
304
+ isRoutableLlmAgent,
266
305
  isRoutedAgent,
267
306
  isRunner,
268
307
  isSequentialAgent,
269
308
  loadAllSkillsInDir,
270
309
  loadSkillFromDir,
271
310
  loadSkillFromZipBuffer,
311
+ runWithClientLabel,
272
312
  setLogLevel,
273
313
  setLogger,
274
314
  stringifyContent,
@@ -0,0 +1,81 @@
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 { createEvent } from "../events/event.js";
10
+ import { ContextCompactionTrigger } from "../plugins/base_plugin.js";
11
+ class AgentControlledContextCompactor {
12
+ constructor(options) {
13
+ this.trigger = ContextCompactionTrigger.AgentControlled;
14
+ this.summarizer = options.summarizer;
15
+ }
16
+ shouldCompact(invocationContext) {
17
+ return invocationContext.session.state["temp:consolidate_context"] === true;
18
+ }
19
+ async compact(invocationContext) {
20
+ const events = invocationContext.session.events;
21
+ const activeEvents = this.getActiveEvents(events);
22
+ const consolidateToolCallIndex = activeEvents.reduce(
23
+ (acc, e, idx) => {
24
+ var _a, _b;
25
+ return ((_b = (_a = e.content) == null ? void 0 : _a.parts) == null ? void 0 : _b.some(
26
+ (p) => {
27
+ var _a2;
28
+ return ((_a2 = p.functionCall) == null ? void 0 : _a2.name) === "consolidate_context";
29
+ }
30
+ )) ? idx : acc;
31
+ },
32
+ -1
33
+ );
34
+ if (consolidateToolCallIndex <= 0) {
35
+ this.clearFlags(invocationContext);
36
+ return;
37
+ }
38
+ const eventsToCompact = activeEvents.slice(0, consolidateToolCallIndex);
39
+ const detail = invocationContext.session.state["temp:consolidate_context_detail"];
40
+ if (detail) {
41
+ eventsToCompact.push(
42
+ createEvent({
43
+ author: "system",
44
+ timestamp: eventsToCompact[eventsToCompact.length - 1].timestamp,
45
+ content: {
46
+ role: "user",
47
+ parts: [
48
+ {
49
+ text: `CRITICAL INSTRUCTION FOR SUMMARY: Please summarize the history. Focus especially on: ${detail}`
50
+ }
51
+ ]
52
+ }
53
+ })
54
+ );
55
+ }
56
+ try {
57
+ const compactedEvent = await this.summarizer.summarize(eventsToCompact);
58
+ invocationContext.session.events.push(compactedEvent);
59
+ } catch (error) {
60
+ console.error("Compaction failed:", error);
61
+ } finally {
62
+ this.clearFlags(invocationContext);
63
+ }
64
+ }
65
+ clearFlags(invocationContext) {
66
+ delete invocationContext.session.state["temp:consolidate_context"];
67
+ delete invocationContext.session.state["temp:consolidate_context_detail"];
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
+ }
79
+ export {
80
+ AgentControlledContextCompactor
81
+ };
@@ -5,8 +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 { getContents } from "../agents/processors/content_processor_utils.js";
8
9
  import { isCompactedEvent } from "../events/compacted_event.js";
9
- import { stringifyContent } from "../events/event.js";
10
+ const CHARS_PER_TOKEN = 4;
10
11
  class TokenBasedContextCompactor {
11
12
  constructor(options) {
12
13
  this.tokenThreshold = options.tokenThreshold;
@@ -38,11 +39,14 @@ class TokenBasedContextCompactor {
38
39
  if (rawEvents.length <= this.eventRetentionSize) {
39
40
  return false;
40
41
  }
41
- let totalTokens = 0;
42
- for (const event of activeEvents) {
43
- totalTokens += getEventTokens(event);
42
+ const promptTokenCount = latestPromptTokenCount(
43
+ activeEvents,
44
+ invocationContext
45
+ );
46
+ if (promptTokenCount === void 0) {
47
+ return false;
44
48
  }
45
- return totalTokens > this.tokenThreshold;
49
+ return promptTokenCount > this.tokenThreshold;
46
50
  }
47
51
  async compact(invocationContext) {
48
52
  const events = invocationContext.session.events;
@@ -82,13 +86,41 @@ class TokenBasedContextCompactor {
82
86
  invocationContext.session.events.push(compactedEvent);
83
87
  }
84
88
  }
85
- function getEventTokens(event) {
89
+ function latestPromptTokenCount(activeEvents, invocationContext) {
90
+ var _a;
91
+ for (let i = activeEvents.length - 1; i >= 0; i--) {
92
+ const count = (_a = activeEvents[i].usageMetadata) == null ? void 0 : _a.promptTokenCount;
93
+ if (count !== void 0) {
94
+ return count;
95
+ }
96
+ }
97
+ return estimatePromptTokenCount(activeEvents, invocationContext);
98
+ }
99
+ function estimatePromptTokenCount(activeEvents, invocationContext) {
86
100
  var _a;
87
- if (((_a = event.usageMetadata) == null ? void 0 : _a.promptTokenCount) !== void 0) {
88
- return event.usageMetadata.promptTokenCount;
101
+ const contents = getContents(
102
+ activeEvents,
103
+ invocationContext.agent.name,
104
+ invocationContext.branch
105
+ );
106
+ let totalChars = 0;
107
+ for (const content of contents) {
108
+ for (const part of (_a = content.parts) != null ? _a : []) {
109
+ if (part.text) {
110
+ totalChars += part.text.length;
111
+ }
112
+ if (part.functionCall) {
113
+ totalChars += JSON.stringify(part.functionCall).length;
114
+ }
115
+ if (part.functionResponse) {
116
+ totalChars += JSON.stringify(part.functionResponse).length;
117
+ }
118
+ }
119
+ }
120
+ if (totalChars <= 0) {
121
+ return void 0;
89
122
  }
90
- const contentStr = stringifyContent(event);
91
- return Math.ceil(contentStr.length / 4);
123
+ return Math.ceil(totalChars / CHARS_PER_TOKEN);
92
124
  }
93
125
  function hasFunctionCall(event) {
94
126
  var _a, _b;
@@ -0,0 +1,43 @@
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 { hasThoughts, pruneThoughts } from "../events/event.js";
9
+ class TrajectoryThoughtPruningCompactor {
10
+ constructor(options) {
11
+ if (options.eventRetentionSize < 0) {
12
+ throw new Error("eventRetentionSize must be a non-negative integer.");
13
+ }
14
+ this.eventRetentionSize = options.eventRetentionSize;
15
+ }
16
+ shouldCompact(invocationContext) {
17
+ const events = invocationContext.session.events;
18
+ if (events.length <= this.eventRetentionSize) {
19
+ return false;
20
+ }
21
+ const olderEvents = events.slice(
22
+ 0,
23
+ events.length - this.eventRetentionSize
24
+ );
25
+ return olderEvents.some((event) => hasThoughts(event));
26
+ }
27
+ compact(invocationContext) {
28
+ const events = invocationContext.session.events;
29
+ if (events.length <= this.eventRetentionSize) {
30
+ return;
31
+ }
32
+ const pruneLimit = events.length - this.eventRetentionSize;
33
+ for (let i = 0; i < pruneLimit; i++) {
34
+ const event = events[i];
35
+ if (hasThoughts(event)) {
36
+ events[i] = pruneThoughts(event);
37
+ }
38
+ }
39
+ }
40
+ }
41
+ export {
42
+ TrajectoryThoughtPruningCompactor
43
+ };