@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
@@ -24,9 +24,12 @@ var __copyProps = (to, from, except, desc) => {
24
24
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
25
  var client_labels_exports = {};
26
26
  __export(client_labels_exports, {
27
- getClientLabels: () => getClientLabels
27
+ getClientLabels: () => getClientLabels,
28
+ parseUserAgent: () => parseUserAgent,
29
+ runWithClientLabel: () => runWithClientLabel
28
30
  });
29
31
  module.exports = __toCommonJS(client_labels_exports);
32
+ var import_node_async_hooks = require("node:async_hooks");
30
33
  var import_version = require("../version.js");
31
34
  var import_env_aware_utils = require("./env_aware_utils.js");
32
35
  /**
@@ -38,19 +41,54 @@ const ADK_LABEL = "google-adk";
38
41
  const LANGUAGE_LABEL = "gl-typescript";
39
42
  const AGENT_ENGINE_TELEMETRY_TAG = "remote_reasoning_engine";
40
43
  const AGENT_ENGINE_TELEMETRY_ENV_VARIABLE_NAME = "GOOGLE_CLOUD_AGENT_ENGINE_ID";
44
+ const clientLabelLocalStorage = new import_node_async_hooks.AsyncLocalStorage();
45
+ const USER_AGENT_PATTERNS = [
46
+ ["Edge", /(?:Edg|Edge|EdgA)\/([0-9.]+)/i],
47
+ ["Firefox", /(?:Firefox|FxiOS)\/([0-9.]+)/i],
48
+ ["Chrome", /(?:Chrome|CriOS)\/([0-9.]+)/i],
49
+ ["Safari", /Version\/([0-9.]+).*Safari/i]
50
+ ];
51
+ function parseUserAgent(userAgent) {
52
+ if (!userAgent) {
53
+ return "Browser";
54
+ }
55
+ for (const [name, regex] of USER_AGENT_PATTERNS) {
56
+ const match = userAgent.match(regex);
57
+ if (match) {
58
+ return `${name}/${match[1]}`;
59
+ }
60
+ }
61
+ return "Browser";
62
+ }
41
63
  function _getDefaultLabels() {
42
64
  let frameworkLabel = `${ADK_LABEL}/${import_version.version}`;
43
65
  if (!(0, import_env_aware_utils.isBrowser)() && process.env[AGENT_ENGINE_TELEMETRY_ENV_VARIABLE_NAME]) {
44
66
  frameworkLabel = `${frameworkLabel}+${AGENT_ENGINE_TELEMETRY_TAG}`;
45
67
  }
46
- const languageLabel = `${LANGUAGE_LABEL}/${(0, import_env_aware_utils.isBrowser)() ? window.navigator.userAgent : process.version}`;
68
+ const languageLabelDetail = (0, import_env_aware_utils.isBrowser)() ? (
69
+ // eslint-disable-next-line no-undef
70
+ parseUserAgent(window.navigator.userAgent)
71
+ ) : process.version;
72
+ const languageLabel = `${LANGUAGE_LABEL}/${languageLabelDetail}`;
47
73
  return [frameworkLabel, languageLabel];
48
74
  }
75
+ function runWithClientLabel(clientLabel, callback) {
76
+ if (typeof clientLabel !== "string" || clientLabel.trim() === "") {
77
+ throw new Error("Client label must be a non-empty string.");
78
+ }
79
+ return clientLabelLocalStorage.run(clientLabel, callback);
80
+ }
49
81
  function getClientLabels() {
50
82
  const labels = _getDefaultLabels();
83
+ const contextLabel = clientLabelLocalStorage.getStore();
84
+ if (contextLabel) {
85
+ labels.push(contextLabel);
86
+ }
51
87
  return labels;
52
88
  }
53
89
  // Annotate the CommonJS export names for ESM import in node:
54
90
  0 && (module.exports = {
55
- getClientLabels
91
+ getClientLabels,
92
+ parseUserAgent,
93
+ runWithClientLabel
56
94
  });
@@ -61,7 +61,16 @@ function randomUUID() {
61
61
  }
62
62
  function base64Encode(data) {
63
63
  if (isBrowser()) {
64
- return window.btoa(data);
64
+ let strData = "";
65
+ if (typeof data === "string") {
66
+ strData = data;
67
+ } else {
68
+ const len = data.byteLength;
69
+ for (let i = 0; i < len; i++) {
70
+ strData += String.fromCharCode(data[i]);
71
+ }
72
+ }
73
+ return window.btoa(strData);
65
74
  }
66
75
  return Buffer.from(data).toString("base64");
67
76
  }
@@ -356,10 +356,16 @@ class StreamingResponseAggregator {
356
356
  const candidate = (_b = (_a = this.response) == null ? void 0 : _a.candidates) == null ? void 0 : _b[0];
357
357
  const finishReason = (_c = this.finishReason) != null ? _c : candidate == null ? void 0 : candidate.finishReason;
358
358
  return {
359
- content: {
360
- role: "model",
361
- parts: finalParts != null ? finalParts : []
362
- },
359
+ // Only attach a model `content` when there are actual parts to emit. When
360
+ // the turn accumulated no parts (e.g. a function call that was already
361
+ // flushed, followed by a trailing STOP chunk that carries only usage
362
+ // metadata) we still surface that trailing metadata, but MUST NOT emit
363
+ // `content: { parts: [] }`. An empty-parts model turn corrupts the session
364
+ // history: on the next request the Vertex AI backend rejects the whole
365
+ // call with HTTP 400 "Unable to submit request because it must include at
366
+ // least one parts field", which breaks multi-turn tool-using sessions
367
+ // right after the first tool call (google/adk-js#21, #22).
368
+ content: finalParts ? { role: "model", parts: finalParts } : void 0,
363
369
  groundingMetadata: this.groundingMetadata,
364
370
  citationMetadata: this.citationMetadata,
365
371
  errorCode: finishReason === import_genai.FinishReason.STOP ? void 0 : finishReason,
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ "use strict";
8
+ var __defProp = Object.defineProperty;
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
+ var __getOwnPropNames = Object.getOwnPropertyNames;
11
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
12
+ var __export = (target, all) => {
13
+ for (var name in all)
14
+ __defProp(target, name, { get: all[name], enumerable: true });
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from))
19
+ if (!__hasOwnProp.call(to, key) && key !== except)
20
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
+ }
22
+ return to;
23
+ };
24
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
+ var task_exports = {};
26
+ __export(task_exports, {
27
+ Task: () => Task
28
+ });
29
+ module.exports = __toCommonJS(task_exports);
30
+ /**
31
+ * @license
32
+ * Copyright 2026 Google LLC
33
+ * SPDX-License-Identifier: Apache-2.0
34
+ */
35
+ class Task {
36
+ constructor(executable) {
37
+ this.executable = executable;
38
+ this.isDone = false;
39
+ this.abortController = new AbortController();
40
+ const markDone = () => {
41
+ this.isDone = true;
42
+ };
43
+ this.promise = executable(this.abortController.signal);
44
+ this.promise.then(markDone).catch(markDone);
45
+ }
46
+ /**
47
+ * Cancels the task execution.
48
+ */
49
+ cancel() {
50
+ this.abortController.abort();
51
+ }
52
+ /**
53
+ * Returns true if the task has completed (either resolved or rejected).
54
+ */
55
+ done() {
56
+ return this.isDone;
57
+ }
58
+ }
59
+ // Annotate the CommonJS export names for ESM import in node:
60
+ 0 && (module.exports = {
61
+ Task
62
+ });
@@ -32,7 +32,7 @@ module.exports = __toCommonJS(version_exports);
32
32
  * Copyright 2025 Google LLC
33
33
  * SPDX-License-Identifier: Apache-2.0
34
34
  */
35
- const version = "1.3.0";
35
+ const version = "1.4.0";
36
36
  // Annotate the CommonJS export names for ESM import in node:
37
37
  0 && (module.exports = {
38
38
  version
@@ -5,9 +5,14 @@ const require = topLevelCreateRequire(import.meta.url);
5
5
  * Copyright 2025 Google LLC
6
6
  * SPDX-License-Identifier: Apache-2.0
7
7
  */
8
+ import { Task } from "../utils/task.js";
8
9
  class ActiveStreamingTool {
9
10
  constructor(params = {}) {
10
- this.task = params.task;
11
+ if (params.task instanceof Promise) {
12
+ this.task = new Task(() => params.task);
13
+ } else {
14
+ this.task = params.task;
15
+ }
11
16
  this.stream = params.stream;
12
17
  }
13
18
  }
@@ -56,9 +56,6 @@ class Context extends ReadonlyContext {
56
56
  throw new Error("Artifact service is not initialized.");
57
57
  }
58
58
  return this.invocationContext.artifactService.loadArtifact({
59
- appName: this.invocationContext.appName,
60
- userId: this.invocationContext.userId,
61
- sessionId: this.invocationContext.session.id,
62
59
  filename,
63
60
  version
64
61
  });
@@ -75,9 +72,6 @@ class Context extends ReadonlyContext {
75
72
  throw new Error("Artifact service is not initialized.");
76
73
  }
77
74
  const version = await this.invocationContext.artifactService.saveArtifact({
78
- appName: this.invocationContext.appName,
79
- userId: this.invocationContext.userId,
80
- sessionId: this.invocationContext.session.id,
81
75
  filename,
82
76
  artifact
83
77
  });
@@ -110,11 +104,7 @@ class Context extends ReadonlyContext {
110
104
  if (!this.invocationContext.artifactService) {
111
105
  throw new Error("Artifact service is not initialized.");
112
106
  }
113
- return this.invocationContext.artifactService.listArtifactKeys({
114
- appName: this.invocationContext.session.appName,
115
- userId: this.invocationContext.session.userId,
116
- sessionId: this.invocationContext.session.id
117
- });
107
+ return this.invocationContext.artifactService.listArtifactKeys();
118
108
  }
119
109
  /**
120
110
  * Searches the memory of the current user.
@@ -7,7 +7,11 @@ const require = topLevelCreateRequire(import.meta.url);
7
7
  */
8
8
  import { createUserContent } from "@google/genai";
9
9
  import { isEmpty } from "lodash-es";
10
- import { createEvent, getFunctionCalls } from "../events/event.js";
10
+ import {
11
+ createEvent,
12
+ getFunctionCalls,
13
+ getFunctionResponses
14
+ } from "../events/event.js";
11
15
  import { mergeEventActions } from "../events/event_actions.js";
12
16
  import { randomUUID } from "../utils/env_aware_utils.js";
13
17
  import { logger } from "../utils/logger.js";
@@ -39,18 +43,6 @@ function populateClientFunctionCallId(modelResponseEvent) {
39
43
  }
40
44
  }
41
45
  }
42
- function removeClientFunctionCallId(content) {
43
- if (content && content.parts) {
44
- for (const part of content.parts) {
45
- if (part.functionCall && part.functionCall.id && part.functionCall.id.startsWith(AF_FUNCTION_CALL_ID_PREFIX)) {
46
- part.functionCall.id = void 0;
47
- }
48
- if (part.functionResponse && part.functionResponse.id && part.functionResponse.id.startsWith(AF_FUNCTION_CALL_ID_PREFIX)) {
49
- part.functionResponse.id = void 0;
50
- }
51
- }
52
- }
53
- }
54
46
  function getLongRunningFunctionCalls(functionCalls, toolsDict) {
55
47
  const longRunningToolIds = /* @__PURE__ */ new Set();
56
48
  for (const functionCall of functionCalls) {
@@ -393,9 +385,39 @@ function mergeParallelFunctionResponseEvents(functionResponseEvents) {
393
385
  timestamp: baseEvent.timestamp
394
386
  });
395
387
  }
388
+ function findEventByFunctionCallId(events, functionCallId, endIndex = events.length) {
389
+ for (let i = endIndex - 1; i >= 0; i--) {
390
+ const event = events[i];
391
+ const functionCalls = getFunctionCalls(event);
392
+ for (const functionCall of functionCalls) {
393
+ if (functionCall.id === functionCallId) {
394
+ return event;
395
+ }
396
+ }
397
+ }
398
+ return void 0;
399
+ }
400
+ function findMatchingFunctionCall(events) {
401
+ if (!events.length) {
402
+ return void 0;
403
+ }
404
+ const lastEvent = events[events.length - 1];
405
+ const functionResponses = getFunctionResponses(lastEvent);
406
+ if (!functionResponses.length || !functionResponses[0].id) {
407
+ return void 0;
408
+ }
409
+ return findEventByFunctionCallId(
410
+ events,
411
+ functionResponses[0].id,
412
+ events.length - 1
413
+ );
414
+ }
396
415
  export {
416
+ AF_FUNCTION_CALL_ID_PREFIX,
397
417
  REQUEST_CONFIRMATION_FUNCTION_CALL_NAME,
398
418
  REQUEST_EUC_FUNCTION_CALL_NAME,
419
+ findEventByFunctionCallId,
420
+ findMatchingFunctionCall,
399
421
  functionsExportedForTestingOnly,
400
422
  generateAuthEvent,
401
423
  generateClientFunctionCallId,
@@ -404,6 +426,5 @@ export {
404
426
  handleFunctionCallList,
405
427
  handleFunctionCallsAsync,
406
428
  mergeParallelFunctionResponseEvents,
407
- populateClientFunctionCallId,
408
- removeClientFunctionCallId
429
+ populateClientFunctionCallId
409
430
  };
@@ -15,9 +15,6 @@ async function resolveKey(key, isOptional, rawMatch, readonlyContext) {
15
15
  throw new Error("Artifact service is not initialized.");
16
16
  }
17
17
  const artifact = await invocationContext.artifactService.loadArtifact({
18
- appName: invocationContext.session.appName,
19
- userId: invocationContext.session.userId,
20
- sessionId: invocationContext.session.id,
21
18
  filename: fileName
22
19
  });
23
20
  if (!artifact) {
@@ -26,19 +23,40 @@ async function resolveKey(key, isOptional, rawMatch, readonlyContext) {
26
23
  }
27
24
  throw new Error(`Artifact ${fileName} not found.`);
28
25
  }
29
- return String(artifact);
26
+ return formatValue(artifact, true);
30
27
  }
31
28
  if (!isValidStateName(key)) {
32
29
  return rawMatch;
33
30
  }
34
31
  if (key in invocationContext.session.state) {
35
- return String(invocationContext.session.state[key]);
32
+ return formatValue(invocationContext.session.state[key], false);
36
33
  }
37
34
  if (isOptional) {
38
35
  return "";
39
36
  }
40
37
  throw new Error(`Context variable not found: \`${key}\`.`);
41
38
  }
39
+ function formatValue(value, isArtifact = false) {
40
+ if (typeof value === "string") {
41
+ return value;
42
+ }
43
+ if (typeof value === "object" && value !== null) {
44
+ if (isArtifact && "text" in value && typeof value.text === "string") {
45
+ return value.text;
46
+ }
47
+ try {
48
+ const json = JSON.stringify(value);
49
+ if (json !== void 0) {
50
+ return json;
51
+ }
52
+ } catch (e) {
53
+ throw new Error(
54
+ `Failed to serialize value for instruction template: ${e instanceof Error ? e.message : String(e)}`
55
+ );
56
+ }
57
+ }
58
+ return String(value);
59
+ }
42
60
  async function injectSessionState(template, readonlyContext) {
43
61
  const pattern = /\{+[^{}]*}+/g;
44
62
  const matches = Array.from(template.matchAll(pattern));
@@ -30,11 +30,7 @@ class InvocationContext {
30
30
  * @param params The parameters for creating an invocation context.
31
31
  */
32
32
  constructor(params) {
33
- /**
34
- * A container to keep track of different kinds of costs incurred as a part of
35
- * this invocation.
36
- */
37
- this.invocationCostManager = new InvocationCostManager();
33
+ var _a;
38
34
  this.artifactService = params.artifactService;
39
35
  this.sessionService = params.sessionService;
40
36
  this.memoryService = params.memoryService;
@@ -49,6 +45,7 @@ class InvocationContext {
49
45
  this.activeStreamingTools = params.activeStreamingTools;
50
46
  this.pluginManager = params.pluginManager;
51
47
  this.abortSignal = params.abortSignal;
48
+ this.invocationCostManager = (_a = params.invocationCostManager) != null ? _a : new InvocationCostManager();
52
49
  }
53
50
  /**
54
51
  * The app name of the current session.
@@ -42,6 +42,7 @@ import { CONTENT_REQUEST_PROCESSOR } from "./processors/content_request_processo
42
42
  import { ContextCompactorRequestProcessor } from "./processors/context_compactor_request_processor.js";
43
43
  import { IDENTITY_LLM_REQUEST_PROCESSOR } from "./processors/identity_llm_request_processor.js";
44
44
  import { INSTRUCTIONS_LLM_REQUEST_PROCESSOR } from "./processors/instructions_llm_request_processor.js";
45
+ import { INTERACTIONS_REQUEST_PROCESSOR } from "./processors/interactions_request_processor.js";
45
46
  import { REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR } from "./processors/request_confirmation_llm_request_processor.js";
46
47
  import { TOOL_FILTER_REQUEST_PROCESSOR } from "./processors/tool_filter_request_processor.js";
47
48
  import { ReadonlyContext } from "./readonly_context.js";
@@ -86,6 +87,7 @@ class LlmAgent extends (_b = BaseAgent, _a = LLM_AGENT_SIGNATURE_SYMBOL, _b) {
86
87
  INSTRUCTIONS_LLM_REQUEST_PROCESSOR,
87
88
  REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR,
88
89
  CONTENT_REQUEST_PROCESSOR,
90
+ INTERACTIONS_REQUEST_PROCESSOR,
89
91
  CODE_EXECUTION_REQUEST_PROCESSOR,
90
92
  TOOL_FILTER_REQUEST_PROCESSOR
91
93
  ];
@@ -468,7 +470,7 @@ class LlmAgent extends (_b = BaseAgent, _a = LLM_AGENT_SIGNATURE_SYMBOL, _b) {
468
470
  span.end();
469
471
  }
470
472
  async *postprocess(invocationContext, llmRequest, llmResponse, modelResponseEvent) {
471
- var _a2, _b2, _c, _d, _e;
473
+ var _a2, _b2, _c, _d, _e, _f;
472
474
  for (const processor of this.responseProcessors) {
473
475
  for await (const event of processor.runAsync(
474
476
  invocationContext,
@@ -480,7 +482,7 @@ class LlmAgent extends (_b = BaseAgent, _a = LLM_AGENT_SIGNATURE_SYMBOL, _b) {
480
482
  yield event;
481
483
  }
482
484
  }
483
- if (!llmResponse.content && !llmResponse.errorCode && !llmResponse.interrupted) {
485
+ if ((!llmResponse.content || ((_b2 = llmResponse.content.parts) == null ? void 0 : _b2.length) === 0) && !llmResponse.errorCode && !llmResponse.interrupted) {
484
486
  return;
485
487
  }
486
488
  const mergedEvent = createEvent({
@@ -504,10 +506,10 @@ class LlmAgent extends (_b = BaseAgent, _a = LLM_AGENT_SIGNATURE_SYMBOL, _b) {
504
506
  }
505
507
  }
506
508
  yield mergedEvent;
507
- if (!((_b2 = getFunctionCalls(mergedEvent)) == null ? void 0 : _b2.length)) {
509
+ if (!((_c = getFunctionCalls(mergedEvent)) == null ? void 0 : _c.length)) {
508
510
  return;
509
511
  }
510
- if ((_c = invocationContext.runConfig) == null ? void 0 : _c.pauseOnToolCalls) {
512
+ if ((_d = invocationContext.runConfig) == null ? void 0 : _d.pauseOnToolCalls) {
511
513
  invocationContext.endInvocation = true;
512
514
  return;
513
515
  }
@@ -518,7 +520,7 @@ class LlmAgent extends (_b = BaseAgent, _a = LLM_AGENT_SIGNATURE_SYMBOL, _b) {
518
520
  beforeToolCallbacks: this.canonicalBeforeToolCallbacks,
519
521
  afterToolCallbacks: this.canonicalAfterToolCallbacks
520
522
  });
521
- if (!functionResponseEvent || ((_d = invocationContext.abortSignal) == null ? void 0 : _d.aborted)) {
523
+ if (!functionResponseEvent || ((_e = invocationContext.abortSignal) == null ? void 0 : _e.aborted)) {
522
524
  return;
523
525
  }
524
526
  const authEvent = generateAuthEvent(
@@ -543,7 +545,7 @@ class LlmAgent extends (_b = BaseAgent, _a = LLM_AGENT_SIGNATURE_SYMBOL, _b) {
543
545
  if (nextAgentName) {
544
546
  const nextAgent = this.getAgentByName(invocationContext, nextAgentName);
545
547
  for await (const event of nextAgent.runAsync(invocationContext)) {
546
- if ((_e = invocationContext.abortSignal) == null ? void 0 : _e.aborted) {
548
+ if ((_f = invocationContext.abortSignal) == null ? void 0 : _f.aborted) {
547
549
  return;
548
550
  }
549
551
  yield event;
@@ -317,9 +317,6 @@ async function postProcessCodeExecutionResult(invocationContext, codeExecutorCon
317
317
  }
318
318
  for (const outputFile of codeExecutionResult.outputFiles) {
319
319
  const version = await invocationContext.artifactService.saveArtifact({
320
- appName: invocationContext.appName || "",
321
- userId: invocationContext.userId || "",
322
- sessionId: invocationContext.session.id,
323
320
  filename: outputFile.name,
324
321
  artifact: {
325
322
  inlineData: { data: outputFile.content, mimeType: outputFile.mimeType }
@@ -16,10 +16,21 @@ import {
16
16
  getFunctionResponses
17
17
  } from "../../events/event.js";
18
18
  import {
19
- removeClientFunctionCallId,
19
+ AF_FUNCTION_CALL_ID_PREFIX,
20
20
  REQUEST_CONFIRMATION_FUNCTION_CALL_NAME,
21
21
  REQUEST_EUC_FUNCTION_CALL_NAME
22
22
  } from "../functions.js";
23
+ function removeClientFunctionCallId(content) {
24
+ var _a, _b, _c, _d, _e;
25
+ for (const part of (_a = content == null ? void 0 : content.parts) != null ? _a : []) {
26
+ if ((_c = (_b = part.functionCall) == null ? void 0 : _b.id) == null ? void 0 : _c.startsWith(AF_FUNCTION_CALL_ID_PREFIX)) {
27
+ part.functionCall.id = void 0;
28
+ }
29
+ if ((_e = (_d = part.functionResponse) == null ? void 0 : _d.id) == null ? void 0 : _e.startsWith(AF_FUNCTION_CALL_ID_PREFIX)) {
30
+ part.functionResponse.id = void 0;
31
+ }
32
+ }
33
+ }
23
34
  function getContents(events, agentName, currentBranch) {
24
35
  var _a, _b, _c;
25
36
  const filteredEvents = [];
@@ -327,5 +338,6 @@ ${event.compactedContent}`
327
338
  export {
328
339
  getContents,
329
340
  getCurrentTurnContents,
330
- mergeFunctionResponseEvents
341
+ mergeFunctionResponseEvents,
342
+ removeClientFunctionCallId
331
343
  };
@@ -23,20 +23,22 @@ class ContextCompactorRequestProcessor {
23
23
  * @param _llmRequest - Unused; present to satisfy the {@link BaseLlmRequestProcessor} interface.
24
24
  */
25
25
  async *runAsync(invocationContext, _llmRequest) {
26
+ var _a;
26
27
  for (const compactor of this.compactors) {
27
28
  const shouldCompact = await Promise.resolve(
28
29
  compactor.shouldCompact(invocationContext)
29
30
  );
30
31
  if (shouldCompact) {
32
+ const trigger = (_a = compactor.trigger) != null ? _a : ContextCompactionTrigger.Auto;
31
33
  await invocationContext.pluginManager.runBeforeContextCompaction({
32
34
  invocationContext,
33
- trigger: ContextCompactionTrigger.Auto
35
+ trigger
34
36
  });
35
37
  const oldEvents = new Set(invocationContext.session.events);
36
38
  await Promise.resolve(compactor.compact(invocationContext));
37
39
  await invocationContext.pluginManager.runAfterContextCompaction({
38
40
  invocationContext,
39
- trigger: ContextCompactionTrigger.Auto
41
+ trigger
40
42
  });
41
43
  const newEvents = invocationContext.session.events.filter(
42
44
  (e) => !oldEvents.has(e)
@@ -0,0 +1,34 @@
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 { isGemini } from "../../models/google_llm.js";
9
+ import { isLlmAgent } from "../llm_agent.js";
10
+ class InteractionsRequestProcessor {
11
+ // eslint-disable-next-line require-yield
12
+ async *runAsync(invocationContext, llmRequest) {
13
+ const agent = invocationContext.agent;
14
+ if (!agent || !isLlmAgent(agent)) {
15
+ return;
16
+ }
17
+ const model = agent.canonicalModel;
18
+ if (isGemini(model) && model.useInteractionsApi) {
19
+ const events = invocationContext.session.events;
20
+ for (let i = events.length - 1; i >= 0; i--) {
21
+ const event = events[i];
22
+ if (event.branch === invocationContext.branch && event.author === agent.name && event.interactionId) {
23
+ llmRequest.previousInteractionId = event.interactionId;
24
+ break;
25
+ }
26
+ }
27
+ }
28
+ }
29
+ }
30
+ const INTERACTIONS_REQUEST_PROCESSOR = new InteractionsRequestProcessor();
31
+ export {
32
+ INTERACTIONS_REQUEST_PROCESSOR,
33
+ InteractionsRequestProcessor
34
+ };
@@ -0,0 +1,49 @@
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
+ var _a;
9
+ import { isBaseAgent } from "../agents/base_agent.js";
10
+ const VALID_APP_NAME_RE = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
11
+ function validateAppName(name) {
12
+ if (!VALID_APP_NAME_RE.test(name)) {
13
+ throw new Error(
14
+ `Invalid app name '${name}': must start with a letter and can only consist of letters, digits, underscores, and hyphens.`
15
+ );
16
+ }
17
+ if (name === "user") {
18
+ throw new Error("App name cannot be 'user'; reserved for end-user input.");
19
+ }
20
+ }
21
+ const APP_SIGNATURE_SYMBOL = Symbol.for("google.adk.app");
22
+ function isApp(obj) {
23
+ return typeof obj === "object" && obj !== null && APP_SIGNATURE_SYMBOL in obj && obj[APP_SIGNATURE_SYMBOL] === true;
24
+ }
25
+ _a = APP_SIGNATURE_SYMBOL;
26
+ class App {
27
+ constructor(options) {
28
+ this[_a] = true;
29
+ var _a2, _b, _c, _d;
30
+ validateAppName(options.name);
31
+ if (options.rootAgent === void 0 || options.rootAgent === null) {
32
+ throw new Error("rootAgent must be provided.");
33
+ }
34
+ if (!isBaseAgent(options.rootAgent)) {
35
+ throw new TypeError(
36
+ `rootAgent must be a BaseAgent instance, got ${(_c = (_b = (_a2 = options.rootAgent) == null ? void 0 : _a2.constructor) == null ? void 0 : _b.name) != null ? _c : typeof options.rootAgent}`
37
+ );
38
+ }
39
+ this.name = options.name;
40
+ this.rootAgent = options.rootAgent;
41
+ this.plugins = (_d = options.plugins) != null ? _d : [];
42
+ this.resumabilityConfig = options.resumabilityConfig;
43
+ }
44
+ }
45
+ export {
46
+ App,
47
+ isApp,
48
+ validateAppName
49
+ };
@@ -0,0 +1,16 @@
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 createResumabilityConfig(params = {}) {
9
+ return {
10
+ isResumable: false,
11
+ ...params
12
+ };
13
+ }
14
+ export {
15
+ createResumabilityConfig
16
+ };
@@ -26,7 +26,7 @@ class FileArtifactService {
26
26
  artifact,
27
27
  customMetadata
28
28
  }) {
29
- if (!artifact.inlineData && !artifact.text) {
29
+ if (!artifact.inlineData && !artifact.text && !artifact.fileData) {
30
30
  throw new Error("Artifact must have either inlineData or text content.");
31
31
  }
32
32
  const artifactDir = getArtifactDir(
@@ -44,12 +44,19 @@ class FileArtifactService {
44
44
  const storedFilename = path.basename(artifactDir);
45
45
  const contentPath = path.join(versionDir, storedFilename);
46
46
  let mimeType;
47
+ let fileUri;
47
48
  if (artifact.inlineData) {
48
49
  const data = artifact.inlineData.data || "";
49
50
  await fs.writeFile(contentPath, Buffer.from(data, "base64"));
50
51
  mimeType = artifact.inlineData.mimeType || "application/octet-stream";
51
52
  } else if (artifact.text !== void 0) {
52
53
  await fs.writeFile(contentPath, artifact.text, "utf-8");
54
+ } else {
55
+ fileUri = artifact.fileData.fileUri;
56
+ if (!fileUri) {
57
+ throw new Error("Artifact fileData must have a fileUri.");
58
+ }
59
+ mimeType = artifact.fileData.mimeType;
53
60
  }
54
61
  const canonicalUri = await getCanonicalUri(
55
62
  this.rootDir,
@@ -61,6 +68,7 @@ class FileArtifactService {
61
68
  const metadata = {
62
69
  fileName: filename,
63
70
  mimeType,
71
+ fileUri,
64
72
  version: nextVersion,
65
73
  canonicalUri,
66
74
  customMetadata
@@ -112,6 +120,11 @@ class FileArtifactService {
112
120
  );
113
121
  const metadataPath = path.join(versionDir, "metadata.json");
114
122
  const metadata = await readMetadata(metadataPath);
123
+ if (metadata.fileUri) {
124
+ return {
125
+ fileData: { fileUri: metadata.fileUri, mimeType: metadata.mimeType }
126
+ };
127
+ }
115
128
  const storedFilename = path.basename(artifactDir);
116
129
  let contentPath = path.join(versionDir, storedFilename);
117
130
  if (metadata.canonicalUri) {