@paean-ai/adk 0.2.1 → 0.2.2

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.
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
- # @google/adk
1
+ # @paean-ai/adk
2
2
 
3
3
  Please see README for adk-js at https://github.com/google/adk-js
@@ -25,18 +25,27 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
25
25
  var llm_agent_exports = {};
26
26
  __export(llm_agent_exports, {
27
27
  LlmAgent: () => LlmAgent,
28
- REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR: () => REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR
28
+ REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR: () => REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR,
29
+ responseProcessor: () => responseProcessor
29
30
  });
30
31
  module.exports = __toCommonJS(llm_agent_exports);
31
32
  var import_zod = require("zod");
33
+ var import_base_code_executor = require("../code_executors/base_code_executor.js");
34
+ var import_built_in_code_executor = require("../code_executors/built_in_code_executor.js");
35
+ var import_code_execution_utils = require("../code_executors/code_execution_utils.js");
36
+ var import_code_executor_context = require("../code_executors/code_executor_context.js");
32
37
  var import_event = require("../events/event.js");
38
+ var import_event_actions = require("../events/event_actions.js");
33
39
  var import_base_llm = require("../models/base_llm.js");
34
40
  var import_llm_request = require("../models/llm_request.js");
35
41
  var import_registry = require("../models/registry.js");
42
+ var import_state = require("../sessions/state.js");
36
43
  var import_base_tool = require("../tools/base_tool.js");
37
44
  var import_function_tool = require("../tools/function_tool.js");
38
45
  var import_tool_confirmation = require("../tools/tool_confirmation.js");
39
46
  var import_tool_context = require("../tools/tool_context.js");
47
+ var import_deep_clone = require("../utils/deep_clone.js");
48
+ var import_env_aware_utils = require("../utils/env_aware_utils.js");
40
49
  var import_logger = require("../utils/logger.js");
41
50
  var import_base_agent = require("./base_agent.js");
42
51
  var import_base_llm_processor = require("./base_llm_processor.js");
@@ -353,6 +362,321 @@ class RequestConfirmationLlmRequestProcessor extends import_base_llm_processor.B
353
362
  }
354
363
  }
355
364
  const REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR = new RequestConfirmationLlmRequestProcessor();
365
+ class CodeExecutionRequestProcessor extends import_base_llm_processor.BaseLlmRequestProcessor {
366
+ async *runAsync(invocationContext, llmRequest) {
367
+ if (!(invocationContext.agent instanceof LlmAgent)) {
368
+ return;
369
+ }
370
+ if (!invocationContext.agent.codeExecutor) {
371
+ return;
372
+ }
373
+ for await (const event of runPreProcessor(invocationContext, llmRequest)) {
374
+ yield event;
375
+ }
376
+ if (!(invocationContext.agent.codeExecutor instanceof import_base_code_executor.BaseCodeExecutor)) {
377
+ return;
378
+ }
379
+ for (const content of llmRequest.contents) {
380
+ const delimeters = invocationContext.agent.codeExecutor.codeBlockDelimiters.length ? invocationContext.agent.codeExecutor.codeBlockDelimiters[0] : ["", ""];
381
+ const codeExecutionParts = (0, import_code_execution_utils.convertCodeExecutionParts)(
382
+ content,
383
+ delimeters,
384
+ invocationContext.agent.codeExecutor.executionResultDelimiters
385
+ );
386
+ }
387
+ }
388
+ }
389
+ const DATA_FILE_UTIL_MAP = {
390
+ "text/csv": {
391
+ extension: ".csv",
392
+ loaderCodeTemplate: "pd.read_csv('{filename}')"
393
+ }
394
+ };
395
+ const DATA_FILE_HELPER_LIB = `
396
+ import pandas as pd
397
+
398
+ def explore_df(df: pd.DataFrame) -> None:
399
+ """Prints some information about a pandas DataFrame."""
400
+
401
+ with pd.option_context(
402
+ 'display.max_columns', None, 'display.expand_frame_repr', False
403
+ ):
404
+ # Print the column names to never encounter KeyError when selecting one.
405
+ df_dtypes = df.dtypes
406
+
407
+ # Obtain information about data types and missing values.
408
+ df_nulls = (len(df) - df.isnull().sum()).apply(
409
+ lambda x: f'{x} / {df.shape[0]} non-null'
410
+ )
411
+
412
+ # Explore unique total values in columns using \`.unique()\`.
413
+ df_unique_count = df.apply(lambda x: len(x.unique()))
414
+
415
+ # Explore unique values in columns using \`.unique()\`.
416
+ df_unique = df.apply(lambda x: crop(str(list(x.unique()))))
417
+
418
+ df_info = pd.concat(
419
+ (
420
+ df_dtypes.rename('Dtype'),
421
+ df_nulls.rename('Non-Null Count'),
422
+ df_unique_count.rename('Unique Values Count'),
423
+ df_unique.rename('Unique Values'),
424
+ ),
425
+ axis=1,
426
+ )
427
+ df_info.index.name = 'Columns'
428
+ print(f"""Total rows: {df.shape[0]}
429
+ Total columns: {df.shape[1]}
430
+
431
+ {df_info}""")
432
+ `;
433
+ class CodeExecutionResponseProcessor {
434
+ /**
435
+ * Processes the LLM response asynchronously.
436
+ *
437
+ * @param invocationContext The invocation context
438
+ * @param llmResponse The LLM response to process
439
+ * @returns An async generator yielding events
440
+ */
441
+ async *runAsync(invocationContext, llmResponse) {
442
+ if (llmResponse.partial) {
443
+ return;
444
+ }
445
+ for await (const event of runPostProcessor(invocationContext, llmResponse)) {
446
+ yield event;
447
+ }
448
+ }
449
+ }
450
+ const responseProcessor = new CodeExecutionResponseProcessor();
451
+ async function* runPreProcessor(invocationContext, llmRequest) {
452
+ const agent = invocationContext.agent;
453
+ if (!(agent instanceof LlmAgent)) {
454
+ return;
455
+ }
456
+ const codeExecutor = agent.codeExecutor;
457
+ if (!codeExecutor || !(codeExecutor instanceof import_base_code_executor.BaseCodeExecutor)) {
458
+ return;
459
+ }
460
+ if (codeExecutor instanceof import_built_in_code_executor.BuiltInCodeExecutor) {
461
+ codeExecutor.processLlmRequest(llmRequest);
462
+ return;
463
+ }
464
+ if (!codeExecutor.optimizeDataFile) {
465
+ return;
466
+ }
467
+ const codeExecutorContext = new import_code_executor_context.CodeExecutorContext(new import_state.State(invocationContext.session.state));
468
+ if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >= codeExecutor.errorRetryAttempts) {
469
+ return;
470
+ }
471
+ const allInputFiles = extractAndReplaceInlineFiles(codeExecutorContext, llmRequest);
472
+ const processedFileNames = new Set(codeExecutorContext.getProcessedFileNames());
473
+ const filesToProcess = allInputFiles.filter((f) => !processedFileNames.has(f.name));
474
+ for (const file of filesToProcess) {
475
+ const codeStr = getDataFilePreprocessingCode(file);
476
+ if (!codeStr) {
477
+ return;
478
+ }
479
+ const codeContent = {
480
+ role: "model",
481
+ parts: [
482
+ { text: `Processing input file: \`${file.name}\`` },
483
+ (0, import_code_execution_utils.buildExecutableCodePart)(codeStr)
484
+ ]
485
+ };
486
+ llmRequest.contents.push((0, import_deep_clone.deepClone)(codeContent));
487
+ yield (0, import_event.createEvent)({
488
+ invocationId: invocationContext.invocationId,
489
+ author: agent.name,
490
+ branch: invocationContext.branch,
491
+ content: codeContent
492
+ });
493
+ const executionId = getOrSetExecutionId(invocationContext, codeExecutorContext);
494
+ const codeExecutionResult = await codeExecutor.executeCode({
495
+ invocationContext,
496
+ codeExecutionInput: {
497
+ code: codeStr,
498
+ inputFiles: [file],
499
+ executionId
500
+ }
501
+ });
502
+ codeExecutorContext.updateCodeExecutionResult({
503
+ invocationId: invocationContext.invocationId,
504
+ code: codeStr,
505
+ resultStdout: codeExecutionResult.stdout,
506
+ resultStderr: codeExecutionResult.stderr
507
+ });
508
+ codeExecutorContext.addProcessedFileNames([file.name]);
509
+ const executionResultEvent = await postProcessCodeExecutionResult(
510
+ invocationContext,
511
+ codeExecutorContext,
512
+ codeExecutionResult
513
+ );
514
+ yield executionResultEvent;
515
+ llmRequest.contents.push((0, import_deep_clone.deepClone)(executionResultEvent.content));
516
+ }
517
+ }
518
+ async function* runPostProcessor(invocationContext, llmResponse) {
519
+ const agent = invocationContext.agent;
520
+ if (!(agent instanceof LlmAgent)) {
521
+ return;
522
+ }
523
+ const codeExecutor = agent.codeExecutor;
524
+ if (!codeExecutor || !(codeExecutor instanceof import_base_code_executor.BaseCodeExecutor)) {
525
+ return;
526
+ }
527
+ if (!llmResponse || !llmResponse.content) {
528
+ return;
529
+ }
530
+ if (codeExecutor instanceof import_built_in_code_executor.BuiltInCodeExecutor) {
531
+ return;
532
+ }
533
+ const codeExecutorContext = new import_code_executor_context.CodeExecutorContext(new import_state.State(invocationContext.session.state));
534
+ if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >= codeExecutor.errorRetryAttempts) {
535
+ return;
536
+ }
537
+ const responseContent = llmResponse.content;
538
+ const codeStr = (0, import_code_execution_utils.extractCodeAndTruncateContent)(
539
+ responseContent,
540
+ codeExecutor.codeBlockDelimiters
541
+ );
542
+ if (!codeStr) {
543
+ return;
544
+ }
545
+ yield (0, import_event.createEvent)({
546
+ invocationId: invocationContext.invocationId,
547
+ author: agent.name,
548
+ branch: invocationContext.branch,
549
+ content: responseContent
550
+ });
551
+ const executionId = getOrSetExecutionId(invocationContext, codeExecutorContext);
552
+ const codeExecutionResult = await codeExecutor.executeCode({
553
+ invocationContext,
554
+ codeExecutionInput: {
555
+ code: codeStr,
556
+ inputFiles: codeExecutorContext.getInputFiles(),
557
+ executionId
558
+ }
559
+ });
560
+ codeExecutorContext.updateCodeExecutionResult({
561
+ invocationId: invocationContext.invocationId,
562
+ code: codeStr,
563
+ resultStdout: codeExecutionResult.stdout,
564
+ resultStderr: codeExecutionResult.stderr
565
+ });
566
+ yield await postProcessCodeExecutionResult(
567
+ invocationContext,
568
+ codeExecutorContext,
569
+ codeExecutionResult
570
+ );
571
+ llmResponse.content = null;
572
+ }
573
+ function extractAndReplaceInlineFiles(codeExecutorContext, llmRequest) {
574
+ var _a;
575
+ const allInputFiles = codeExecutorContext.getInputFiles();
576
+ const savedFileNames = new Set(allInputFiles.map((f) => f.name));
577
+ for (let i = 0; i < llmRequest.contents.length; i++) {
578
+ const content = llmRequest.contents[i];
579
+ if (content.role !== "user" || !content.parts) {
580
+ continue;
581
+ }
582
+ for (let j = 0; j < content.parts.length; j++) {
583
+ const part = content.parts[j];
584
+ const mimeType = (_a = part.inlineData) == null ? void 0 : _a.mimeType;
585
+ if (!mimeType || !part.inlineData || !DATA_FILE_UTIL_MAP[mimeType]) {
586
+ continue;
587
+ }
588
+ const fileName = `data_${i + 1}_${j + 1}${DATA_FILE_UTIL_MAP[mimeType].extension}`;
589
+ part.text = `
590
+ Available file: \`${fileName}\`
591
+ `;
592
+ const file = {
593
+ name: fileName,
594
+ content: (0, import_env_aware_utils.base64Decode)(part.inlineData.data),
595
+ mimeType
596
+ };
597
+ if (!savedFileNames.has(fileName)) {
598
+ codeExecutorContext.addInputFiles([file]);
599
+ allInputFiles.push(file);
600
+ }
601
+ }
602
+ }
603
+ return allInputFiles;
604
+ }
605
+ function getOrSetExecutionId(invocationContext, codeExecutorContext) {
606
+ var _a;
607
+ const agent = invocationContext.agent;
608
+ if (!(agent instanceof LlmAgent) || !((_a = agent.codeExecutor) == null ? void 0 : _a.stateful)) {
609
+ return void 0;
610
+ }
611
+ let executionId = codeExecutorContext.getExecutionId();
612
+ if (!executionId) {
613
+ executionId = invocationContext.session.id;
614
+ codeExecutorContext.setExecutionId(executionId);
615
+ }
616
+ return executionId;
617
+ }
618
+ async function postProcessCodeExecutionResult(invocationContext, codeExecutorContext, codeExecutionResult) {
619
+ if (!invocationContext.artifactService) {
620
+ throw new Error("Artifact service is not initialized.");
621
+ }
622
+ const resultContent = {
623
+ role: "model",
624
+ parts: [(0, import_code_execution_utils.buildCodeExecutionResultPart)(codeExecutionResult)]
625
+ };
626
+ const eventActions = (0, import_event_actions.createEventActions)({ stateDelta: codeExecutorContext.getStateDelta() });
627
+ if (codeExecutionResult.stderr) {
628
+ codeExecutorContext.incrementErrorCount(invocationContext.invocationId);
629
+ } else {
630
+ codeExecutorContext.resetErrorCount(invocationContext.invocationId);
631
+ }
632
+ for (const outputFile of codeExecutionResult.outputFiles) {
633
+ const version = await invocationContext.artifactService.saveArtifact({
634
+ appName: invocationContext.appName || "",
635
+ userId: invocationContext.userId || "",
636
+ sessionId: invocationContext.session.id,
637
+ filename: outputFile.name,
638
+ artifact: {
639
+ inlineData: { data: outputFile.content, mimeType: outputFile.mimeType }
640
+ }
641
+ });
642
+ eventActions.artifactDelta[outputFile.name] = version;
643
+ }
644
+ return (0, import_event.createEvent)({
645
+ invocationId: invocationContext.invocationId,
646
+ author: invocationContext.agent.name,
647
+ branch: invocationContext.branch,
648
+ content: resultContent,
649
+ actions: eventActions
650
+ });
651
+ }
652
+ function getDataFilePreprocessingCode(file) {
653
+ function getNormalizedFileName(fileName) {
654
+ const [varName2] = fileName.split(".");
655
+ let normalizedName = varName2.replace(/[^a-zA-Z0-9_]/g, "_");
656
+ if (/^\d/.test(normalizedName)) {
657
+ normalizedName = "_" + normalizedName;
658
+ }
659
+ return normalizedName;
660
+ }
661
+ if (!DATA_FILE_UTIL_MAP[file.mimeType]) {
662
+ return void 0;
663
+ }
664
+ const varName = getNormalizedFileName(file.name);
665
+ const loaderCode = DATA_FILE_UTIL_MAP[file.mimeType].loaderCodeTemplate.replace(
666
+ "{filename}",
667
+ file.name
668
+ );
669
+ return `
670
+ ${DATA_FILE_HELPER_LIB}
671
+
672
+ # Load the dataframe.
673
+ ${varName} = ${loaderCode}
674
+
675
+ # Use \`explore_df\` to guide my analysis.
676
+ explore_df(${varName})
677
+ `;
678
+ }
679
+ const CODE_EXECUTION_REQUEST_PROCESSOR = new CodeExecutionRequestProcessor();
356
680
  class LlmAgent extends import_base_agent.BaseAgent {
357
681
  constructor(config) {
358
682
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
@@ -372,12 +696,14 @@ class LlmAgent extends import_base_agent.BaseAgent {
372
696
  this.afterModelCallback = config.afterModelCallback;
373
697
  this.beforeToolCallback = config.beforeToolCallback;
374
698
  this.afterToolCallback = config.afterToolCallback;
699
+ this.codeExecutor = config.codeExecutor;
375
700
  this.requestProcessors = (_g = config.requestProcessors) != null ? _g : [
376
701
  BASIC_LLM_REQUEST_PROCESSOR,
377
702
  IDENTITY_LLM_REQUEST_PROCESSOR,
378
703
  INSTRUCTIONS_LLM_REQUEST_PROCESSOR,
379
704
  REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR,
380
- CONTENT_REQUEST_PROCESSOR
705
+ CONTENT_REQUEST_PROCESSOR,
706
+ CODE_EXECUTION_REQUEST_PROCESSOR
381
707
  ];
382
708
  this.responseProcessors = (_h = config.responseProcessors) != null ? _h : [];
383
709
  const agentTransferDisabled = this.disallowTransferToParent && this.disallowTransferToPeers && !((_i = this.subAgents) == null ? void 0 : _i.length);
@@ -861,5 +1187,6 @@ class LlmAgent extends import_base_agent.BaseAgent {
861
1187
  // Annotate the CommonJS export names for ESM import in node:
862
1188
  0 && (module.exports = {
863
1189
  LlmAgent,
864
- REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR
1190
+ REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR,
1191
+ responseProcessor
865
1192
  });
@@ -31,6 +31,7 @@ __export(common_exports, {
31
31
  BasePlugin: () => import_base_plugin.BasePlugin,
32
32
  BaseTool: () => import_base_tool.BaseTool,
33
33
  BaseToolset: () => import_base_toolset.BaseToolset,
34
+ BuiltInCodeExecutor: () => import_built_in_code_executor.BuiltInCodeExecutor,
34
35
  CallbackContext: () => import_callback_context.CallbackContext,
35
36
  FunctionTool: () => import_function_tool.FunctionTool,
36
37
  GOOGLE_SEARCH: () => import_google_search_tool.GOOGLE_SEARCH,
@@ -86,6 +87,7 @@ var import_parallel_agent = require("./agents/parallel_agent.js");
86
87
  var import_run_config = require("./agents/run_config.js");
87
88
  var import_sequential_agent = require("./agents/sequential_agent.js");
88
89
  var import_in_memory_artifact_service = require("./artifacts/in_memory_artifact_service.js");
90
+ var import_built_in_code_executor = require("./code_executors/built_in_code_executor.js");
89
91
  var import_event = require("./events/event.js");
90
92
  var import_event_actions = require("./events/event_actions.js");
91
93
  var import_in_memory_memory_service = require("./memory/in_memory_memory_service.js");
@@ -129,6 +131,7 @@ __reExport(common_exports, require("./tools/base_tool.js"), module.exports);
129
131
  BasePlugin,
130
132
  BaseTool,
131
133
  BaseToolset,
134
+ BuiltInCodeExecutor,
132
135
  CallbackContext,
133
136
  FunctionTool,
134
137
  GOOGLE_SEARCH,