from typing import Annotated from langchain.tools import InjectedToolCallId, ToolRuntime, tool from langchain_core.messages import ToolMessage from langgraph.types import Command from langgraph.typing import ContextT from src.agents.thread_state import ThreadState @tool("present_files", parse_docstring=True) def present_file_tool( runtime: ToolRuntime[ContextT, ThreadState], filepaths: list[str], tool_call_id: Annotated[str, InjectedToolCallId], ) -> Command: """Make files visible to the user for viewing and rendering in the client interface. When to use the present_files tool: - Making any file available for the user to view, download, or interact with - Presenting multiple related files at once - After creating files that should be presented to the user When NOT to use the present_files tool: - When you only need to read file contents for your own processing - For temporary or intermediate files not meant for user viewing Notes: - You should call this tool after creating files and moving them to the `/mnt/user-data/outputs` directory. - Use non-parallel tool calling to present files in a single step. Args: filepaths: List of absolute file paths to present to the user. **Only** files in `/mnt/user-data/outputs` can be presented. """ existing_artifacts = runtime.state.get("artifacts") or [] new_artifacts = existing_artifacts + filepaths runtime.state["artifacts"] = new_artifacts return Command( update={"artifacts": new_artifacts, "messages": [ToolMessage("Successfully presented files", tool_call_id=tool_call_id)]}, )