diff --git a/src/codegen/extensions/tools/observation.py b/src/codegen/extensions/tools/observation.py index 487c1bdfe..1d12aadc0 100644 --- a/src/codegen/extensions/tools/observation.py +++ b/src/codegen/extensions/tools/observation.py @@ -6,6 +6,10 @@ from langchain_core.messages import ToolMessage from pydantic import BaseModel, Field +from codegen.shared.logging.get_logger import get_logger + +logger = get_logger(__name__) + class Observation(BaseModel): """Base class for all tool observations. @@ -44,14 +48,18 @@ def __repr__(self) -> str: """Get detailed string representation of the observation.""" return f"{self.__class__.__name__}({self.model_dump_json()})" - def render_as_string(self) -> str: + def render_as_string(self, max_tokens: int = 8000) -> str: """Render the observation as a string. This is used for string representation and as the content field in the ToolMessage. Subclasses can override this to customize their string output format. """ - return json.dumps(self.model_dump(), indent=2) + rendered = json.dumps(self.model_dump(), indent=2) + if 3 * len(rendered) > max_tokens: + logger.error(f"Observation is too long to render: {len(rendered) * 3} tokens") + return rendered[:max_tokens] + "\n\n...truncated...\n\n" + return rendered def render(self, tool_call_id: Optional[str] = None) -> ToolMessage | str: """Render the observation as a ToolMessage or string.