@google/adk 0.4.0 → 0.5.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 (132) hide show
  1. package/dist/cjs/a2a/a2a_event.js +290 -0
  2. package/dist/cjs/a2a/event_converter_utils.js +201 -0
  3. package/dist/cjs/a2a/executor_context.js +53 -0
  4. package/dist/cjs/a2a/metadata_converter_utils.js +125 -0
  5. package/dist/cjs/a2a/part_converter_utils.js +23 -21
  6. package/dist/cjs/agents/base_agent.js +3 -3
  7. package/dist/cjs/{tools/tool_context.js → agents/context.js} +70 -15
  8. package/dist/cjs/agents/functions.js +2 -2
  9. package/dist/cjs/agents/llm_agent.js +21 -674
  10. package/dist/cjs/agents/processors/agent_transfer_llm_request_processor.js +132 -0
  11. package/dist/cjs/agents/processors/basic_llm_request_processor.js +68 -0
  12. package/dist/cjs/agents/processors/code_execution_request_processor.js +389 -0
  13. package/dist/cjs/agents/processors/content_request_processor.js +66 -0
  14. package/dist/cjs/agents/processors/identity_llm_request_processor.js +54 -0
  15. package/dist/cjs/agents/processors/instructions_llm_request_processor.js +85 -0
  16. package/dist/cjs/agents/processors/request_confirmation_llm_request_processor.js +165 -0
  17. package/dist/cjs/common.js +11 -7
  18. package/dist/cjs/index.js +89 -53
  19. package/dist/cjs/index.js.map +7 -0
  20. package/dist/cjs/models/llm_response.js +2 -0
  21. package/dist/cjs/plugins/base_plugin.js +1 -1
  22. package/dist/cjs/runner/runner.js +1 -1
  23. package/dist/cjs/sessions/database_session_service.js +4 -1
  24. package/dist/cjs/sessions/db/operations.js +24 -12
  25. package/dist/cjs/tools/base_tool.js +3 -0
  26. package/dist/cjs/tools/base_toolset.js +13 -3
  27. package/dist/cjs/tools/exit_loop_tool.js +63 -0
  28. package/dist/cjs/tools/mcp/mcp_toolset.js +9 -5
  29. package/dist/cjs/utils/logger.js +61 -54
  30. package/dist/cjs/version.js +1 -1
  31. package/dist/esm/a2a/a2a_event.js +243 -0
  32. package/dist/esm/a2a/event_converter_utils.js +187 -0
  33. package/dist/esm/a2a/executor_context.js +23 -0
  34. package/dist/esm/a2a/metadata_converter_utils.js +90 -0
  35. package/dist/esm/a2a/part_converter_utils.js +25 -21
  36. package/dist/esm/agents/base_agent.js +3 -3
  37. package/dist/esm/{tools/tool_context.js → agents/context.js} +66 -11
  38. package/dist/esm/agents/functions.js +2 -2
  39. package/dist/esm/agents/llm_agent.js +14 -683
  40. package/dist/esm/agents/processors/agent_transfer_llm_request_processor.js +101 -0
  41. package/dist/esm/agents/processors/basic_llm_request_processor.js +37 -0
  42. package/dist/esm/agents/processors/code_execution_request_processor.js +363 -0
  43. package/dist/esm/agents/processors/content_request_processor.js +38 -0
  44. package/dist/esm/agents/processors/identity_llm_request_processor.js +23 -0
  45. package/dist/esm/agents/processors/instructions_llm_request_processor.js +54 -0
  46. package/dist/esm/agents/processors/request_confirmation_llm_request_processor.js +140 -0
  47. package/dist/esm/common.js +11 -9
  48. package/dist/esm/index.js +95 -18
  49. package/dist/esm/index.js.map +7 -0
  50. package/dist/esm/models/llm_response.js +2 -0
  51. package/dist/esm/plugins/base_plugin.js +1 -1
  52. package/dist/esm/runner/runner.js +1 -1
  53. package/dist/esm/sessions/database_session_service.js +4 -1
  54. package/dist/esm/sessions/db/operations.js +31 -7
  55. package/dist/esm/tools/base_tool.js +3 -0
  56. package/dist/esm/tools/base_toolset.js +11 -2
  57. package/dist/esm/tools/exit_loop_tool.js +32 -0
  58. package/dist/esm/tools/mcp/mcp_toolset.js +9 -5
  59. package/dist/esm/utils/logger.js +51 -54
  60. package/dist/esm/version.js +1 -1
  61. package/dist/types/a2a/a2a_event.d.ts +122 -0
  62. package/dist/types/a2a/event_converter_utils.d.ts +20 -0
  63. package/dist/types/a2a/executor_context.d.ts +33 -0
  64. package/dist/types/a2a/metadata_converter_utils.d.ts +62 -0
  65. package/dist/types/a2a/part_converter_utils.d.ts +4 -3
  66. package/dist/types/agents/base_agent.d.ts +2 -2
  67. package/dist/types/{tools/tool_context.d.ts → agents/context.d.ts} +43 -8
  68. package/dist/types/agents/llm_agent.d.ts +8 -31
  69. package/dist/types/agents/processors/agent_transfer_llm_request_processor.d.ts +18 -0
  70. package/dist/types/agents/{base_llm_processor.d.ts → processors/base_llm_processor.d.ts} +4 -4
  71. package/dist/types/agents/processors/basic_llm_request_processor.d.ts +13 -0
  72. package/dist/types/agents/processors/code_execution_request_processor.d.ts +34 -0
  73. package/dist/types/agents/processors/content_request_processor.d.ts +13 -0
  74. package/dist/types/agents/processors/identity_llm_request_processor.d.ts +13 -0
  75. package/dist/types/agents/processors/instructions_llm_request_processor.d.ts +16 -0
  76. package/dist/types/agents/processors/request_confirmation_llm_request_processor.d.ts +13 -0
  77. package/dist/types/auth/credential_service/base_credential_service.d.ts +3 -3
  78. package/dist/types/auth/credential_service/in_memory_credential_service.d.ts +3 -3
  79. package/dist/types/common.d.ts +4 -4
  80. package/dist/types/models/llm_response.d.ts +5 -1
  81. package/dist/types/plugins/base_plugin.d.ts +12 -13
  82. package/dist/types/plugins/logging_plugin.d.ts +9 -10
  83. package/dist/types/plugins/plugin_manager.d.ts +9 -10
  84. package/dist/types/plugins/security_plugin.d.ts +2 -2
  85. package/dist/types/sessions/database_session_service.d.ts +2 -1
  86. package/dist/types/sessions/db/operations.d.ts +1 -1
  87. package/dist/types/tools/base_tool.d.ts +3 -3
  88. package/dist/types/tools/base_toolset.d.ts +12 -3
  89. package/dist/types/tools/exit_loop_tool.d.ts +24 -0
  90. package/dist/types/tools/forwarding_artifact_service.d.ts +2 -2
  91. package/dist/types/tools/function_tool.d.ts +2 -2
  92. package/dist/types/tools/mcp/mcp_toolset.d.ts +1 -1
  93. package/dist/types/utils/logger.d.ts +5 -9
  94. package/dist/types/version.d.ts +1 -1
  95. package/dist/web/a2a/a2a_event.js +243 -0
  96. package/dist/web/a2a/event_converter_utils.js +201 -0
  97. package/dist/web/a2a/executor_context.js +23 -0
  98. package/dist/web/a2a/metadata_converter_utils.js +107 -0
  99. package/dist/web/a2a/part_converter_utils.js +25 -21
  100. package/dist/web/agents/base_agent.js +3 -3
  101. package/dist/web/{tools/tool_context.js → agents/context.js} +66 -11
  102. package/dist/web/agents/functions.js +2 -2
  103. package/dist/web/agents/llm_agent.js +14 -661
  104. package/dist/web/agents/processors/agent_transfer_llm_request_processor.js +100 -0
  105. package/dist/web/agents/processors/basic_llm_request_processor.js +71 -0
  106. package/dist/web/agents/processors/code_execution_request_processor.js +365 -0
  107. package/dist/web/agents/processors/content_request_processor.js +56 -0
  108. package/dist/web/agents/processors/identity_llm_request_processor.js +41 -0
  109. package/dist/web/agents/processors/instructions_llm_request_processor.js +72 -0
  110. package/dist/web/agents/processors/request_confirmation_llm_request_processor.js +158 -0
  111. package/dist/web/common.js +11 -9
  112. package/dist/web/index.js +13 -18
  113. package/dist/web/index.js.map +7 -0
  114. package/dist/web/models/llm_response.js +2 -0
  115. package/dist/web/plugins/base_plugin.js +1 -1
  116. package/dist/web/runner/runner.js +1 -1
  117. package/dist/web/sessions/database_session_service.js +4 -1
  118. package/dist/web/sessions/db/operations.js +31 -7
  119. package/dist/web/tools/base_tool.js +3 -0
  120. package/dist/web/tools/base_toolset.js +11 -2
  121. package/dist/web/tools/exit_loop_tool.js +32 -0
  122. package/dist/web/tools/mcp/mcp_toolset.js +27 -5
  123. package/dist/web/utils/logger.js +51 -54
  124. package/dist/web/version.js +1 -1
  125. package/package.json +3 -2
  126. package/dist/cjs/agents/callback_context.js +0 -101
  127. package/dist/esm/agents/callback_context.js +0 -71
  128. package/dist/types/agents/callback_context.d.ts +0 -42
  129. package/dist/web/agents/callback_context.js +0 -71
  130. /package/dist/cjs/agents/{base_llm_processor.js → processors/base_llm_processor.js} +0 -0
  131. /package/dist/esm/agents/{base_llm_processor.js → processors/base_llm_processor.js} +0 -0
  132. /package/dist/web/agents/{base_llm_processor.js → processors/base_llm_processor.js} +0 -0
@@ -0,0 +1,101 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { z } from "zod";
7
+ import { appendInstructions } from "../../models/llm_request.js";
8
+ import { FunctionTool } from "../../tools/function_tool.js";
9
+ import { Context } from "../context.js";
10
+ import { isLlmAgent } from "../llm_agent.js";
11
+ import { BaseLlmRequestProcessor } from "./base_llm_processor.js";
12
+ class AgentTransferLlmRequestProcessor extends BaseLlmRequestProcessor {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.toolName = "transfer_to_agent";
16
+ this.tool = new FunctionTool({
17
+ name: this.toolName,
18
+ description: "Transfer the question to another agent. This tool hands off control to another agent when it is more suitable to answer the user question according to the agent description.",
19
+ parameters: z.object({
20
+ agentName: z.string().describe("the agent name to transfer to.")
21
+ }),
22
+ execute: function(args, toolContext) {
23
+ if (!toolContext) {
24
+ throw new Error("toolContext is required.");
25
+ }
26
+ toolContext.actions.transferToAgent = args.agentName;
27
+ return "Transfer queued";
28
+ }
29
+ });
30
+ }
31
+ // eslint-disable-next-line require-yield
32
+ async *runAsync(invocationContext, llmRequest) {
33
+ if (!isLlmAgent(invocationContext.agent)) {
34
+ return;
35
+ }
36
+ const transferTargets = this.getTransferTargets(invocationContext.agent);
37
+ if (!transferTargets.length) {
38
+ return;
39
+ }
40
+ appendInstructions(llmRequest, [
41
+ this.buildTargetAgentsInstructions(
42
+ invocationContext.agent,
43
+ transferTargets
44
+ )
45
+ ]);
46
+ const toolContext = new Context({ invocationContext });
47
+ await this.tool.processLlmRequest({ toolContext, llmRequest });
48
+ }
49
+ buildTargetAgentsInfo(targetAgent) {
50
+ return `
51
+ Agent name: ${targetAgent.name}
52
+ Agent description: ${targetAgent.description}
53
+ `;
54
+ }
55
+ buildTargetAgentsInstructions(agent, targetAgents) {
56
+ let instructions = `
57
+ You have a list of other agents to transfer to:
58
+
59
+ ${targetAgents.map((t) => this.buildTargetAgentsInfo(t)).join("\n")}
60
+
61
+ If you are the best to answer the question according to your description, you
62
+ can answer it.
63
+
64
+ If another agent is better for answering the question according to its
65
+ description, call \`${this.toolName}\` function to transfer the
66
+ question to that agent. When transferring, do not generate any text other than
67
+ the function call.
68
+ `;
69
+ if (agent.parentAgent && !agent.disallowTransferToParent) {
70
+ instructions += `
71
+ Your parent agent is ${agent.parentAgent.name}. If neither the other agents nor
72
+ you are best for answering the question according to the descriptions, transfer
73
+ to your parent agent.
74
+ `;
75
+ }
76
+ return instructions;
77
+ }
78
+ getTransferTargets(agent) {
79
+ const targets = [];
80
+ targets.push(...agent.subAgents);
81
+ if (!agent.parentAgent || !isLlmAgent(agent.parentAgent)) {
82
+ return targets;
83
+ }
84
+ if (!agent.disallowTransferToParent) {
85
+ targets.push(agent.parentAgent);
86
+ }
87
+ if (!agent.disallowTransferToPeers) {
88
+ targets.push(
89
+ ...agent.parentAgent.subAgents.filter(
90
+ (peerAgent) => peerAgent.name !== agent.name
91
+ )
92
+ );
93
+ }
94
+ return targets;
95
+ }
96
+ }
97
+ const AGENT_TRANSFER_LLM_REQUEST_PROCESSOR = new AgentTransferLlmRequestProcessor();
98
+ export {
99
+ AGENT_TRANSFER_LLM_REQUEST_PROCESSOR,
100
+ AgentTransferLlmRequestProcessor
101
+ };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { setOutputSchema } from "../../models/llm_request.js";
7
+ import { isLlmAgent } from "../llm_agent.js";
8
+ import { BaseLlmRequestProcessor } from "./base_llm_processor.js";
9
+ class BasicLlmRequestProcessor extends BaseLlmRequestProcessor {
10
+ // eslint-disable-next-line require-yield
11
+ async *runAsync(invocationContext, llmRequest) {
12
+ var _a;
13
+ const agent = invocationContext.agent;
14
+ if (!isLlmAgent(agent)) {
15
+ return;
16
+ }
17
+ llmRequest.model = agent.canonicalModel.model;
18
+ llmRequest.config = { ...(_a = agent.generateContentConfig) != null ? _a : {} };
19
+ if (agent.outputSchema) {
20
+ setOutputSchema(llmRequest, agent.outputSchema);
21
+ }
22
+ if (invocationContext.runConfig) {
23
+ llmRequest.liveConnectConfig.responseModalities = invocationContext.runConfig.responseModalities;
24
+ llmRequest.liveConnectConfig.speechConfig = invocationContext.runConfig.speechConfig;
25
+ llmRequest.liveConnectConfig.outputAudioTranscription = invocationContext.runConfig.outputAudioTranscription;
26
+ llmRequest.liveConnectConfig.inputAudioTranscription = invocationContext.runConfig.inputAudioTranscription;
27
+ llmRequest.liveConnectConfig.realtimeInputConfig = invocationContext.runConfig.realtimeInputConfig;
28
+ llmRequest.liveConnectConfig.enableAffectiveDialog = invocationContext.runConfig.enableAffectiveDialog;
29
+ llmRequest.liveConnectConfig.proactivity = invocationContext.runConfig.proactivity;
30
+ }
31
+ }
32
+ }
33
+ const BASIC_LLM_REQUEST_PROCESSOR = new BasicLlmRequestProcessor();
34
+ export {
35
+ BASIC_LLM_REQUEST_PROCESSOR,
36
+ BasicLlmRequestProcessor
37
+ };
@@ -0,0 +1,363 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { cloneDeep } from "lodash-es";
7
+ import { isBaseCodeExecutor } from "../../code_executors/base_code_executor.js";
8
+ import { isBuiltInCodeExecutor } from "../../code_executors/built_in_code_executor.js";
9
+ import {
10
+ buildCodeExecutionResultPart,
11
+ buildExecutableCodePart,
12
+ convertCodeExecutionParts,
13
+ extractCodeAndTruncateContent
14
+ } from "../../code_executors/code_execution_utils.js";
15
+ import { CodeExecutorContext } from "../../code_executors/code_executor_context.js";
16
+ import { createEvent } from "../../events/event.js";
17
+ import { createEventActions } from "../../events/event_actions.js";
18
+ import { State } from "../../sessions/state.js";
19
+ import { base64Decode } from "../../utils/env_aware_utils.js";
20
+ import { isLlmAgent } from "../llm_agent.js";
21
+ import {
22
+ BaseLlmRequestProcessor
23
+ } from "./base_llm_processor.js";
24
+ class CodeExecutionRequestProcessor extends BaseLlmRequestProcessor {
25
+ async *runAsync(invocationContext, llmRequest) {
26
+ if (!isLlmAgent(invocationContext.agent)) {
27
+ return;
28
+ }
29
+ if (!invocationContext.agent.codeExecutor) {
30
+ return;
31
+ }
32
+ for await (const event of runPreProcessor(invocationContext, llmRequest)) {
33
+ yield event;
34
+ }
35
+ if (!isBaseCodeExecutor(invocationContext.agent.codeExecutor)) {
36
+ return;
37
+ }
38
+ for (const content of llmRequest.contents) {
39
+ const delimeters = invocationContext.agent.codeExecutor.codeBlockDelimiters.length ? invocationContext.agent.codeExecutor.codeBlockDelimiters[0] : ["", ""];
40
+ convertCodeExecutionParts(
41
+ content,
42
+ delimeters,
43
+ invocationContext.agent.codeExecutor.executionResultDelimiters
44
+ );
45
+ }
46
+ }
47
+ }
48
+ const DATA_FILE_UTIL_MAP = {
49
+ "text/csv": {
50
+ extension: ".csv",
51
+ loaderCodeTemplate: "pd.read_csv('{filename}')"
52
+ }
53
+ };
54
+ const DATA_FILE_HELPER_LIB = `
55
+ import pandas as pd
56
+
57
+ def explore_df(df: pd.DataFrame) -> None:
58
+ """Prints some information about a pandas DataFrame."""
59
+
60
+ with pd.option_context(
61
+ 'display.max_columns', None, 'display.expand_frame_repr', False
62
+ ):
63
+ # Print the column names to never encounter KeyError when selecting one.
64
+ df_dtypes = df.dtypes
65
+
66
+ # Obtain information about data types and missing values.
67
+ df_nulls = (len(df) - df.isnull().sum()).apply(
68
+ lambda x: f'{x} / {df.shape[0]} non-null'
69
+ )
70
+
71
+ # Explore unique total values in columns using \`.unique()\`.
72
+ df_unique_count = df.apply(lambda x: len(x.unique()))
73
+
74
+ # Explore unique values in columns using \`.unique()\`.
75
+ df_unique = df.apply(lambda x: crop(str(list(x.unique()))))
76
+
77
+ df_info = pd.concat(
78
+ (
79
+ df_dtypes.rename('Dtype'),
80
+ df_nulls.rename('Non-Null Count'),
81
+ df_unique_count.rename('Unique Values Count'),
82
+ df_unique.rename('Unique Values'),
83
+ ),
84
+ axis=1,
85
+ )
86
+ df_info.index.name = 'Columns'
87
+ print(f"""Total rows: {df.shape[0]}
88
+ Total columns: {df.shape[1]}
89
+
90
+ {df_info}""")
91
+ `;
92
+ class CodeExecutionResponseProcessor {
93
+ /**
94
+ * Processes the LLM response asynchronously.
95
+ *
96
+ * @param invocationContext The invocation context
97
+ * @param llmResponse The LLM response to process
98
+ * @returns An async generator yielding events
99
+ */
100
+ async *runAsync(invocationContext, llmResponse) {
101
+ if (llmResponse.partial) {
102
+ return;
103
+ }
104
+ for await (const event of runPostProcessor(
105
+ invocationContext,
106
+ llmResponse
107
+ )) {
108
+ yield event;
109
+ }
110
+ }
111
+ }
112
+ const responseProcessor = new CodeExecutionResponseProcessor();
113
+ async function* runPreProcessor(invocationContext, llmRequest) {
114
+ const agent = invocationContext.agent;
115
+ if (!isLlmAgent(agent)) {
116
+ return;
117
+ }
118
+ const codeExecutor = agent.codeExecutor;
119
+ if (!codeExecutor || !isBaseCodeExecutor(codeExecutor)) {
120
+ return;
121
+ }
122
+ if (isBuiltInCodeExecutor(codeExecutor)) {
123
+ codeExecutor.processLlmRequest(llmRequest);
124
+ return;
125
+ }
126
+ if (!codeExecutor.optimizeDataFile) {
127
+ return;
128
+ }
129
+ const codeExecutorContext = new CodeExecutorContext(
130
+ new State(invocationContext.session.state)
131
+ );
132
+ if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >= codeExecutor.errorRetryAttempts) {
133
+ return;
134
+ }
135
+ const allInputFiles = extractAndReplaceInlineFiles(
136
+ codeExecutorContext,
137
+ llmRequest
138
+ );
139
+ const processedFileNames = new Set(
140
+ codeExecutorContext.getProcessedFileNames()
141
+ );
142
+ const filesToProcess = allInputFiles.filter(
143
+ (f) => !processedFileNames.has(f.name)
144
+ );
145
+ for (const file of filesToProcess) {
146
+ const codeStr = getDataFilePreprocessingCode(file);
147
+ if (!codeStr) {
148
+ return;
149
+ }
150
+ const codeContent = {
151
+ role: "model",
152
+ parts: [
153
+ { text: `Processing input file: \`${file.name}\`` },
154
+ buildExecutableCodePart(codeStr)
155
+ ]
156
+ };
157
+ llmRequest.contents.push(cloneDeep(codeContent));
158
+ yield createEvent({
159
+ invocationId: invocationContext.invocationId,
160
+ author: agent.name,
161
+ branch: invocationContext.branch,
162
+ content: codeContent
163
+ });
164
+ const executionId = getOrSetExecutionId(
165
+ invocationContext,
166
+ codeExecutorContext
167
+ );
168
+ const codeExecutionResult = await codeExecutor.executeCode({
169
+ invocationContext,
170
+ codeExecutionInput: {
171
+ code: codeStr,
172
+ inputFiles: [file],
173
+ executionId
174
+ }
175
+ });
176
+ codeExecutorContext.updateCodeExecutionResult({
177
+ invocationId: invocationContext.invocationId,
178
+ code: codeStr,
179
+ resultStdout: codeExecutionResult.stdout,
180
+ resultStderr: codeExecutionResult.stderr
181
+ });
182
+ codeExecutorContext.addProcessedFileNames([file.name]);
183
+ const executionResultEvent = await postProcessCodeExecutionResult(
184
+ invocationContext,
185
+ codeExecutorContext,
186
+ codeExecutionResult
187
+ );
188
+ yield executionResultEvent;
189
+ llmRequest.contents.push(cloneDeep(executionResultEvent.content));
190
+ }
191
+ }
192
+ async function* runPostProcessor(invocationContext, llmResponse) {
193
+ const agent = invocationContext.agent;
194
+ if (!isLlmAgent(agent)) {
195
+ return;
196
+ }
197
+ const codeExecutor = agent.codeExecutor;
198
+ if (!codeExecutor || !isBaseCodeExecutor(codeExecutor)) {
199
+ return;
200
+ }
201
+ if (!llmResponse || !llmResponse.content) {
202
+ return;
203
+ }
204
+ if (isBuiltInCodeExecutor(codeExecutor)) {
205
+ return;
206
+ }
207
+ const codeExecutorContext = new CodeExecutorContext(
208
+ new State(invocationContext.session.state)
209
+ );
210
+ if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >= codeExecutor.errorRetryAttempts) {
211
+ return;
212
+ }
213
+ const responseContent = llmResponse.content;
214
+ const codeStr = extractCodeAndTruncateContent(
215
+ responseContent,
216
+ codeExecutor.codeBlockDelimiters
217
+ );
218
+ if (!codeStr) {
219
+ return;
220
+ }
221
+ yield createEvent({
222
+ invocationId: invocationContext.invocationId,
223
+ author: agent.name,
224
+ branch: invocationContext.branch,
225
+ content: responseContent
226
+ });
227
+ const executionId = getOrSetExecutionId(
228
+ invocationContext,
229
+ codeExecutorContext
230
+ );
231
+ const codeExecutionResult = await codeExecutor.executeCode({
232
+ invocationContext,
233
+ codeExecutionInput: {
234
+ code: codeStr,
235
+ inputFiles: codeExecutorContext.getInputFiles(),
236
+ executionId
237
+ }
238
+ });
239
+ codeExecutorContext.updateCodeExecutionResult({
240
+ invocationId: invocationContext.invocationId,
241
+ code: codeStr,
242
+ resultStdout: codeExecutionResult.stdout,
243
+ resultStderr: codeExecutionResult.stderr
244
+ });
245
+ yield await postProcessCodeExecutionResult(
246
+ invocationContext,
247
+ codeExecutorContext,
248
+ codeExecutionResult
249
+ );
250
+ llmResponse.content = void 0;
251
+ }
252
+ function extractAndReplaceInlineFiles(codeExecutorContext, llmRequest) {
253
+ var _a;
254
+ const allInputFiles = codeExecutorContext.getInputFiles();
255
+ const savedFileNames = new Set(allInputFiles.map((f) => f.name));
256
+ for (let i = 0; i < llmRequest.contents.length; i++) {
257
+ const content = llmRequest.contents[i];
258
+ if (content.role !== "user" || !content.parts) {
259
+ continue;
260
+ }
261
+ for (let j = 0; j < content.parts.length; j++) {
262
+ const part = content.parts[j];
263
+ const mimeType = (_a = part.inlineData) == null ? void 0 : _a.mimeType;
264
+ if (!mimeType || !part.inlineData || !DATA_FILE_UTIL_MAP[mimeType]) {
265
+ continue;
266
+ }
267
+ const fileName = `data_${i + 1}_${j + 1}${DATA_FILE_UTIL_MAP[mimeType].extension}`;
268
+ part.text = `
269
+ Available file: \`${fileName}\`
270
+ `;
271
+ const file = {
272
+ name: fileName,
273
+ content: base64Decode(part.inlineData.data),
274
+ mimeType
275
+ };
276
+ if (!savedFileNames.has(fileName)) {
277
+ codeExecutorContext.addInputFiles([file]);
278
+ allInputFiles.push(file);
279
+ }
280
+ }
281
+ }
282
+ return allInputFiles;
283
+ }
284
+ function getOrSetExecutionId(invocationContext, codeExecutorContext) {
285
+ var _a;
286
+ const agent = invocationContext.agent;
287
+ if (!isLlmAgent(agent) || !((_a = agent.codeExecutor) == null ? void 0 : _a.stateful)) {
288
+ return void 0;
289
+ }
290
+ let executionId = codeExecutorContext.getExecutionId();
291
+ if (!executionId) {
292
+ executionId = invocationContext.session.id;
293
+ codeExecutorContext.setExecutionId(executionId);
294
+ }
295
+ return executionId;
296
+ }
297
+ async function postProcessCodeExecutionResult(invocationContext, codeExecutorContext, codeExecutionResult) {
298
+ if (!invocationContext.artifactService) {
299
+ throw new Error("Artifact service is not initialized.");
300
+ }
301
+ const resultContent = {
302
+ role: "model",
303
+ parts: [buildCodeExecutionResultPart(codeExecutionResult)]
304
+ };
305
+ const eventActions = createEventActions({
306
+ stateDelta: codeExecutorContext.getStateDelta()
307
+ });
308
+ if (codeExecutionResult.stderr) {
309
+ codeExecutorContext.incrementErrorCount(invocationContext.invocationId);
310
+ } else {
311
+ codeExecutorContext.resetErrorCount(invocationContext.invocationId);
312
+ }
313
+ for (const outputFile of codeExecutionResult.outputFiles) {
314
+ const version = await invocationContext.artifactService.saveArtifact({
315
+ appName: invocationContext.appName || "",
316
+ userId: invocationContext.userId || "",
317
+ sessionId: invocationContext.session.id,
318
+ filename: outputFile.name,
319
+ artifact: {
320
+ inlineData: { data: outputFile.content, mimeType: outputFile.mimeType }
321
+ }
322
+ });
323
+ eventActions.artifactDelta[outputFile.name] = version;
324
+ }
325
+ return createEvent({
326
+ invocationId: invocationContext.invocationId,
327
+ author: invocationContext.agent.name,
328
+ branch: invocationContext.branch,
329
+ content: resultContent,
330
+ actions: eventActions
331
+ });
332
+ }
333
+ function getDataFilePreprocessingCode(file) {
334
+ function getNormalizedFileName(fileName) {
335
+ const [varName2] = fileName.split(".");
336
+ let normalizedName = varName2.replace(/[^a-zA-Z0-9_]/g, "_");
337
+ if (/^\d/.test(normalizedName)) {
338
+ normalizedName = "_" + normalizedName;
339
+ }
340
+ return normalizedName;
341
+ }
342
+ if (!DATA_FILE_UTIL_MAP[file.mimeType]) {
343
+ return void 0;
344
+ }
345
+ const varName = getNormalizedFileName(file.name);
346
+ const loaderCode = DATA_FILE_UTIL_MAP[file.mimeType].loaderCodeTemplate.replace("{filename}", file.name);
347
+ return `
348
+ ${DATA_FILE_HELPER_LIB}
349
+
350
+ # Load the dataframe.
351
+ ${varName} = ${loaderCode}
352
+
353
+ # Use \`explore_df\` to guide my analysis.
354
+ explore_df(${varName})
355
+ `;
356
+ }
357
+ const CODE_EXECUTION_REQUEST_PROCESSOR = new CodeExecutionRequestProcessor();
358
+ export {
359
+ CODE_EXECUTION_REQUEST_PROCESSOR,
360
+ CodeExecutionRequestProcessor,
361
+ CodeExecutionResponseProcessor,
362
+ responseProcessor
363
+ };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import {
7
+ getContents,
8
+ getCurrentTurnContents
9
+ } from "../content_processor_utils.js";
10
+ import { isLlmAgent } from "../llm_agent.js";
11
+ class ContentRequestProcessor {
12
+ // eslint-disable-next-line require-yield
13
+ async *runAsync(invocationContext, llmRequest) {
14
+ const agent = invocationContext.agent;
15
+ if (!agent || !isLlmAgent(agent)) {
16
+ return;
17
+ }
18
+ if (agent.includeContents === "default") {
19
+ llmRequest.contents = getContents(
20
+ invocationContext.session.events,
21
+ agent.name,
22
+ invocationContext.branch
23
+ );
24
+ } else {
25
+ llmRequest.contents = getCurrentTurnContents(
26
+ invocationContext.session.events,
27
+ agent.name,
28
+ invocationContext.branch
29
+ );
30
+ }
31
+ return;
32
+ }
33
+ }
34
+ const CONTENT_REQUEST_PROCESSOR = new ContentRequestProcessor();
35
+ export {
36
+ CONTENT_REQUEST_PROCESSOR,
37
+ ContentRequestProcessor
38
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { appendInstructions } from "../../models/llm_request.js";
7
+ import { BaseLlmRequestProcessor } from "./base_llm_processor.js";
8
+ class IdentityLlmRequestProcessor extends BaseLlmRequestProcessor {
9
+ // eslint-disable-next-line require-yield
10
+ async *runAsync(invocationContext, llmRequest) {
11
+ const agent = invocationContext.agent;
12
+ const si = [`You are an agent. Your internal name is "${agent.name}".`];
13
+ if (agent.description) {
14
+ si.push(`The description about you is "${agent.description}"`);
15
+ }
16
+ appendInstructions(llmRequest, si);
17
+ }
18
+ }
19
+ const IDENTITY_LLM_REQUEST_PROCESSOR = new IdentityLlmRequestProcessor();
20
+ export {
21
+ IDENTITY_LLM_REQUEST_PROCESSOR,
22
+ IdentityLlmRequestProcessor
23
+ };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { appendInstructions } from "../../models/llm_request.js";
7
+ import { injectSessionState } from "../instructions.js";
8
+ import { isLlmAgent } from "../llm_agent.js";
9
+ import { ReadonlyContext } from "../readonly_context.js";
10
+ import { BaseLlmRequestProcessor } from "./base_llm_processor.js";
11
+ class InstructionsLlmRequestProcessor extends BaseLlmRequestProcessor {
12
+ /**
13
+ * Handles instructions and global instructions for LLM flow.
14
+ */
15
+ // eslint-disable-next-line require-yield
16
+ async *runAsync(invocationContext, llmRequest) {
17
+ const agent = invocationContext.agent;
18
+ if (!isLlmAgent(agent) || !isLlmAgent(agent.rootAgent)) {
19
+ return;
20
+ }
21
+ const rootAgent = agent.rootAgent;
22
+ if (isLlmAgent(rootAgent) && rootAgent.globalInstruction) {
23
+ const { instruction, requireStateInjection } = await rootAgent.canonicalGlobalInstruction(
24
+ new ReadonlyContext(invocationContext)
25
+ );
26
+ let instructionWithState = instruction;
27
+ if (requireStateInjection) {
28
+ instructionWithState = await injectSessionState(
29
+ instruction,
30
+ new ReadonlyContext(invocationContext)
31
+ );
32
+ }
33
+ appendInstructions(llmRequest, [instructionWithState]);
34
+ }
35
+ if (agent.instruction) {
36
+ const { instruction, requireStateInjection } = await agent.canonicalInstruction(
37
+ new ReadonlyContext(invocationContext)
38
+ );
39
+ let instructionWithState = instruction;
40
+ if (requireStateInjection) {
41
+ instructionWithState = await injectSessionState(
42
+ instruction,
43
+ new ReadonlyContext(invocationContext)
44
+ );
45
+ }
46
+ appendInstructions(llmRequest, [instructionWithState]);
47
+ }
48
+ }
49
+ }
50
+ const INSTRUCTIONS_LLM_REQUEST_PROCESSOR = new InstructionsLlmRequestProcessor();
51
+ export {
52
+ INSTRUCTIONS_LLM_REQUEST_PROCESSOR,
53
+ InstructionsLlmRequestProcessor
54
+ };