@google/adk 0.5.0 → 0.6.1

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 (142) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/a2a/a2a_event.js +53 -26
  3. package/dist/cjs/a2a/a2a_remote_agent.js +179 -0
  4. package/dist/cjs/a2a/a2a_remote_agent_run_processor.js +205 -0
  5. package/dist/cjs/a2a/a2a_remote_agent_utils.js +165 -0
  6. package/dist/cjs/a2a/agent_card.js +380 -0
  7. package/dist/cjs/a2a/agent_executor.js +221 -0
  8. package/dist/cjs/a2a/agent_to_a2a.js +115 -0
  9. package/dist/cjs/a2a/event_processor_utils.js +180 -0
  10. package/dist/cjs/a2a/executor_context.js +1 -1
  11. package/dist/cjs/a2a/metadata_converter_utils.js +1 -0
  12. package/dist/cjs/a2a/part_converter_utils.js +24 -13
  13. package/dist/cjs/agents/llm_agent.js +17 -0
  14. package/dist/cjs/agents/{content_processor_utils.js → processors/content_processor_utils.js} +21 -2
  15. package/dist/cjs/agents/processors/content_request_processor.js +24 -3
  16. package/dist/cjs/agents/processors/context_compactor_request_processor.js +61 -0
  17. package/dist/cjs/agents/processors/instructions_llm_request_processor.js +1 -1
  18. package/dist/cjs/artifacts/file_artifact_service.js +35 -4
  19. package/dist/cjs/common.js +37 -0
  20. package/dist/cjs/context/base_context_compactor.js +27 -0
  21. package/dist/cjs/context/summarizers/base_summarizer.js +27 -0
  22. package/dist/cjs/context/summarizers/llm_summarizer.js +93 -0
  23. package/dist/cjs/context/token_based_context_compactor.js +135 -0
  24. package/dist/cjs/context/truncating_context_compactor.js +58 -0
  25. package/dist/cjs/events/compacted_event.js +53 -0
  26. package/dist/cjs/index.js +38 -14
  27. package/dist/cjs/index.js.map +4 -4
  28. package/dist/cjs/memory/in_memory_memory_service.js +1 -1
  29. package/dist/cjs/runner/runner.js +19 -10
  30. package/dist/cjs/sessions/db/operations.js +4 -14
  31. package/dist/cjs/sessions/state.js +2 -2
  32. package/dist/cjs/tools/agent_tool.js +6 -5
  33. package/dist/cjs/tools/load_artifacts_tool.js +188 -0
  34. package/dist/cjs/tools/load_memory_tool.js +107 -0
  35. package/dist/cjs/tools/preload_memory_tool.js +109 -0
  36. package/dist/cjs/utils/gemini_schema_util.js +54 -12
  37. package/dist/cjs/utils/logger.js +1 -0
  38. package/dist/cjs/version.js +1 -1
  39. package/dist/esm/a2a/a2a_event.js +52 -26
  40. package/dist/esm/a2a/a2a_remote_agent.js +153 -0
  41. package/dist/esm/a2a/a2a_remote_agent_run_processor.js +182 -0
  42. package/dist/esm/a2a/a2a_remote_agent_utils.js +131 -0
  43. package/dist/esm/a2a/agent_card.js +340 -0
  44. package/dist/esm/a2a/agent_executor.js +202 -0
  45. package/dist/esm/a2a/agent_to_a2a.js +80 -0
  46. package/dist/esm/a2a/event_processor_utils.js +159 -0
  47. package/dist/esm/a2a/executor_context.js +1 -1
  48. package/dist/esm/a2a/metadata_converter_utils.js +1 -0
  49. package/dist/esm/a2a/part_converter_utils.js +24 -13
  50. package/dist/esm/agents/llm_agent.js +17 -0
  51. package/dist/esm/agents/{content_processor_utils.js → processors/content_processor_utils.js} +23 -2
  52. package/dist/esm/agents/processors/content_request_processor.js +25 -4
  53. package/dist/esm/agents/processors/context_compactor_request_processor.js +31 -0
  54. package/dist/esm/agents/processors/instructions_llm_request_processor.js +1 -1
  55. package/dist/esm/artifacts/file_artifact_service.js +30 -3
  56. package/dist/esm/common.js +33 -1
  57. package/dist/esm/context/base_context_compactor.js +5 -0
  58. package/dist/esm/context/summarizers/base_summarizer.js +5 -0
  59. package/dist/esm/context/summarizers/llm_summarizer.js +65 -0
  60. package/dist/esm/context/token_based_context_compactor.js +105 -0
  61. package/dist/esm/context/truncating_context_compactor.js +28 -0
  62. package/dist/esm/events/compacted_event.js +22 -0
  63. package/dist/esm/index.js +38 -14
  64. package/dist/esm/index.js.map +4 -4
  65. package/dist/esm/memory/in_memory_memory_service.js +1 -1
  66. package/dist/esm/runner/runner.js +17 -9
  67. package/dist/esm/sessions/db/operations.js +4 -14
  68. package/dist/esm/sessions/state.js +2 -2
  69. package/dist/esm/tools/agent_tool.js +6 -5
  70. package/dist/esm/tools/load_artifacts_tool.js +159 -0
  71. package/dist/esm/tools/load_memory_tool.js +78 -0
  72. package/dist/esm/tools/preload_memory_tool.js +80 -0
  73. package/dist/esm/utils/gemini_schema_util.js +54 -12
  74. package/dist/esm/utils/logger.js +1 -0
  75. package/dist/esm/version.js +1 -1
  76. package/dist/types/a2a/a2a_event.d.ts +23 -6
  77. package/dist/types/a2a/a2a_remote_agent.d.ts +67 -0
  78. package/dist/types/a2a/a2a_remote_agent_run_processor.d.ts +31 -0
  79. package/dist/types/a2a/a2a_remote_agent_utils.d.ts +38 -0
  80. package/dist/types/a2a/agent_card.d.ts +23 -0
  81. package/dist/types/a2a/agent_executor.d.ts +52 -0
  82. package/dist/types/a2a/agent_to_a2a.d.ts +45 -0
  83. package/dist/types/a2a/event_processor_utils.d.ts +24 -0
  84. package/dist/types/a2a/executor_context.d.ts +1 -1
  85. package/dist/types/a2a/metadata_converter_utils.d.ts +2 -1
  86. package/dist/types/agents/llm_agent.d.ts +6 -0
  87. package/dist/types/agents/loop_agent.d.ts +1 -1
  88. package/dist/types/agents/{content_processor_utils.d.ts → processors/content_processor_utils.d.ts} +1 -1
  89. package/dist/types/agents/processors/context_compactor_request_processor.d.ts +22 -0
  90. package/dist/types/artifacts/file_artifact_service.d.ts +4 -0
  91. package/dist/types/common.d.ts +16 -1
  92. package/dist/types/context/base_context_compactor.d.ts +24 -0
  93. package/dist/types/context/summarizers/base_summarizer.d.ts +19 -0
  94. package/dist/types/context/summarizers/llm_summarizer.d.ts +23 -0
  95. package/dist/types/context/token_based_context_compactor.d.ts +33 -0
  96. package/dist/types/context/truncating_context_compactor.d.ts +24 -0
  97. package/dist/types/events/compacted_event.d.ts +33 -0
  98. package/dist/types/index.d.ts +8 -0
  99. package/dist/types/runner/runner.d.ts +13 -0
  100. package/dist/types/sessions/db/operations.d.ts +2 -3
  101. package/dist/types/tools/load_artifacts_tool.d.ts +21 -0
  102. package/dist/types/tools/load_memory_tool.d.ts +22 -0
  103. package/dist/types/tools/preload_memory_tool.d.ts +23 -0
  104. package/dist/types/version.d.ts +1 -1
  105. package/dist/web/a2a/a2a_event.js +52 -26
  106. package/dist/web/a2a/a2a_remote_agent.js +184 -0
  107. package/dist/web/a2a/a2a_remote_agent_run_processor.js +182 -0
  108. package/dist/web/a2a/a2a_remote_agent_utils.js +131 -0
  109. package/dist/web/a2a/agent_card.js +340 -0
  110. package/dist/web/a2a/agent_executor.js +216 -0
  111. package/dist/web/a2a/agent_to_a2a.js +80 -0
  112. package/dist/web/a2a/event_processor_utils.js +168 -0
  113. package/dist/web/a2a/executor_context.js +1 -1
  114. package/dist/web/a2a/metadata_converter_utils.js +1 -0
  115. package/dist/web/a2a/part_converter_utils.js +24 -13
  116. package/dist/web/agents/llm_agent.js +17 -0
  117. package/dist/web/agents/{content_processor_utils.js → processors/content_processor_utils.js} +22 -2
  118. package/dist/web/agents/processors/content_request_processor.js +25 -4
  119. package/dist/web/agents/processors/context_compactor_request_processor.js +49 -0
  120. package/dist/web/agents/processors/instructions_llm_request_processor.js +1 -1
  121. package/dist/web/artifacts/file_artifact_service.js +30 -3
  122. package/dist/web/common.js +33 -1
  123. package/dist/web/context/base_context_compactor.js +5 -0
  124. package/dist/web/context/summarizers/base_summarizer.js +5 -0
  125. package/dist/web/context/summarizers/llm_summarizer.js +74 -0
  126. package/dist/web/context/token_based_context_compactor.js +105 -0
  127. package/dist/web/context/truncating_context_compactor.js +28 -0
  128. package/dist/web/events/compacted_event.js +40 -0
  129. package/dist/web/index.js +1 -1
  130. package/dist/web/index.js.map +4 -4
  131. package/dist/web/memory/in_memory_memory_service.js +1 -1
  132. package/dist/web/runner/runner.js +17 -9
  133. package/dist/web/sessions/db/operations.js +4 -14
  134. package/dist/web/sessions/state.js +2 -2
  135. package/dist/web/tools/agent_tool.js +6 -5
  136. package/dist/web/tools/load_artifacts_tool.js +150 -0
  137. package/dist/web/tools/load_memory_tool.js +77 -0
  138. package/dist/web/tools/preload_memory_tool.js +75 -0
  139. package/dist/web/utils/gemini_schema_util.js +85 -12
  140. package/dist/web/utils/logger.js +1 -0
  141. package/dist/web/version.js +1 -1
  142. package/package.json +7 -5
@@ -0,0 +1,159 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { createEventActions } from "../events/event_actions.js";
7
+ import {
8
+ createInputMissingErrorEvent,
9
+ createTaskCompletedEvent,
10
+ createTaskFailedEvent,
11
+ createTaskInputRequiredEvent,
12
+ isInputRequiredTaskStatusUpdateEvent
13
+ } from "./a2a_event.js";
14
+ import {
15
+ getA2AEventMetadata,
16
+ getA2AEventMetadataFromActions,
17
+ getA2ASessionMetadata
18
+ } from "./metadata_converter_utils.js";
19
+ import { toA2AParts, toGenAIParts } from "./part_converter_utils.js";
20
+ function getFinalTaskStatusUpdate(adkEvents, context) {
21
+ var _a, _b;
22
+ const finalEventActions = createEventActions();
23
+ for (const adkEvent of adkEvents) {
24
+ if (adkEvent.errorCode || adkEvent.errorMessage) {
25
+ return createTaskFailedEvent({
26
+ taskId: context.requestContext.taskId,
27
+ contextId: context.requestContext.contextId,
28
+ error: new Error(adkEvent.errorMessage || adkEvent.errorCode),
29
+ metadata: {
30
+ ...getA2AEventMetadata(adkEvent, context),
31
+ ...getA2AEventMetadataFromActions(finalEventActions)
32
+ }
33
+ });
34
+ }
35
+ finalEventActions.escalate = finalEventActions.escalate || ((_a = adkEvent.actions) == null ? void 0 : _a.escalate);
36
+ if ((_b = adkEvent.actions) == null ? void 0 : _b.transferToAgent) {
37
+ finalEventActions.transferToAgent = adkEvent.actions.transferToAgent;
38
+ }
39
+ }
40
+ const inputRequiredEvent = scanForInputRequiredEvents(adkEvents, context);
41
+ if (inputRequiredEvent) {
42
+ return {
43
+ ...inputRequiredEvent,
44
+ metadata: {
45
+ ...inputRequiredEvent.metadata,
46
+ ...getA2AEventMetadataFromActions(finalEventActions)
47
+ }
48
+ };
49
+ }
50
+ return createTaskCompletedEvent({
51
+ taskId: context.requestContext.taskId,
52
+ contextId: context.requestContext.contextId,
53
+ metadata: {
54
+ ...getA2ASessionMetadata(context),
55
+ ...getA2AEventMetadataFromActions(finalEventActions)
56
+ }
57
+ });
58
+ }
59
+ function scanForInputRequiredEvents(adkEvents, context) {
60
+ var _a, _b;
61
+ const inputRequiredParts = [];
62
+ const inputRequiredFunctionCallIds = /* @__PURE__ */ new Set();
63
+ for (const adkEvent of adkEvents) {
64
+ if (!((_b = (_a = adkEvent.content) == null ? void 0 : _a.parts) == null ? void 0 : _b.length)) {
65
+ continue;
66
+ }
67
+ for (const genAIPart of adkEvent.content.parts) {
68
+ const longRunningFunctionCallId = getLongRunnningFunctionCallId(
69
+ genAIPart,
70
+ adkEvent.longRunningToolIds,
71
+ inputRequiredParts
72
+ );
73
+ if (!longRunningFunctionCallId) {
74
+ continue;
75
+ }
76
+ const isAlreadyAdded = inputRequiredFunctionCallIds.has(
77
+ longRunningFunctionCallId
78
+ );
79
+ if (isAlreadyAdded) {
80
+ continue;
81
+ }
82
+ inputRequiredParts.push(genAIPart);
83
+ inputRequiredFunctionCallIds.add(longRunningFunctionCallId);
84
+ }
85
+ }
86
+ if (inputRequiredParts.length > 0) {
87
+ return createTaskInputRequiredEvent({
88
+ taskId: context.requestContext.taskId,
89
+ contextId: context.requestContext.contextId,
90
+ parts: toA2AParts(inputRequiredParts, [...inputRequiredFunctionCallIds]),
91
+ metadata: getA2ASessionMetadata(context)
92
+ });
93
+ }
94
+ return void 0;
95
+ }
96
+ function getLongRunnningFunctionCallId(genAIPart, longRunningToolIds = [], inputRequiredParts = []) {
97
+ var _a, _b, _c;
98
+ const functionCallId = (_a = genAIPart.functionCall) == null ? void 0 : _a.id;
99
+ const functionResponseId = (_b = genAIPart.functionResponse) == null ? void 0 : _b.id;
100
+ if (!functionCallId && !functionResponseId) {
101
+ return;
102
+ }
103
+ if (functionCallId && longRunningToolIds.includes(functionCallId)) {
104
+ return functionCallId;
105
+ }
106
+ if (functionResponseId && longRunningToolIds.includes(functionResponseId)) {
107
+ return functionResponseId;
108
+ }
109
+ for (const part of inputRequiredParts) {
110
+ if (((_c = part.functionCall) == null ? void 0 : _c.id) === functionResponseId) {
111
+ return functionResponseId;
112
+ }
113
+ }
114
+ return;
115
+ }
116
+ function getTaskInputRequiredEvent(task, genAIContent) {
117
+ var _a;
118
+ if (!task || !isInputRequiredTaskStatusUpdateEvent(task) || !task.status.message) {
119
+ return void 0;
120
+ }
121
+ const statusMsg = task.status.message;
122
+ const taskParts = toGenAIParts(statusMsg.parts);
123
+ for (const taskPart of taskParts) {
124
+ const functionCallId = (_a = taskPart.functionCall) == null ? void 0 : _a.id;
125
+ if (!functionCallId) {
126
+ continue;
127
+ }
128
+ const hasMatchingResponse = ((genAIContent == null ? void 0 : genAIContent.parts) || []).some(
129
+ (p) => {
130
+ var _a2;
131
+ return ((_a2 = p.functionResponse) == null ? void 0 : _a2.id) === functionCallId;
132
+ }
133
+ );
134
+ if (!hasMatchingResponse) {
135
+ return createInputMissingErrorEvent({
136
+ taskId: task.id,
137
+ contextId: task.contextId,
138
+ parts: [
139
+ ...statusMsg.parts.filter((p) => {
140
+ var _a2;
141
+ return !((_a2 = p.metadata) == null ? void 0 : _a2.validation_error);
142
+ }),
143
+ {
144
+ kind: "text",
145
+ text: `No input provided for function call id ${functionCallId}`,
146
+ metadata: {
147
+ validation_error: true
148
+ }
149
+ }
150
+ ]
151
+ });
152
+ }
153
+ }
154
+ return void 0;
155
+ }
156
+ export {
157
+ getFinalTaskStatusUpdate,
158
+ getTaskInputRequiredEvent
159
+ };
@@ -11,7 +11,7 @@ function createExecutorContext({
11
11
  return {
12
12
  userId: session.userId,
13
13
  sessionId: session.id,
14
- agentName: session.appName,
14
+ appName: session.appName,
15
15
  readonlyState: session.state,
16
16
  events: session.events,
17
17
  userContent,
@@ -25,6 +25,7 @@ var A2AMetadataKeys = ((A2AMetadataKeys2) => {
25
25
  A2AMetadataKeys2["GROUNDING_METADATA"] = `${ADK_METADATA_KEY_PREFIX}grounding_metadata`;
26
26
  A2AMetadataKeys2["USAGE_METADATA"] = `${ADK_METADATA_KEY_PREFIX}usage_metadata`;
27
27
  A2AMetadataKeys2["CUSTOM_METADATA"] = `${ADK_METADATA_KEY_PREFIX}custom_metadata`;
28
+ A2AMetadataKeys2["VIDEO_METADATA"] = `${ADK_METADATA_KEY_PREFIX}video_metadata`;
28
29
  return A2AMetadataKeys2;
29
30
  })(A2AMetadataKeys || {});
30
31
  var AdkMetadataKeys = ((AdkMetadataKeys2) => {
@@ -37,6 +37,10 @@ function toA2ATextPart(part) {
37
37
  return a2aPart;
38
38
  }
39
39
  function toA2AFilePart(part) {
40
+ const metadata = {};
41
+ if (part.videoMetadata) {
42
+ metadata[A2AMetadataKeys.VIDEO_METADATA] = part.videoMetadata;
43
+ }
40
44
  if (part.fileData) {
41
45
  return {
42
46
  kind: "file",
@@ -44,7 +48,7 @@ function toA2AFilePart(part) {
44
48
  uri: part.fileData.fileUri || "",
45
49
  mimeType: part.fileData.mimeType
46
50
  },
47
- metadata: {}
51
+ metadata
48
52
  };
49
53
  }
50
54
  if (part.inlineData) {
@@ -54,7 +58,7 @@ function toA2AFilePart(part) {
54
58
  bytes: part.inlineData.data || "",
55
59
  mimeType: part.inlineData.mimeType
56
60
  },
57
- metadata: {}
61
+ metadata
58
62
  };
59
63
  }
60
64
  throw new Error(`Not a file part: ${JSON.stringify(part)}`);
@@ -75,7 +79,11 @@ function toA2ADataPart(part, longRunningToolIDs = []) {
75
79
  dataPartType = "code_execution_result" /* CODE_EXEC_RESULT */;
76
80
  data = part.codeExecutionResult;
77
81
  } else {
78
- throw new Error(`Unknown part type: ${JSON.stringify(part)}`);
82
+ return {
83
+ kind: "data",
84
+ data: {},
85
+ metadata: {}
86
+ };
79
87
  }
80
88
  const metadata = {
81
89
  [A2AMetadataKeys.DATA_PART_TYPE]: dataPartType
@@ -119,21 +127,24 @@ function toGenAIPartText(a2aPart) {
119
127
  };
120
128
  }
121
129
  function toGenAIPartFile(a2aPart) {
130
+ var _a;
131
+ const part = {};
132
+ if ((_a = a2aPart.metadata) == null ? void 0 : _a[A2AMetadataKeys.VIDEO_METADATA]) {
133
+ part.videoMetadata = a2aPart.metadata[A2AMetadataKeys.VIDEO_METADATA];
134
+ }
122
135
  if ("bytes" in a2aPart.file) {
123
- return {
124
- inlineData: {
125
- data: a2aPart.file.bytes,
126
- mimeType: a2aPart.file.mimeType || ""
127
- }
136
+ part.inlineData = {
137
+ data: a2aPart.file.bytes,
138
+ mimeType: a2aPart.file.mimeType || ""
128
139
  };
140
+ return part;
129
141
  }
130
142
  if ("uri" in a2aPart.file) {
131
- return {
132
- fileData: {
133
- fileUri: a2aPart.file.uri,
134
- mimeType: a2aPart.file.mimeType || ""
135
- }
143
+ part.fileData = {
144
+ fileUri: a2aPart.file.uri,
145
+ mimeType: a2aPart.file.mimeType || ""
136
146
  };
147
+ return part;
137
148
  }
138
149
  throw new Error(`Not a file part: ${JSON.stringify(a2aPart)}`);
139
150
  }
@@ -34,6 +34,7 @@ import { AGENT_TRANSFER_LLM_REQUEST_PROCESSOR } from "./processors/agent_transfe
34
34
  import { BASIC_LLM_REQUEST_PROCESSOR } from "./processors/basic_llm_request_processor.js";
35
35
  import { CODE_EXECUTION_REQUEST_PROCESSOR } from "./processors/code_execution_request_processor.js";
36
36
  import { CONTENT_REQUEST_PROCESSOR } from "./processors/content_request_processor.js";
37
+ import { ContextCompactorRequestProcessor } from "./processors/context_compactor_request_processor.js";
37
38
  import { IDENTITY_LLM_REQUEST_PROCESSOR } from "./processors/identity_llm_request_processor.js";
38
39
  import { INSTRUCTIONS_LLM_REQUEST_PROCESSOR } from "./processors/instructions_llm_request_processor.js";
39
40
  import { REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR } from "./processors/request_confirmation_llm_request_processor.js";
@@ -80,6 +81,22 @@ class LlmAgent extends (_b = BaseAgent, _a = LLM_AGENT_SIGNATURE_SYMBOL, _b) {
80
81
  CONTENT_REQUEST_PROCESSOR,
81
82
  CODE_EXECUTION_REQUEST_PROCESSOR
82
83
  ];
84
+ if (!config.requestProcessors && config.contextCompactors && config.contextCompactors.length > 0) {
85
+ const contentIndex = this.requestProcessors.indexOf(
86
+ CONTENT_REQUEST_PROCESSOR
87
+ );
88
+ if (contentIndex !== -1) {
89
+ this.requestProcessors.splice(
90
+ contentIndex,
91
+ 0,
92
+ new ContextCompactorRequestProcessor(config.contextCompactors)
93
+ );
94
+ } else {
95
+ this.requestProcessors.push(
96
+ new ContextCompactorRequestProcessor(config.contextCompactors)
97
+ );
98
+ }
99
+ }
83
100
  this.responseProcessors = (_h = config.responseProcessors) != null ? _h : [];
84
101
  const agentTransferDisabled = this.disallowTransferToParent && this.disallowTransferToPeers && !((_i = this.subAgents) == null ? void 0 : _i.length);
85
102
  if (!agentTransferDisabled) {
@@ -3,21 +3,29 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
+ import { createUserContent } from "@google/genai";
6
7
  import { cloneDeep } from "lodash-es";
8
+ import {
9
+ isCompactedEvent
10
+ } from "../../events/compacted_event.js";
7
11
  import {
8
12
  createEvent,
9
13
  getFunctionCalls,
10
14
  getFunctionResponses
11
- } from "../events/event.js";
15
+ } from "../../events/event.js";
12
16
  import {
13
17
  removeClientFunctionCallId,
14
18
  REQUEST_CONFIRMATION_FUNCTION_CALL_NAME,
15
19
  REQUEST_EUC_FUNCTION_CALL_NAME
16
- } from "./functions.js";
20
+ } from "../functions.js";
17
21
  function getContents(events, agentName, currentBranch) {
18
22
  var _a, _b, _c;
19
23
  const filteredEvents = [];
20
24
  for (const event of events) {
25
+ if (isCompactedEvent(event)) {
26
+ filteredEvents.push(convertCompactedEvent(event));
27
+ continue;
28
+ }
21
29
  if (!((_a = event.content) == null ? void 0 : _a.role) || ((_c = (_b = event.content.parts) == null ? void 0 : _b[0]) == null ? void 0 : _c.text) === "") {
22
30
  continue;
23
31
  }
@@ -290,6 +298,19 @@ function safeStringify(obj) {
290
298
  return String(obj);
291
299
  }
292
300
  }
301
+ function convertCompactedEvent(event) {
302
+ const content = createUserContent(
303
+ `[Previous Context Summary]:
304
+ ${event.compactedContent}`
305
+ );
306
+ return createEvent({
307
+ invocationId: event.invocationId,
308
+ author: "user",
309
+ content,
310
+ branch: event.branch,
311
+ timestamp: event.timestamp
312
+ });
313
+ }
293
314
  export {
294
315
  getContents,
295
316
  getCurrentTurnContents
@@ -3,11 +3,12 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
+ import { isCompactedEvent } from "../../events/compacted_event.js";
7
+ import { isLlmAgent } from "../llm_agent.js";
6
8
  import {
7
9
  getContents,
8
10
  getCurrentTurnContents
9
- } from "../content_processor_utils.js";
10
- import { isLlmAgent } from "../llm_agent.js";
11
+ } from "./content_processor_utils.js";
11
12
  class ContentRequestProcessor {
12
13
  // eslint-disable-next-line require-yield
13
14
  async *runAsync(invocationContext, llmRequest) {
@@ -15,15 +16,35 @@ class ContentRequestProcessor {
15
16
  if (!agent || !isLlmAgent(agent)) {
16
17
  return;
17
18
  }
19
+ let events = invocationContext.session.events;
20
+ const compactedEvents = events.filter(isCompactedEvent);
21
+ const latestCompactedEvent = compactedEvents.length > 0 ? compactedEvents.reduce(
22
+ (latest, current) => current.endTime > latest.endTime ? current : latest
23
+ ) : void 0;
24
+ if (latestCompactedEvent) {
25
+ const remainingEvents = events.filter((event) => {
26
+ if (event === latestCompactedEvent) {
27
+ return false;
28
+ }
29
+ if (isCompactedEvent(event)) {
30
+ return false;
31
+ }
32
+ if (event.timestamp <= latestCompactedEvent.endTime) {
33
+ return false;
34
+ }
35
+ return true;
36
+ });
37
+ events = [latestCompactedEvent, ...remainingEvents];
38
+ }
18
39
  if (agent.includeContents === "default") {
19
40
  llmRequest.contents = getContents(
20
- invocationContext.session.events,
41
+ events,
21
42
  agent.name,
22
43
  invocationContext.branch
23
44
  );
24
45
  } else {
25
46
  llmRequest.contents = getCurrentTurnContents(
26
- invocationContext.session.events,
47
+ events,
27
48
  agent.name,
28
49
  invocationContext.branch
29
50
  );
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ class ContextCompactorRequestProcessor {
7
+ constructor(compactors) {
8
+ this.compactors = compactors;
9
+ }
10
+ async *runAsync(invocationContext, _llmRequest) {
11
+ for (const compactor of this.compactors) {
12
+ const shouldCompact = await Promise.resolve(
13
+ compactor.shouldCompact(invocationContext)
14
+ );
15
+ if (shouldCompact) {
16
+ const oldEvents = new Set(invocationContext.session.events);
17
+ await Promise.resolve(compactor.compact(invocationContext));
18
+ const newEvents = invocationContext.session.events.filter(
19
+ (e) => !oldEvents.has(e)
20
+ );
21
+ for (const e of newEvents) {
22
+ yield e;
23
+ }
24
+ return;
25
+ }
26
+ }
27
+ }
28
+ }
29
+ export {
30
+ ContextCompactorRequestProcessor
31
+ };
@@ -15,7 +15,7 @@ class InstructionsLlmRequestProcessor extends BaseLlmRequestProcessor {
15
15
  // eslint-disable-next-line require-yield
16
16
  async *runAsync(invocationContext, llmRequest) {
17
17
  const agent = invocationContext.agent;
18
- if (!isLlmAgent(agent) || !isLlmAgent(agent.rootAgent)) {
18
+ if (!isLlmAgent(agent)) {
19
19
  return;
20
20
  }
21
21
  const rootAgent = agent.rootAgent;
@@ -307,8 +307,28 @@ class FileArtifactService {
307
307
  }
308
308
  }
309
309
  }
310
+ const SAFE_SEGMENT_RE = /^[a-zA-Z0-9_@-][a-zA-Z0-9_.@-]{0,255}$/;
311
+ function assertSafeSegment(value, label) {
312
+ if (!value || !SAFE_SEGMENT_RE.test(value)) {
313
+ throw new Error(
314
+ `[FileArtifactService] Invalid ${label}: value contains disallowed characters.`
315
+ );
316
+ }
317
+ }
318
+ function assertInsideRoot(resolvedPath, rootDir, label) {
319
+ const root = path.resolve(rootDir);
320
+ const resolved = path.resolve(resolvedPath);
321
+ if (!resolved.startsWith(root + path.sep) && resolved !== root) {
322
+ throw new Error(
323
+ `[FileArtifactService] ${label} escapes storage root. Resolved: ${resolved}, Root: ${root}`
324
+ );
325
+ }
326
+ }
310
327
  function getUserRoot(rootDir, userId) {
311
- return path.join(rootDir, "users", userId);
328
+ assertSafeSegment(userId, "userId");
329
+ const result = path.join(rootDir, "users", userId);
330
+ assertInsideRoot(result, rootDir, "userRoot");
331
+ return result;
312
332
  }
313
333
  function isUserScoped(sessionId, filename) {
314
334
  return !sessionId || filename.startsWith(USER_NAMESPACE_PREFIX);
@@ -317,7 +337,10 @@ function getUserArtifactsDir(userRoot) {
317
337
  return path.join(userRoot, "artifacts");
318
338
  }
319
339
  function getSessionArtifactsDir(baseRoot, sessionId) {
320
- return path.join(baseRoot, "sessions", sessionId, "artifacts");
340
+ assertSafeSegment(sessionId, "sessionId");
341
+ const result = path.join(baseRoot, "sessions", sessionId, "artifacts");
342
+ assertInsideRoot(result, baseRoot, "sessionArtifactsDir");
343
+ return result;
321
344
  }
322
345
  function getVersionsDir(artifactDir) {
323
346
  return path.join(artifactDir, "versions");
@@ -447,5 +470,9 @@ function asPosixPath(p) {
447
470
  return p.split(path.sep).join("/");
448
471
  }
449
472
  export {
450
- FileArtifactService
473
+ FileArtifactService,
474
+ assertInsideRoot,
475
+ assertSafeSegment,
476
+ getSessionArtifactsDir,
477
+ getUserRoot
451
478
  };
@@ -16,6 +16,11 @@ import {
16
16
  BaseLlmRequestProcessor,
17
17
  BaseLlmResponseProcessor
18
18
  } from "./agents/processors/base_llm_processor.js";
19
+ import {
20
+ CONTENT_REQUEST_PROCESSOR,
21
+ ContentRequestProcessor
22
+ } from "./agents/processors/content_request_processor.js";
23
+ import { ContextCompactorRequestProcessor } from "./agents/processors/context_compactor_request_processor.js";
19
24
  import { ReadonlyContext } from "./agents/readonly_context.js";
20
25
  import { StreamingMode } from "./agents/run_config.js";
21
26
  import { SequentialAgent, isSequentialAgent } from "./agents/sequential_agent.js";
@@ -23,6 +28,10 @@ import { InMemoryArtifactService } from "./artifacts/in_memory_artifact_service.
23
28
  import { AuthCredentialTypes } from "./auth/auth_credential.js";
24
29
  import { BaseCodeExecutor } from "./code_executors/base_code_executor.js";
25
30
  import { BuiltInCodeExecutor } from "./code_executors/built_in_code_executor.js";
31
+ import { LlmSummarizer } from "./context/summarizers/llm_summarizer.js";
32
+ import { TokenBasedContextCompactor } from "./context/token_based_context_compactor.js";
33
+ import { TruncatingContextCompactor } from "./context/truncating_context_compactor.js";
34
+ import { isCompactedEvent } from "./events/compacted_event.js";
26
35
  import {
27
36
  createEvent,
28
37
  getFunctionCalls,
@@ -53,7 +62,7 @@ import {
53
62
  getAskUserConfirmationFunctionCalls
54
63
  } from "./plugins/security_plugin.js";
55
64
  import { InMemoryRunner } from "./runner/in_memory_runner.js";
56
- import { Runner } from "./runner/runner.js";
65
+ import { Runner, isRunner } from "./runner/runner.js";
57
66
  import { BaseSessionService } from "./sessions/base_session_service.js";
58
67
  import { InMemorySessionService } from "./sessions/in_memory_session_service.js";
59
68
  import { createSession } from "./sessions/session.js";
@@ -64,7 +73,16 @@ import { BaseToolset, isBaseToolset } from "./tools/base_toolset.js";
64
73
  import { EXIT_LOOP, ExitLoopTool } from "./tools/exit_loop_tool.js";
65
74
  import { FunctionTool, isFunctionTool } from "./tools/function_tool.js";
66
75
  import { GOOGLE_SEARCH, GoogleSearchTool } from "./tools/google_search_tool.js";
76
+ import {
77
+ LOAD_ARTIFACTS,
78
+ LoadArtifactsTool
79
+ } from "./tools/load_artifacts_tool.js";
80
+ import { LOAD_MEMORY, LoadMemoryTool } from "./tools/load_memory_tool.js";
67
81
  import { LongRunningFunctionTool } from "./tools/long_running_tool.js";
82
+ import {
83
+ PRELOAD_MEMORY,
84
+ PreloadMemoryTool
85
+ } from "./tools/preload_memory_tool.js";
68
86
  import { ToolConfirmation } from "./tools/tool_confirmation.js";
69
87
  import { LogLevel, getLogger, setLogLevel, setLogger } from "./utils/logger.js";
70
88
  import { isGemini2OrAbove } from "./utils/model_name.js";
@@ -91,7 +109,10 @@ export {
91
109
  BaseTool,
92
110
  BaseToolset,
93
111
  BuiltInCodeExecutor,
112
+ CONTENT_REQUEST_PROCESSOR,
113
+ ContentRequestProcessor,
94
114
  Context,
115
+ ContextCompactorRequestProcessor,
95
116
  EXIT_LOOP,
96
117
  EventType,
97
118
  ExitLoopTool,
@@ -107,15 +128,22 @@ export {
107
128
  InMemorySessionService,
108
129
  InvocationContext,
109
130
  LLMRegistry,
131
+ LOAD_ARTIFACTS,
132
+ LOAD_MEMORY,
110
133
  LiveRequestQueue,
111
134
  LlmAgent,
135
+ LlmSummarizer,
136
+ LoadArtifactsTool,
137
+ LoadMemoryTool,
112
138
  LogLevel,
113
139
  LoggingPlugin,
114
140
  LongRunningFunctionTool,
115
141
  LoopAgent,
142
+ PRELOAD_MEMORY,
116
143
  ParallelAgent,
117
144
  PluginManager,
118
145
  PolicyOutcome,
146
+ PreloadMemoryTool,
119
147
  REQUEST_CONFIRMATION_FUNCTION_CALL_NAME,
120
148
  ReadonlyContext,
121
149
  Runner,
@@ -123,7 +151,9 @@ export {
123
151
  SequentialAgent,
124
152
  State,
125
153
  StreamingMode,
154
+ TokenBasedContextCompactor,
126
155
  ToolConfirmation,
156
+ TruncatingContextCompactor,
127
157
  createEvent,
128
158
  createEventActions,
129
159
  createSession,
@@ -140,12 +170,14 @@ export {
140
170
  isBaseLlm,
141
171
  isBaseTool,
142
172
  isBaseToolset,
173
+ isCompactedEvent,
143
174
  isFinalResponse,
144
175
  isFunctionTool,
145
176
  isGemini2OrAbove,
146
177
  isLlmAgent,
147
178
  isLoopAgent,
148
179
  isParallelAgent,
180
+ isRunner,
149
181
  isSequentialAgent,
150
182
  setLogLevel,
151
183
  setLogger,
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import {
7
+ createCompactedEvent
8
+ } from "../../events/compacted_event.js";
9
+ import { stringifyContent } from "../../events/event.js";
10
+ const DEFAULT_PROMPT = "The following is a conversation history between a user and an AI agent. Please summarize the conversation, focusing on key information and decisions made, as well as any unresolved questions or tasks. The summary should be concise and capture the essence of the interaction.";
11
+ class LlmSummarizer {
12
+ constructor(options) {
13
+ this.llm = options.llm;
14
+ this.prompt = options.prompt || DEFAULT_PROMPT;
15
+ }
16
+ async summarize(events) {
17
+ var _a, _b, _c, _d, _e, _f;
18
+ if (events.length === 0) {
19
+ throw new Error("Cannot summarize an empty list of events.");
20
+ }
21
+ const startTime = events[0].timestamp;
22
+ const endTime = events[events.length - 1].timestamp;
23
+ let formattedEvents = "";
24
+ for (let i = 0; i < events.length; i++) {
25
+ formattedEvents += `[Event ${i + 1} - Author: ${events[i].author}]
26
+ `;
27
+ formattedEvents += `${stringifyContent(events[i])}
28
+
29
+ `;
30
+ }
31
+ const fullPrompt = `${this.prompt}
32
+
33
+ ${formattedEvents}`;
34
+ const request = {
35
+ contents: [{ role: "user", parts: [{ text: fullPrompt }] }],
36
+ toolsDict: {},
37
+ liveConnectConfig: {}
38
+ };
39
+ const responseGen = this.llm.generateContentAsync(request, false);
40
+ let compactedContent = "";
41
+ const firstResponse = await responseGen.next();
42
+ if (firstResponse.done || !((_c = (_b = (_a = firstResponse.value.content) == null ? void 0 : _a.parts) == null ? void 0 : _b[0]) == null ? void 0 : _c.text)) {
43
+ throw new Error("LLM failed to return a valid summary.");
44
+ }
45
+ compactedContent += firstResponse.value.content.parts[0].text;
46
+ for await (const chunk of responseGen) {
47
+ if ((_f = (_e = (_d = chunk.content) == null ? void 0 : _d.parts) == null ? void 0 : _e[0]) == null ? void 0 : _f.text) {
48
+ compactedContent += chunk.content.parts[0].text;
49
+ }
50
+ }
51
+ return createCompactedEvent({
52
+ author: "system",
53
+ content: {
54
+ role: "model",
55
+ parts: [{ text: compactedContent }]
56
+ },
57
+ startTime,
58
+ endTime,
59
+ compactedContent
60
+ });
61
+ }
62
+ }
63
+ export {
64
+ LlmSummarizer
65
+ };