diff --git a/frontend/src/components/chat/chat-panel.tsx b/frontend/src/components/chat/chat-panel.tsx index 1bdd83ef06b..a5106ed589e 100644 --- a/frontend/src/components/chat/chat-panel.tsx +++ b/frontend/src/components/chat/chat-panel.tsx @@ -238,6 +238,7 @@ const ChatMessageDisplay: React.FC = memo( result={part.output} className="my-2" state={part.state} + input={part.input} /> ); } @@ -269,6 +270,7 @@ const ChatMessageDisplay: React.FC = memo( toolName={part.type} result={part.output} state={part.state} + input={part.input} className="my-2" /> ); diff --git a/frontend/src/components/chat/tool-call-accordion.tsx b/frontend/src/components/chat/tool-call-accordion.tsx index 07d05799e5b..e09623d7a85 100644 --- a/frontend/src/components/chat/tool-call-accordion.tsx +++ b/frontend/src/components/chat/tool-call-accordion.tsx @@ -45,17 +45,21 @@ const PrettySuccessResult: React.FC<{ data: SuccessResult }> = ({ data }) => { } = data; return ( -
- {/* Status */} -
- - {status} - - {auth_required && ( - - Auth Required +
+
+

+ Tool Result +

+
+ + {status} - )} + {auth_required && ( + + Auth Required + + )} +
{/* Message */} @@ -68,17 +72,18 @@ const PrettySuccessResult: React.FC<{ data: SuccessResult }> = ({ data }) => { {/* Data */} {rest && ( -
+
{Object.entries(rest).map(([key, value]) => { if (isEmpty(value)) { return null; } return ( -
-
- {key}: +
+
+
+ {key}
-
+                
                   {JSON.stringify(value, null, 2)}
                 
@@ -107,6 +112,29 @@ const ResultRenderer: React.FC<{ result: unknown }> = ({ result }) => { ); }; +const ToolArgsRenderer: React.FC<{ input: unknown }> = ({ input }) => { + const hasinput = input && input !== null; + + if (!hasinput) { + return null; + } + + const isObject = + typeof input === "object" && + Object.keys(input as Record).length > 0; + + return ( +
+

+ Tool Request +

+
+        {isObject ? JSON.stringify(input, null, 2) : String(input)}
+      
+
+ ); +}; + interface ToolCallAccordionProps { toolName: string; result: unknown; @@ -114,6 +142,7 @@ interface ToolCallAccordionProps { index?: number; state?: ToolUIPart["state"]; className?: string; + input?: unknown; } export const ToolCallAccordion: React.FC = ({ @@ -123,6 +152,7 @@ export const ToolCallAccordion: React.FC = ({ index = 0, state, className, + input, }) => { const hasResult = state === "output-available" && (result || error); const status = error ? "error" : hasResult ? "success" : "loading"; @@ -176,21 +206,23 @@ export const ToolCallAccordion: React.FC = ({ - + {/* Only show content when tool is complete */} {hasResult && (
+ {result !== undefined && result !== null && ( )} {/* Error */} {error && ( -
-
- Error: +
+
+
+ Error
-
+
{error}
diff --git a/marimo/_ai/_tools/tools/datasource.py b/marimo/_ai/_tools/tools/datasource.py index 02248513d49..48115d43657 100644 --- a/marimo/_ai/_tools/tools/datasource.py +++ b/marimo/_ai/_tools/tools/datasource.py @@ -40,11 +40,11 @@ class GetDatabaseTables( ToolBase[GetDatabaseTablesArgs, GetDatabaseTablesOutput] ): """ - Get information about tables in a database. + Get information about tables in a database. Use the query parameter to search by name. Use regex for complex searches. Args: session_id: The session id. - query (optional): The query to match the database, schemas, and tables. Regex is supported. + query (optional): The query to match the database, schemas, and tables. If a query is provided, it will fuzzy match the query to the database, schemas, and tables available. If no query is provided, all tables are returned. Don't provide a query if you need to see the entire schema view. diff --git a/marimo/_ai/_types.py b/marimo/_ai/_types.py index 6865cd8bcec..13a98ef7ab0 100644 --- a/marimo/_ai/_types.py +++ b/marimo/_ai/_types.py @@ -215,6 +215,7 @@ def __post_init__(self) -> None: self.parts = parts def _convert_part(self, part: Any) -> Optional[ChatPart]: + PartType = None for PartType in PART_TYPES: try: if dataclasses.is_dataclass(part):