From b74cf283c8d1b763402022a16ef0cb4a47e7b718 Mon Sep 17 00:00:00 2001 From: Siddharth Ganesan Date: Mon, 6 Apr 2026 11:04:05 -0700 Subject: [PATCH] Eager tool streaming --- .../components/agent-group/agent-group.tsx | 1 + .../components/agent-group/tool-call-item.tsx | 66 +++++++++++++++++-- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group.tsx index 41a0011a81..9de719a7f1 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group.tsx @@ -111,6 +111,7 @@ export function AgentGroup({ toolName={item.data.toolName} displayTitle={item.data.displayTitle} status={item.data.status} + streamingArgs={item.data.streamingArgs} /> ) : ( } +const LANG_ALIASES: Record = { + javascript: 'javascript', + python: 'python', + shell: 'bash', + bash: 'bash', +} + +function extractFunctionExecutePreview(raw: string): { code: string; lang: string } | null { + if (!raw) return null + const langMatch = raw.match(/"language"\s*:\s*"(\w+)"/) + const lang = langMatch ? (LANG_ALIASES[langMatch[1]] ?? langMatch[1]) : 'javascript' + + const codeStart = raw.indexOf('"code"') + if (codeStart === -1) return null + const colonIdx = raw.indexOf(':', codeStart + 6) + if (colonIdx === -1) return null + const quoteIdx = raw.indexOf('"', colonIdx + 1) + if (quoteIdx === -1) return null + + let value = raw.slice(quoteIdx + 1) + if (value.endsWith('"}') || value.endsWith('"\n}')) { + value = value.replace(/"\s*\}?\s*$/, '') + } + if (value.endsWith('"')) { + value = value.slice(0, -1) + } + + const code = value + .replace(/\\n/g, '\n') + .replace(/\\t/g, '\t') + .replace(/\\"/g, '"') + .replace(/\\\\/g, '\\') + + return code.length > 0 ? { code, lang } : null +} + interface ToolCallItemProps { toolName: string displayTitle: string status: ToolCallStatus + streamingArgs?: string } -export function ToolCallItem({ toolName, displayTitle, status }: ToolCallItemProps) { +export function ToolCallItem({ toolName, displayTitle, status, streamingArgs }: ToolCallItemProps) { + const extracted = useMemo(() => { + if (toolName !== FunctionExecute.id || !streamingArgs) return null + return extractFunctionExecutePreview(streamingArgs) + }, [toolName, streamingArgs]) + const markdown = useMemo( + () => (extracted ? `\`\`\`${extracted.lang}\n${extracted.code}\n\`\`\`` : null), + [extracted] + ) + return ( -
-
- +
+
+
+ +
+ {displayTitle}
- {displayTitle} + {markdown && ( +
+ +
+ )}
) }