You've already forked adk-python
mirror of
https://github.com/encounter/adk-python.git
synced 2026-03-30 10:57:20 -07:00
feat: Expose the Python code run by the code interpreter in the logs
Co-authored-by: Eliza Huang <heliza@google.com> PiperOrigin-RevId: 826521391
This commit is contained in:
committed by
Copybara-Service
parent
546c2a6816
commit
a2c6a8a85c
@@ -125,6 +125,7 @@ class AgentEngineSandboxCodeExecutor(BaseCodeExecutor):
|
||||
input_data=input_data,
|
||||
)
|
||||
)
|
||||
logger.debug('Executed code:\n```\n%s\n```', code_execution_input.code)
|
||||
saved_files = []
|
||||
stdout = ''
|
||||
stderr = ''
|
||||
|
||||
@@ -131,6 +131,7 @@ class ContainerCodeExecutor(BaseCodeExecutor):
|
||||
['python3', '-c', code_execution_input.code],
|
||||
demux=True,
|
||||
)
|
||||
logger.debug('Executed code:\n```\n%s\n```', code_execution_input.code)
|
||||
|
||||
if exec_result.output and exec_result.output[0]:
|
||||
output = exec_result.output[0].decode('utf-8')
|
||||
|
||||
@@ -162,6 +162,7 @@ class GkeCodeExecutor(BaseCodeExecutor):
|
||||
logger.info(
|
||||
f"Submitted Job '{job_name}' to namespace '{self.namespace}'."
|
||||
)
|
||||
logger.debug("Executing code:\n```\n%s\n```", code_execution_input.code)
|
||||
return self._watch_job_completion(job_name)
|
||||
|
||||
except ApiException as e:
|
||||
|
||||
@@ -16,6 +16,7 @@ from __future__ import annotations
|
||||
|
||||
from contextlib import redirect_stdout
|
||||
import io
|
||||
import logging
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
@@ -27,6 +28,8 @@ from .base_code_executor import BaseCodeExecutor
|
||||
from .code_execution_utils import CodeExecutionInput
|
||||
from .code_execution_utils import CodeExecutionResult
|
||||
|
||||
logger = logging.getLogger('google_adk.' + __name__)
|
||||
|
||||
|
||||
def _prepare_globals(code: str, globals_: dict[str, Any]) -> None:
|
||||
"""Prepare globals for code execution, injecting __name__ if needed."""
|
||||
@@ -60,6 +63,7 @@ class UnsafeLocalCodeExecutor(BaseCodeExecutor):
|
||||
invocation_context: InvocationContext,
|
||||
code_execution_input: CodeExecutionInput,
|
||||
) -> CodeExecutionResult:
|
||||
logger.debug('Executing code:\n```\n%s\n```', code_execution_input.code)
|
||||
# Execute the code.
|
||||
output = ''
|
||||
error = ''
|
||||
|
||||
@@ -152,6 +152,7 @@ class VertexAiCodeExecutor(BaseCodeExecutor):
|
||||
code_execution_input.input_files,
|
||||
code_execution_input.execution_id,
|
||||
)
|
||||
logger.debug('Executed code:\n```\n%s\n```', code_execution_input.code)
|
||||
|
||||
# Save output file as artifacts.
|
||||
saved_files = []
|
||||
@@ -187,11 +188,13 @@ class VertexAiCodeExecutor(BaseCodeExecutor):
|
||||
)
|
||||
|
||||
# Collect the final result.
|
||||
return CodeExecutionResult(
|
||||
result = CodeExecutionResult(
|
||||
stdout=code_execution_result.get('execution_result', ''),
|
||||
stderr=code_execution_result.get('execution_error', ''),
|
||||
output_files=saved_files,
|
||||
)
|
||||
logger.debug('Code execution result: %s', result)
|
||||
return result
|
||||
|
||||
def _execute_code_interpreter(
|
||||
self,
|
||||
|
||||
@@ -20,6 +20,7 @@ import base64
|
||||
import copy
|
||||
import dataclasses
|
||||
import datetime
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from typing import AsyncGenerator
|
||||
@@ -47,6 +48,8 @@ from ._base_llm_processor import BaseLlmResponseProcessor
|
||||
if TYPE_CHECKING:
|
||||
from ...models.llm_request import LlmRequest
|
||||
|
||||
logger = logging.getLogger('google_adk.' + __name__)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class DataFileUtil:
|
||||
@@ -245,6 +248,7 @@ async def _run_pre_processor(
|
||||
),
|
||||
),
|
||||
)
|
||||
logger.debug('Executed code:\n```\n%s\n```', code_str)
|
||||
# Update the processing results to code executor context.
|
||||
code_executor_context.update_code_execution_result(
|
||||
invocation_context.invocation_id,
|
||||
@@ -352,6 +356,7 @@ async def _run_post_processor(
|
||||
),
|
||||
),
|
||||
)
|
||||
logger.debug('Executed code:\n```\n%s\n```', code_str)
|
||||
code_executor_context.update_code_execution_result(
|
||||
invocation_context.invocation_id,
|
||||
code_str,
|
||||
|
||||
@@ -20,7 +20,9 @@ from unittest.mock import MagicMock
|
||||
from unittest.mock import patch
|
||||
|
||||
from google.adk.agents.llm_agent import Agent
|
||||
from google.adk.code_executors.base_code_executor import BaseCodeExecutor
|
||||
from google.adk.code_executors.built_in_code_executor import BuiltInCodeExecutor
|
||||
from google.adk.code_executors.code_execution_utils import CodeExecutionResult
|
||||
from google.adk.flows.llm_flows._code_execution import response_processor
|
||||
from google.adk.models.llm_response import LlmResponse
|
||||
from google.genai import types
|
||||
@@ -105,3 +107,44 @@ async def test_builtin_code_executor_image_artifact_creation(mock_datetime):
|
||||
== f'Saved as artifact: {expected_filename2}. '
|
||||
)
|
||||
assert not llm_response.content.parts[2].inline_data
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch('google.adk.flows.llm_flows._code_execution.logger')
|
||||
async def test_logs_executed_code(mock_logger):
|
||||
"""Test that the response processor logs the code it executes."""
|
||||
mock_code_executor = MagicMock(spec=BaseCodeExecutor)
|
||||
mock_code_executor.code_block_delimiters = [('```python\n', '\n```')]
|
||||
mock_code_executor.error_retry_attempts = 2
|
||||
mock_code_executor.stateful = False
|
||||
mock_code_executor.execute_code.return_value = CodeExecutionResult(
|
||||
stdout='hello'
|
||||
)
|
||||
|
||||
agent = Agent(name='test_agent', code_executor=mock_code_executor)
|
||||
invocation_context = await testing_utils.create_invocation_context(
|
||||
agent=agent, user_content='test message'
|
||||
)
|
||||
invocation_context.artifact_service = MagicMock()
|
||||
invocation_context.artifact_service.save_artifact = AsyncMock()
|
||||
|
||||
llm_response = LlmResponse(
|
||||
content=types.Content(
|
||||
parts=[
|
||||
types.Part(text='Here is some code:'),
|
||||
types.Part(text='```python\nprint("hello")\n```'),
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
_ = [
|
||||
event
|
||||
async for event in response_processor.run_async(
|
||||
invocation_context, llm_response
|
||||
)
|
||||
]
|
||||
|
||||
mock_code_executor.execute_code.assert_called_once()
|
||||
mock_logger.debug.assert_called_once_with(
|
||||
'Executed code:\n```\n%s\n```', 'print("hello")'
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user