@google/adk 0.2.1 → 0.2.3

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 (84) hide show
  1. package/dist/cjs/agents/base_agent.js +14 -2
  2. package/dist/cjs/agents/content_processor_utils.js +12 -2
  3. package/dist/cjs/agents/functions.js +16 -3
  4. package/dist/cjs/agents/llm_agent.js +341 -4
  5. package/dist/cjs/{utils/deep_clone.js → auth/exchanger/base_credential_exchanger.js} +6 -10
  6. package/dist/cjs/auth/exchanger/credential_exchanger_registry.js +59 -0
  7. package/dist/cjs/code_executors/built_in_code_executor.js +1 -1
  8. package/dist/cjs/code_executors/code_execution_utils.js +12 -2
  9. package/dist/cjs/code_executors/code_executor_context.js +12 -2
  10. package/dist/cjs/common.js +10 -0
  11. package/dist/cjs/index.js +58 -5
  12. package/dist/cjs/index.js.map +4 -4
  13. package/dist/cjs/models/base_llm.js +16 -4
  14. package/dist/cjs/runner/runner.js +10 -1
  15. package/dist/cjs/sessions/in_memory_session_service.js +13 -3
  16. package/dist/cjs/sessions/state.js +1 -1
  17. package/dist/cjs/tools/agent_tool.js +2 -2
  18. package/dist/cjs/tools/mcp/mcp_session_manager.js +7 -1
  19. package/dist/cjs/utils/gemini_schema_util.js +16 -0
  20. package/dist/cjs/utils/model_name.js +24 -4
  21. package/dist/cjs/version.js +1 -1
  22. package/dist/esm/agents/base_agent.js +12 -1
  23. package/dist/esm/agents/content_processor_utils.js +2 -2
  24. package/dist/esm/agents/functions.js +6 -3
  25. package/dist/esm/agents/llm_agent.js +330 -4
  26. package/dist/esm/auth/exchanger/base_credential_exchanger.js +10 -0
  27. package/dist/esm/auth/exchanger/credential_exchanger_registry.js +29 -0
  28. package/dist/esm/code_executors/built_in_code_executor.js +2 -2
  29. package/dist/esm/code_executors/code_execution_utils.js +2 -2
  30. package/dist/esm/code_executors/code_executor_context.js +2 -2
  31. package/dist/esm/common.js +8 -2
  32. package/dist/esm/index.js +58 -5
  33. package/dist/esm/index.js.map +4 -4
  34. package/dist/esm/models/base_llm.js +14 -3
  35. package/dist/esm/runner/runner.js +10 -1
  36. package/dist/esm/sessions/in_memory_session_service.js +3 -3
  37. package/dist/esm/sessions/state.js +1 -1
  38. package/dist/esm/tools/agent_tool.js +2 -2
  39. package/dist/esm/tools/function_tool.js +3 -1
  40. package/dist/esm/tools/mcp/mcp_session_manager.js +7 -1
  41. package/dist/esm/utils/gemini_schema_util.js +16 -0
  42. package/dist/esm/utils/model_name.js +23 -3
  43. package/dist/esm/version.js +1 -1
  44. package/dist/types/agents/base_agent.d.ts +15 -0
  45. package/dist/types/agents/functions.d.ts +2 -0
  46. package/dist/types/agents/llm_agent.d.ts +23 -0
  47. package/dist/types/auth/exchanger/base_credential_exchanger.d.ts +32 -0
  48. package/dist/types/auth/exchanger/credential_exchanger_registry.d.ts +28 -0
  49. package/dist/types/code_executors/code_executor_context.d.ts +0 -5
  50. package/dist/types/common.d.ts +4 -2
  51. package/dist/types/models/base_llm.d.ts +16 -0
  52. package/dist/types/sessions/in_memory_session_service.d.ts +0 -5
  53. package/dist/types/sessions/state.d.ts +2 -2
  54. package/dist/types/tools/function_tool.d.ts +3 -3
  55. package/dist/types/tools/tool_confirmation.d.ts +1 -1
  56. package/dist/types/utils/gemini_schema_util.d.ts +2 -2
  57. package/dist/types/utils/model_name.d.ts +1 -1
  58. package/dist/types/version.d.ts +1 -1
  59. package/dist/web/agents/base_agent.js +12 -1
  60. package/dist/web/agents/content_processor_utils.js +2 -2
  61. package/dist/web/agents/functions.js +6 -3
  62. package/dist/web/agents/llm_agent.js +315 -4
  63. package/dist/web/auth/exchanger/base_credential_exchanger.js +10 -0
  64. package/dist/web/auth/exchanger/credential_exchanger_registry.js +29 -0
  65. package/dist/web/code_executors/built_in_code_executor.js +2 -2
  66. package/dist/web/code_executors/code_execution_utils.js +2 -2
  67. package/dist/web/code_executors/code_executor_context.js +2 -2
  68. package/dist/web/common.js +8 -2
  69. package/dist/web/index.js +1 -1
  70. package/dist/web/index.js.map +4 -4
  71. package/dist/web/models/base_llm.js +14 -3
  72. package/dist/web/runner/runner.js +10 -1
  73. package/dist/web/sessions/in_memory_session_service.js +3 -3
  74. package/dist/web/sessions/state.js +1 -1
  75. package/dist/web/tools/agent_tool.js +2 -2
  76. package/dist/web/tools/function_tool.js +3 -1
  77. package/dist/web/tools/mcp/mcp_session_manager.js +7 -1
  78. package/dist/web/utils/gemini_schema_util.js +16 -0
  79. package/dist/web/utils/model_name.js +23 -3
  80. package/dist/web/version.js +1 -1
  81. package/package.json +3 -1
  82. package/dist/esm/utils/deep_clone.js +0 -14
  83. package/dist/types/utils/deep_clone.d.ts +0 -1
  84. package/dist/web/utils/deep_clone.js +0 -14
@@ -3,15 +3,23 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
+ import cloneDeep from "lodash-es/cloneDeep.js";
6
7
  import { z } from "zod";
8
+ import { BaseCodeExecutor } from "../code_executors/base_code_executor.js";
9
+ import { BuiltInCodeExecutor } from "../code_executors/built_in_code_executor.js";
10
+ import { buildCodeExecutionResultPart, buildExecutableCodePart, convertCodeExecutionParts, extractCodeAndTruncateContent } from "../code_executors/code_execution_utils.js";
11
+ import { CodeExecutorContext } from "../code_executors/code_executor_context.js";
7
12
  import { createEvent, createNewEventId, getFunctionCalls, getFunctionResponses, isFinalResponse } from "../events/event.js";
8
- import { BaseLlm } from "../models/base_llm.js";
13
+ import { createEventActions } from "../events/event_actions.js";
14
+ import { isBaseLlm } from "../models/base_llm.js";
9
15
  import { appendInstructions, setOutputSchema } from "../models/llm_request.js";
10
16
  import { LLMRegistry } from "../models/registry.js";
17
+ import { State } from "../sessions/state.js";
11
18
  import { BaseTool } from "../tools/base_tool.js";
12
19
  import { FunctionTool } from "../tools/function_tool.js";
13
20
  import { ToolConfirmation } from "../tools/tool_confirmation.js";
14
21
  import { ToolContext } from "../tools/tool_context.js";
22
+ import { base64Decode } from "../utils/env_aware_utils.js";
15
23
  import { logger } from "../utils/logger.js";
16
24
  import { BaseAgent } from "./base_agent.js";
17
25
  import { BaseLlmRequestProcessor } from "./base_llm_processor.js";
@@ -323,6 +331,321 @@ class RequestConfirmationLlmRequestProcessor extends BaseLlmRequestProcessor {
323
331
  }
324
332
  }
325
333
  const REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR = new RequestConfirmationLlmRequestProcessor();
334
+ class CodeExecutionRequestProcessor extends BaseLlmRequestProcessor {
335
+ async *runAsync(invocationContext, llmRequest) {
336
+ if (!(invocationContext.agent instanceof LlmAgent)) {
337
+ return;
338
+ }
339
+ if (!invocationContext.agent.codeExecutor) {
340
+ return;
341
+ }
342
+ for await (const event of runPreProcessor(invocationContext, llmRequest)) {
343
+ yield event;
344
+ }
345
+ if (!(invocationContext.agent.codeExecutor instanceof BaseCodeExecutor)) {
346
+ return;
347
+ }
348
+ for (const content of llmRequest.contents) {
349
+ const delimeters = invocationContext.agent.codeExecutor.codeBlockDelimiters.length ? invocationContext.agent.codeExecutor.codeBlockDelimiters[0] : ["", ""];
350
+ const codeExecutionParts = convertCodeExecutionParts(
351
+ content,
352
+ delimeters,
353
+ invocationContext.agent.codeExecutor.executionResultDelimiters
354
+ );
355
+ }
356
+ }
357
+ }
358
+ const DATA_FILE_UTIL_MAP = {
359
+ "text/csv": {
360
+ extension: ".csv",
361
+ loaderCodeTemplate: "pd.read_csv('{filename}')"
362
+ }
363
+ };
364
+ const DATA_FILE_HELPER_LIB = `
365
+ import pandas as pd
366
+
367
+ def explore_df(df: pd.DataFrame) -> None:
368
+ """Prints some information about a pandas DataFrame."""
369
+
370
+ with pd.option_context(
371
+ 'display.max_columns', None, 'display.expand_frame_repr', False
372
+ ):
373
+ # Print the column names to never encounter KeyError when selecting one.
374
+ df_dtypes = df.dtypes
375
+
376
+ # Obtain information about data types and missing values.
377
+ df_nulls = (len(df) - df.isnull().sum()).apply(
378
+ lambda x: f'{x} / {df.shape[0]} non-null'
379
+ )
380
+
381
+ # Explore unique total values in columns using \`.unique()\`.
382
+ df_unique_count = df.apply(lambda x: len(x.unique()))
383
+
384
+ # Explore unique values in columns using \`.unique()\`.
385
+ df_unique = df.apply(lambda x: crop(str(list(x.unique()))))
386
+
387
+ df_info = pd.concat(
388
+ (
389
+ df_dtypes.rename('Dtype'),
390
+ df_nulls.rename('Non-Null Count'),
391
+ df_unique_count.rename('Unique Values Count'),
392
+ df_unique.rename('Unique Values'),
393
+ ),
394
+ axis=1,
395
+ )
396
+ df_info.index.name = 'Columns'
397
+ print(f"""Total rows: {df.shape[0]}
398
+ Total columns: {df.shape[1]}
399
+
400
+ {df_info}""")
401
+ `;
402
+ class CodeExecutionResponseProcessor {
403
+ /**
404
+ * Processes the LLM response asynchronously.
405
+ *
406
+ * @param invocationContext The invocation context
407
+ * @param llmResponse The LLM response to process
408
+ * @returns An async generator yielding events
409
+ */
410
+ async *runAsync(invocationContext, llmResponse) {
411
+ if (llmResponse.partial) {
412
+ return;
413
+ }
414
+ for await (const event of runPostProcessor(invocationContext, llmResponse)) {
415
+ yield event;
416
+ }
417
+ }
418
+ }
419
+ const responseProcessor = new CodeExecutionResponseProcessor();
420
+ async function* runPreProcessor(invocationContext, llmRequest) {
421
+ const agent = invocationContext.agent;
422
+ if (!(agent instanceof LlmAgent)) {
423
+ return;
424
+ }
425
+ const codeExecutor = agent.codeExecutor;
426
+ if (!codeExecutor || !(codeExecutor instanceof BaseCodeExecutor)) {
427
+ return;
428
+ }
429
+ if (codeExecutor instanceof BuiltInCodeExecutor) {
430
+ codeExecutor.processLlmRequest(llmRequest);
431
+ return;
432
+ }
433
+ if (!codeExecutor.optimizeDataFile) {
434
+ return;
435
+ }
436
+ const codeExecutorContext = new CodeExecutorContext(new State(invocationContext.session.state));
437
+ if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >= codeExecutor.errorRetryAttempts) {
438
+ return;
439
+ }
440
+ const allInputFiles = extractAndReplaceInlineFiles(codeExecutorContext, llmRequest);
441
+ const processedFileNames = new Set(codeExecutorContext.getProcessedFileNames());
442
+ const filesToProcess = allInputFiles.filter((f) => !processedFileNames.has(f.name));
443
+ for (const file of filesToProcess) {
444
+ const codeStr = getDataFilePreprocessingCode(file);
445
+ if (!codeStr) {
446
+ return;
447
+ }
448
+ const codeContent = {
449
+ role: "model",
450
+ parts: [
451
+ { text: `Processing input file: \`${file.name}\`` },
452
+ buildExecutableCodePart(codeStr)
453
+ ]
454
+ };
455
+ llmRequest.contents.push(cloneDeep(codeContent));
456
+ yield createEvent({
457
+ invocationId: invocationContext.invocationId,
458
+ author: agent.name,
459
+ branch: invocationContext.branch,
460
+ content: codeContent
461
+ });
462
+ const executionId = getOrSetExecutionId(invocationContext, codeExecutorContext);
463
+ const codeExecutionResult = await codeExecutor.executeCode({
464
+ invocationContext,
465
+ codeExecutionInput: {
466
+ code: codeStr,
467
+ inputFiles: [file],
468
+ executionId
469
+ }
470
+ });
471
+ codeExecutorContext.updateCodeExecutionResult({
472
+ invocationId: invocationContext.invocationId,
473
+ code: codeStr,
474
+ resultStdout: codeExecutionResult.stdout,
475
+ resultStderr: codeExecutionResult.stderr
476
+ });
477
+ codeExecutorContext.addProcessedFileNames([file.name]);
478
+ const executionResultEvent = await postProcessCodeExecutionResult(
479
+ invocationContext,
480
+ codeExecutorContext,
481
+ codeExecutionResult
482
+ );
483
+ yield executionResultEvent;
484
+ llmRequest.contents.push(cloneDeep(executionResultEvent.content));
485
+ }
486
+ }
487
+ async function* runPostProcessor(invocationContext, llmResponse) {
488
+ const agent = invocationContext.agent;
489
+ if (!(agent instanceof LlmAgent)) {
490
+ return;
491
+ }
492
+ const codeExecutor = agent.codeExecutor;
493
+ if (!codeExecutor || !(codeExecutor instanceof BaseCodeExecutor)) {
494
+ return;
495
+ }
496
+ if (!llmResponse || !llmResponse.content) {
497
+ return;
498
+ }
499
+ if (codeExecutor instanceof BuiltInCodeExecutor) {
500
+ return;
501
+ }
502
+ const codeExecutorContext = new CodeExecutorContext(new State(invocationContext.session.state));
503
+ if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >= codeExecutor.errorRetryAttempts) {
504
+ return;
505
+ }
506
+ const responseContent = llmResponse.content;
507
+ const codeStr = extractCodeAndTruncateContent(
508
+ responseContent,
509
+ codeExecutor.codeBlockDelimiters
510
+ );
511
+ if (!codeStr) {
512
+ return;
513
+ }
514
+ yield createEvent({
515
+ invocationId: invocationContext.invocationId,
516
+ author: agent.name,
517
+ branch: invocationContext.branch,
518
+ content: responseContent
519
+ });
520
+ const executionId = getOrSetExecutionId(invocationContext, codeExecutorContext);
521
+ const codeExecutionResult = await codeExecutor.executeCode({
522
+ invocationContext,
523
+ codeExecutionInput: {
524
+ code: codeStr,
525
+ inputFiles: codeExecutorContext.getInputFiles(),
526
+ executionId
527
+ }
528
+ });
529
+ codeExecutorContext.updateCodeExecutionResult({
530
+ invocationId: invocationContext.invocationId,
531
+ code: codeStr,
532
+ resultStdout: codeExecutionResult.stdout,
533
+ resultStderr: codeExecutionResult.stderr
534
+ });
535
+ yield await postProcessCodeExecutionResult(
536
+ invocationContext,
537
+ codeExecutorContext,
538
+ codeExecutionResult
539
+ );
540
+ llmResponse.content = null;
541
+ }
542
+ function extractAndReplaceInlineFiles(codeExecutorContext, llmRequest) {
543
+ var _a;
544
+ const allInputFiles = codeExecutorContext.getInputFiles();
545
+ const savedFileNames = new Set(allInputFiles.map((f) => f.name));
546
+ for (let i = 0; i < llmRequest.contents.length; i++) {
547
+ const content = llmRequest.contents[i];
548
+ if (content.role !== "user" || !content.parts) {
549
+ continue;
550
+ }
551
+ for (let j = 0; j < content.parts.length; j++) {
552
+ const part = content.parts[j];
553
+ const mimeType = (_a = part.inlineData) == null ? void 0 : _a.mimeType;
554
+ if (!mimeType || !part.inlineData || !DATA_FILE_UTIL_MAP[mimeType]) {
555
+ continue;
556
+ }
557
+ const fileName = `data_${i + 1}_${j + 1}${DATA_FILE_UTIL_MAP[mimeType].extension}`;
558
+ part.text = `
559
+ Available file: \`${fileName}\`
560
+ `;
561
+ const file = {
562
+ name: fileName,
563
+ content: base64Decode(part.inlineData.data),
564
+ mimeType
565
+ };
566
+ if (!savedFileNames.has(fileName)) {
567
+ codeExecutorContext.addInputFiles([file]);
568
+ allInputFiles.push(file);
569
+ }
570
+ }
571
+ }
572
+ return allInputFiles;
573
+ }
574
+ function getOrSetExecutionId(invocationContext, codeExecutorContext) {
575
+ var _a;
576
+ const agent = invocationContext.agent;
577
+ if (!(agent instanceof LlmAgent) || !((_a = agent.codeExecutor) == null ? void 0 : _a.stateful)) {
578
+ return void 0;
579
+ }
580
+ let executionId = codeExecutorContext.getExecutionId();
581
+ if (!executionId) {
582
+ executionId = invocationContext.session.id;
583
+ codeExecutorContext.setExecutionId(executionId);
584
+ }
585
+ return executionId;
586
+ }
587
+ async function postProcessCodeExecutionResult(invocationContext, codeExecutorContext, codeExecutionResult) {
588
+ if (!invocationContext.artifactService) {
589
+ throw new Error("Artifact service is not initialized.");
590
+ }
591
+ const resultContent = {
592
+ role: "model",
593
+ parts: [buildCodeExecutionResultPart(codeExecutionResult)]
594
+ };
595
+ const eventActions = createEventActions({ stateDelta: codeExecutorContext.getStateDelta() });
596
+ if (codeExecutionResult.stderr) {
597
+ codeExecutorContext.incrementErrorCount(invocationContext.invocationId);
598
+ } else {
599
+ codeExecutorContext.resetErrorCount(invocationContext.invocationId);
600
+ }
601
+ for (const outputFile of codeExecutionResult.outputFiles) {
602
+ const version = await invocationContext.artifactService.saveArtifact({
603
+ appName: invocationContext.appName || "",
604
+ userId: invocationContext.userId || "",
605
+ sessionId: invocationContext.session.id,
606
+ filename: outputFile.name,
607
+ artifact: {
608
+ inlineData: { data: outputFile.content, mimeType: outputFile.mimeType }
609
+ }
610
+ });
611
+ eventActions.artifactDelta[outputFile.name] = version;
612
+ }
613
+ return createEvent({
614
+ invocationId: invocationContext.invocationId,
615
+ author: invocationContext.agent.name,
616
+ branch: invocationContext.branch,
617
+ content: resultContent,
618
+ actions: eventActions
619
+ });
620
+ }
621
+ function getDataFilePreprocessingCode(file) {
622
+ function getNormalizedFileName(fileName) {
623
+ const [varName2] = fileName.split(".");
624
+ let normalizedName = varName2.replace(/[^a-zA-Z0-9_]/g, "_");
625
+ if (/^\d/.test(normalizedName)) {
626
+ normalizedName = "_" + normalizedName;
627
+ }
628
+ return normalizedName;
629
+ }
630
+ if (!DATA_FILE_UTIL_MAP[file.mimeType]) {
631
+ return void 0;
632
+ }
633
+ const varName = getNormalizedFileName(file.name);
634
+ const loaderCode = DATA_FILE_UTIL_MAP[file.mimeType].loaderCodeTemplate.replace(
635
+ "{filename}",
636
+ file.name
637
+ );
638
+ return `
639
+ ${DATA_FILE_HELPER_LIB}
640
+
641
+ # Load the dataframe.
642
+ ${varName} = ${loaderCode}
643
+
644
+ # Use \`explore_df\` to guide my analysis.
645
+ explore_df(${varName})
646
+ `;
647
+ }
648
+ const CODE_EXECUTION_REQUEST_PROCESSOR = new CodeExecutionRequestProcessor();
326
649
  class LlmAgent extends BaseAgent {
327
650
  constructor(config) {
328
651
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
@@ -342,12 +665,14 @@ class LlmAgent extends BaseAgent {
342
665
  this.afterModelCallback = config.afterModelCallback;
343
666
  this.beforeToolCallback = config.beforeToolCallback;
344
667
  this.afterToolCallback = config.afterToolCallback;
668
+ this.codeExecutor = config.codeExecutor;
345
669
  this.requestProcessors = (_g = config.requestProcessors) != null ? _g : [
346
670
  BASIC_LLM_REQUEST_PROCESSOR,
347
671
  IDENTITY_LLM_REQUEST_PROCESSOR,
348
672
  INSTRUCTIONS_LLM_REQUEST_PROCESSOR,
349
673
  REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR,
350
- CONTENT_REQUEST_PROCESSOR
674
+ CONTENT_REQUEST_PROCESSOR,
675
+ CODE_EXECUTION_REQUEST_PROCESSOR
351
676
  ];
352
677
  this.responseProcessors = (_h = config.responseProcessors) != null ? _h : [];
353
678
  const agentTransferDisabled = this.disallowTransferToParent && this.disallowTransferToPeers && !((_i = this.subAgents) == null ? void 0 : _i.length);
@@ -397,7 +722,7 @@ class LlmAgent extends BaseAgent {
397
722
  * When not set, the agent will inherit the model from its ancestor.
398
723
  */
399
724
  get canonicalModel() {
400
- if (this.model instanceof BaseLlm) {
725
+ if (isBaseLlm(this.model)) {
401
726
  return this.model;
402
727
  }
403
728
  if (typeof this.model === "string" && this.model) {
@@ -830,5 +1155,6 @@ class LlmAgent extends BaseAgent {
830
1155
  }
831
1156
  export {
832
1157
  LlmAgent,
833
- REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR
1158
+ REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR,
1159
+ responseProcessor
834
1160
  };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ class CredentialExchangeError extends Error {
7
+ }
8
+ export {
9
+ CredentialExchangeError
10
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ class CredentialExchangerRegistry {
7
+ constructor() {
8
+ this.exchangers = {};
9
+ }
10
+ /**
11
+ * Register an exchanger instance for a credential type.
12
+ * @param credentialType - The credential type to register for.
13
+ * @param exchangerInstance - The exchanger instance to register.
14
+ */
15
+ register(credentialType, exchangerInstance) {
16
+ this.exchangers[credentialType] = exchangerInstance;
17
+ }
18
+ /**
19
+ * Get the exchanger instance for a credential type.
20
+ * @param credentialType - The credential type to get exchanger for.
21
+ * @returns The exchanger instance if registered, undefined otherwise.
22
+ */
23
+ getExchanger(credentialType) {
24
+ return this.exchangers[credentialType];
25
+ }
26
+ }
27
+ export {
28
+ CredentialExchangerRegistry
29
+ };
@@ -3,7 +3,7 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { isGemini2Model } from "../utils/model_name.js";
6
+ import { isGemini2OrAbove } from "../utils/model_name.js";
7
7
  import { BaseCodeExecutor } from "./base_code_executor.js";
8
8
  class BuiltInCodeExecutor extends BaseCodeExecutor {
9
9
  executeCode(params) {
@@ -14,7 +14,7 @@ class BuiltInCodeExecutor extends BaseCodeExecutor {
14
14
  });
15
15
  }
16
16
  processLlmRequest(llmRequest) {
17
- if (llmRequest.model && isGemini2Model(llmRequest.model)) {
17
+ if (llmRequest.model && isGemini2OrAbove(llmRequest.model)) {
18
18
  llmRequest.config = llmRequest.config || {};
19
19
  llmRequest.config.tools = llmRequest.config.tools || [];
20
20
  llmRequest.config.tools.push({ codeExecution: {} });
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { Language, Outcome } from "@google/genai";
7
- import { deepClone } from "../utils/deep_clone.js";
7
+ import cloneDeep from "lodash-es/cloneDeep.js";
8
8
  import { base64Encode, isBase64Encoded } from "../utils/env_aware_utils.js";
9
9
  function getEncodedFileContent(data) {
10
10
  return isBase64Encoded(data) ? data : base64Encode(data);
@@ -25,7 +25,7 @@ function extractCodeAndTruncateContent(content, codeBlockDelimiters) {
25
25
  if (!textParts.length) {
26
26
  return "";
27
27
  }
28
- const firstTextPart = deepClone(textParts[0]);
28
+ const firstTextPart = cloneDeep(textParts[0]);
29
29
  const responseText = textParts.map((part) => part.text).join("\n");
30
30
  const leadingDelimiterPattern = codeBlockDelimiters.map((d) => d[0]).join("|");
31
31
  const trailingDelimiterPattern = codeBlockDelimiters.map((d) => d[1]).join("|");
@@ -3,7 +3,7 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { deepClone } from "../utils/deep_clone.js";
6
+ import cloneDeep from "lodash-es/cloneDeep.js";
7
7
  const CONTEXT_KEY = "_code_execution_context";
8
8
  const SESSION_ID_KEY = "execution_session_id";
9
9
  const PROCESSED_FILE_NAMES_KEY = "processed_input_files";
@@ -23,7 +23,7 @@ class CodeExecutorContext {
23
23
  */
24
24
  getStateDelta() {
25
25
  return {
26
- [CONTEXT_KEY]: deepClone(this.context)
26
+ [CONTEXT_KEY]: cloneDeep(this.context)
27
27
  };
28
28
  }
29
29
  /**
@@ -3,7 +3,7 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { BaseAgent } from "./agents/base_agent.js";
6
+ import { BaseAgent, isBaseAgent } from "./agents/base_agent.js";
7
7
  import { CallbackContext } from "./agents/callback_context.js";
8
8
  import { functionsExportedForTestingOnly } from "./agents/functions.js";
9
9
  import { InvocationContext } from "./agents/invocation_context.js";
@@ -14,10 +14,11 @@ import { ParallelAgent } from "./agents/parallel_agent.js";
14
14
  import { StreamingMode } from "./agents/run_config.js";
15
15
  import { SequentialAgent } from "./agents/sequential_agent.js";
16
16
  import { InMemoryArtifactService } from "./artifacts/in_memory_artifact_service.js";
17
+ import { BuiltInCodeExecutor } from "./code_executors/built_in_code_executor.js";
17
18
  import { createEvent, getFunctionCalls, getFunctionResponses, hasTrailingCodeExecutionResult, isFinalResponse, stringifyContent } from "./events/event.js";
18
19
  import { createEventActions } from "./events/event_actions.js";
19
20
  import { InMemoryMemoryService } from "./memory/in_memory_memory_service.js";
20
- import { BaseLlm } from "./models/base_llm.js";
21
+ import { BaseLlm, isBaseLlm } from "./models/base_llm.js";
21
22
  import { Gemini } from "./models/google_llm.js";
22
23
  import { LLMRegistry } from "./models/registry.js";
23
24
  import { BasePlugin } from "./plugins/base_plugin.js";
@@ -38,6 +39,7 @@ import { LongRunningFunctionTool } from "./tools/long_running_tool.js";
38
39
  import { ToolConfirmation } from "./tools/tool_confirmation.js";
39
40
  import { ToolContext } from "./tools/tool_context.js";
40
41
  import { LogLevel, setLogLevel } from "./utils/logger.js";
42
+ import { isGemini2OrAbove } from "./utils/model_name.js";
41
43
  import { zodObjectToSchema } from "./utils/simple_zod_to_json.js";
42
44
  import { version } from "./version.js";
43
45
  export * from "./artifacts/base_artifact_service.js";
@@ -51,6 +53,7 @@ export {
51
53
  BasePlugin,
52
54
  BaseTool,
53
55
  BaseToolset,
56
+ BuiltInCodeExecutor,
54
57
  CallbackContext,
55
58
  FunctionTool,
56
59
  GOOGLE_SEARCH,
@@ -87,7 +90,10 @@ export {
87
90
  getFunctionCalls,
88
91
  getFunctionResponses,
89
92
  hasTrailingCodeExecutionResult,
93
+ isBaseAgent,
94
+ isBaseLlm,
90
95
  isFinalResponse,
96
+ isGemini2OrAbove,
91
97
  setLogLevel,
92
98
  stringifyContent,
93
99
  version,