From 632e0e076287d0116be4cf9e5d5f95dedb084c13 Mon Sep 17 00:00:00 2001 From: Siddharth Ganesan Date: Wed, 18 Feb 2026 15:29:58 -0800 Subject: [PATCH] Checkpoitn --- apps/sim/lib/copilot/client-sse/handlers.ts | 28 +- .../copilot/client-sse/run-tool-execution.ts | 2 +- .../copilot/client-sse/subagent-handlers.ts | 2 +- .../sim/lib/copilot/messages/serialization.ts | 2 +- apps/sim/lib/copilot/orchestrator/types.ts | 2 + apps/sim/lib/copilot/store-utils.ts | 101 ++++++- .../tools/client/tool-display-registry.ts | 254 ------------------ apps/sim/stores/panel/copilot/store.ts | 6 +- apps/sim/stores/panel/copilot/types.ts | 3 + 9 files changed, 129 insertions(+), 271 deletions(-) diff --git a/apps/sim/lib/copilot/client-sse/handlers.ts b/apps/sim/lib/copilot/client-sse/handlers.ts index 82f887a48..85310a197 100644 --- a/apps/sim/lib/copilot/client-sse/handlers.ts +++ b/apps/sim/lib/copilot/client-sse/handlers.ts @@ -269,7 +269,7 @@ export const sseHandlers: Record = { updatedMap[toolCallId] = { ...current, state: targetState, - display: resolveToolDisplay(current.name, targetState, current.id, current.params), + display: resolveToolDisplay(current.name, targetState, current.id, current.params, current.serverUI), } set({ toolCallsById: updatedMap }) @@ -469,7 +469,8 @@ export const sseHandlers: Record = { b.toolCall?.name, targetState, toolCallId, - b.toolCall?.params + b.toolCall?.params, + b.toolCall?.serverUI ), }, } @@ -507,7 +508,7 @@ export const sseHandlers: Record = { updatedMap[toolCallId] = { ...current, state: targetState, - display: resolveToolDisplay(current.name, targetState, current.id, current.params), + display: resolveToolDisplay(current.name, targetState, current.id, current.params, current.serverUI), } set({ toolCallsById: updatedMap }) } @@ -532,7 +533,8 @@ export const sseHandlers: Record = { b.toolCall?.name, targetState, toolCallId, - b.toolCall?.params + b.toolCall?.params, + b.toolCall?.serverUI ), }, } @@ -579,6 +581,16 @@ export const sseHandlers: Record = { const isPartial = toolData.partial === true const { toolCallsById } = get() + // Extract copilot-provided UI metadata for fallback display + const rawUI = (toolData.ui || data?.ui) as Record | undefined + const serverUI = rawUI + ? { + title: rawUI.title as string | undefined, + phaseLabel: rawUI.phaseLabel as string | undefined, + icon: rawUI.icon as string | undefined, + } + : undefined + const existing = toolCallsById[id] const toolName = name || existing?.name || 'unknown_tool' const isAutoAllowed = get().isToolAutoAllowed(toolName) @@ -592,20 +604,24 @@ export const sseHandlers: Record = { initialState = ClientToolCallState.executing } + const effectiveServerUI = serverUI || existing?.serverUI + const next: CopilotToolCall = existing ? { ...existing, name: toolName, state: initialState, ...(args ? { params: args } : {}), - display: resolveToolDisplay(toolName, initialState, id, args || existing.params), + ...(effectiveServerUI ? { serverUI: effectiveServerUI } : {}), + display: resolveToolDisplay(toolName, initialState, id, args || existing.params, effectiveServerUI), } : { id, name: toolName, state: initialState, ...(args ? { params: args } : {}), - display: resolveToolDisplay(toolName, initialState, id, args), + ...(serverUI ? { serverUI } : {}), + display: resolveToolDisplay(toolName, initialState, id, args, serverUI), } const updated = { ...toolCallsById, [id]: next } set({ toolCallsById: updated }) diff --git a/apps/sim/lib/copilot/client-sse/run-tool-execution.ts b/apps/sim/lib/copilot/client-sse/run-tool-execution.ts index 37ccd80e7..21142b282 100644 --- a/apps/sim/lib/copilot/client-sse/run-tool-execution.ts +++ b/apps/sim/lib/copilot/client-sse/run-tool-execution.ts @@ -178,7 +178,7 @@ function setToolState(toolCallId: string, state: ClientToolCallState): void { [toolCallId]: { ...current, state, - display: resolveToolDisplay(current.name, state, toolCallId, current.params), + display: resolveToolDisplay(current.name, state, toolCallId, current.params, current.serverUI), }, } useCopilotStore.setState({ toolCallsById: updated }) diff --git a/apps/sim/lib/copilot/client-sse/subagent-handlers.ts b/apps/sim/lib/copilot/client-sse/subagent-handlers.ts index 314a40573..06ccb2435 100644 --- a/apps/sim/lib/copilot/client-sse/subagent-handlers.ts +++ b/apps/sim/lib/copilot/client-sse/subagent-handlers.ts @@ -285,7 +285,7 @@ export const subAgentSSEHandlers: Record = { const updatedSubAgentToolCall = { ...existing, state: targetState, - display: resolveToolDisplay(existing.name, targetState, toolCallId, existing.params), + display: resolveToolDisplay(existing.name, targetState, toolCallId, existing.params, existing.serverUI), } context.subAgentToolCalls[parentToolCallId][existingIndex] = updatedSubAgentToolCall diff --git a/apps/sim/lib/copilot/messages/serialization.ts b/apps/sim/lib/copilot/messages/serialization.ts index 29686f6bc..650463971 100644 --- a/apps/sim/lib/copilot/messages/serialization.ts +++ b/apps/sim/lib/copilot/messages/serialization.ts @@ -34,7 +34,7 @@ export function clearStreamingFlags(toolCall: CopilotToolCall): void { ? ClientToolCallState.success : ClientToolCallState.aborted toolCall.state = normalized - toolCall.display = resolveToolDisplay(toolCall.name, normalized, toolCall.id, toolCall.params) + toolCall.display = resolveToolDisplay(toolCall.name, normalized, toolCall.id, toolCall.params, toolCall.serverUI) } if (Array.isArray(toolCall.subAgentBlocks)) { diff --git a/apps/sim/lib/copilot/orchestrator/types.ts b/apps/sim/lib/copilot/orchestrator/types.ts index 3113a23b5..79746b0b6 100644 --- a/apps/sim/lib/copilot/orchestrator/types.ts +++ b/apps/sim/lib/copilot/orchestrator/types.ts @@ -35,6 +35,8 @@ export interface SSEEvent { phase?: string /** Set on tool_result events */ failedDependency?: boolean + /** UI metadata from copilot (title, icon, phaseLabel) */ + ui?: Record } export type ToolCallStatus = 'pending' | 'executing' | 'success' | 'error' | 'skipped' | 'rejected' diff --git a/apps/sim/lib/copilot/store-utils.ts b/apps/sim/lib/copilot/store-utils.ts index 267d368c2..09e444ff2 100644 --- a/apps/sim/lib/copilot/store-utils.ts +++ b/apps/sim/lib/copilot/store-utils.ts @@ -1,5 +1,28 @@ import { createLogger } from '@sim/logger' -import { Loader2 } from 'lucide-react' +import type { LucideIcon } from 'lucide-react' +import { + BookOpen, + Bug, + Cloud, + Code, + FileText, + Folder, + Globe, + HelpCircle, + Key, + Loader2, + Lock, + Pencil, + Play, + Plus, + Rocket, + Search, + Server, + Settings, + Terminal, + Wrench, + Zap, +} from 'lucide-react' import { ClientToolCallState, type ClientToolDisplay, @@ -16,16 +39,62 @@ type StoreSet = ( /** Respond tools are internal to copilot subagents and should never be shown in the UI */ const HIDDEN_TOOL_SUFFIX = '_respond' +/** UI metadata sent by the copilot on SSE tool_call events. */ +export interface ServerToolUI { + title?: string + phaseLabel?: string + icon?: string +} + +/** Maps copilot icon name strings to Lucide icon components. */ +const ICON_MAP: Record = { + search: Search, + globe: Globe, + hammer: Wrench, + rocket: Rocket, + lock: Lock, + book: BookOpen, + wrench: Wrench, + zap: Zap, + play: Play, + cloud: Cloud, + key: Key, + pencil: Pencil, + terminal: Terminal, + workflow: Settings, + settings: Settings, + server: Server, + bug: Bug, + brain: BookOpen, + code: Code, + help: HelpCircle, + plus: Plus, + file: FileText, + folder: Folder, +} + +function resolveIcon(iconName: string | undefined): LucideIcon { + if (!iconName) return Loader2 + return ICON_MAP[iconName] || Loader2 +} + export function resolveToolDisplay( toolName: string | undefined, state: ClientToolCallState, _toolCallId?: string, - params?: Record + params?: Record, + serverUI?: ServerToolUI ): ClientToolDisplay | undefined { if (!toolName) return undefined if (toolName.endsWith(HIDDEN_TOOL_SUFFIX)) return undefined const entry = TOOL_DISPLAY_REGISTRY[toolName] - if (!entry) return humanizedFallback(toolName, state) + if (!entry) { + // Use copilot-provided UI as a better fallback than humanized name + if (serverUI?.title) { + return serverUIFallback(serverUI, state) + } + return humanizedFallback(toolName, state) + } if (entry.uiConfig?.dynamicText && params) { const dynamicText = entry.uiConfig.dynamicText(params, state) @@ -51,6 +120,28 @@ export function resolveToolDisplay( return humanizedFallback(toolName, state) } +/** Generates display from copilot-provided UI metadata. */ +function serverUIFallback( + serverUI: ServerToolUI, + state: ClientToolCallState +): ClientToolDisplay { + const icon = resolveIcon(serverUI.icon) + const title = serverUI.title! + + switch (state) { + case ClientToolCallState.success: + return { text: `Completed ${title.toLowerCase()}`, icon } + case ClientToolCallState.error: + return { text: `Failed ${title.toLowerCase()}`, icon } + case ClientToolCallState.rejected: + return { text: `Skipped ${title.toLowerCase()}`, icon } + case ClientToolCallState.aborted: + return { text: `Aborted ${title.toLowerCase()}`, icon } + default: + return { text: title, icon: Loader2 } + } +} + export function humanizedFallback( toolName: string, state: ClientToolCallState @@ -121,7 +212,7 @@ export function abortAllInProgressTools(set: StoreSet, get: () => CopilotStore) ...tc, state: resolved, subAgentStreaming: false, - display: resolveToolDisplay(tc.name, resolved, id, tc.params), + display: resolveToolDisplay(tc.name, resolved, id, tc.params, tc.serverUI), } hasUpdates = true } else if (tc.subAgentStreaming) { @@ -150,7 +241,7 @@ export function abortAllInProgressTools(set: StoreSet, get: () => CopilotStore) toolCall: { ...prev, state: resolved, - display: resolveToolDisplay(prev?.name, resolved, prev?.id, prev?.params), + display: resolveToolDisplay(prev?.name, resolved, prev?.id, prev?.params, prev?.serverUI), }, } } diff --git a/apps/sim/lib/copilot/tools/client/tool-display-registry.ts b/apps/sim/lib/copilot/tools/client/tool-display-registry.ts index 9c38ea23a..12a4a4384 100644 --- a/apps/sim/lib/copilot/tools/client/tool-display-registry.ts +++ b/apps/sim/lib/copilot/tools/client/tool-display-registry.ts @@ -5,27 +5,20 @@ import { Check, CheckCircle, CheckCircle2, - ClipboardCheck, - Compass, Database, FileText, - FlaskConical, GitBranch, Globe, Globe2, Grid2x2, Grid2x2Check, Grid2x2X, - Info, KeyRound, - ListFilter, - ListTodo, Loader2, MessageSquare, MinusCircle, Moon, Navigation, - Pencil, PencilLine, Play, PlugZap, @@ -334,46 +327,6 @@ const META_build: ToolMetadata = { }, } -const META_debug: ToolMetadata = { - displayNames: { - [ClientToolCallState.generating]: { text: 'Debugging', icon: Loader2 }, - [ClientToolCallState.pending]: { text: 'Debugging', icon: Loader2 }, - [ClientToolCallState.executing]: { text: 'Debugging', icon: Loader2 }, - [ClientToolCallState.success]: { text: 'Debugged', icon: Bug }, - [ClientToolCallState.error]: { text: 'Failed to debug', icon: XCircle }, - [ClientToolCallState.rejected]: { text: 'Skipped debug', icon: XCircle }, - [ClientToolCallState.aborted]: { text: 'Aborted debug', icon: XCircle }, - }, - uiConfig: { - subagent: { - streamingLabel: 'Debugging', - completedLabel: 'Debugged', - shouldCollapse: true, - outputArtifacts: [], - }, - }, -} - -const META_discovery: ToolMetadata = { - displayNames: { - [ClientToolCallState.generating]: { text: 'Discovering', icon: Loader2 }, - [ClientToolCallState.pending]: { text: 'Discovering', icon: Loader2 }, - [ClientToolCallState.executing]: { text: 'Discovering', icon: Loader2 }, - [ClientToolCallState.success]: { text: 'Discovered', icon: Search }, - [ClientToolCallState.error]: { text: 'Failed to discover', icon: XCircle }, - [ClientToolCallState.rejected]: { text: 'Skipped discovery', icon: XCircle }, - [ClientToolCallState.aborted]: { text: 'Aborted discovery', icon: XCircle }, - }, - uiConfig: { - subagent: { - streamingLabel: 'Discovering', - completedLabel: 'Discovered', - shouldCollapse: true, - outputArtifacts: [], - }, - }, -} - const META_deploy: ToolMetadata = { displayNames: { [ClientToolCallState.generating]: { text: 'Deploying', icon: Loader2 }, @@ -564,28 +517,6 @@ const META_deploy_mcp: ToolMetadata = { }, } -const META_edit: ToolMetadata = { - displayNames: { - [ClientToolCallState.generating]: { text: 'Editing', icon: Loader2 }, - [ClientToolCallState.pending]: { text: 'Editing', icon: Loader2 }, - [ClientToolCallState.executing]: { text: 'Editing', icon: Loader2 }, - [ClientToolCallState.success]: { text: 'Edited', icon: Pencil }, - [ClientToolCallState.error]: { text: 'Failed to apply edit', icon: XCircle }, - [ClientToolCallState.rejected]: { text: 'Skipped edit', icon: XCircle }, - [ClientToolCallState.aborted]: { text: 'Aborted edit', icon: XCircle }, - }, - uiConfig: { - isSpecial: true, - subagent: { - streamingLabel: 'Editing', - completedLabel: 'Edited', - shouldCollapse: false, // Edit subagent stays expanded - outputArtifacts: ['edit_summary'], - hideThinkingText: true, // We show WorkflowEditSummary instead - }, - }, -} - const META_edit_workflow: ToolMetadata = { displayNames: { [ClientToolCallState.generating]: { text: 'Editing your workflow', icon: Loader2 }, @@ -603,26 +534,6 @@ const META_edit_workflow: ToolMetadata = { }, } -const META_evaluate: ToolMetadata = { - displayNames: { - [ClientToolCallState.generating]: { text: 'Evaluating', icon: Loader2 }, - [ClientToolCallState.pending]: { text: 'Evaluating', icon: Loader2 }, - [ClientToolCallState.executing]: { text: 'Evaluating', icon: Loader2 }, - [ClientToolCallState.success]: { text: 'Evaluated', icon: ClipboardCheck }, - [ClientToolCallState.error]: { text: 'Failed to evaluate', icon: XCircle }, - [ClientToolCallState.rejected]: { text: 'Skipped evaluation', icon: XCircle }, - [ClientToolCallState.aborted]: { text: 'Aborted evaluation', icon: XCircle }, - }, - uiConfig: { - subagent: { - streamingLabel: 'Evaluating', - completedLabel: 'Evaluated', - shouldCollapse: true, - outputArtifacts: [], - }, - }, -} - const META_get_block_outputs: ToolMetadata = { displayNames: { [ClientToolCallState.generating]: { text: 'Getting block outputs', icon: Loader2 }, @@ -681,47 +592,6 @@ const META_get_block_upstream_references: ToolMetadata = { }, } -const META_get_blocks_metadata: ToolMetadata = { - displayNames: { - [ClientToolCallState.generating]: { text: 'Searching block choices', icon: Loader2 }, - [ClientToolCallState.pending]: { text: 'Searching block choices', icon: Loader2 }, - [ClientToolCallState.executing]: { text: 'Searching block choices', icon: Loader2 }, - [ClientToolCallState.success]: { text: 'Searched block choices', icon: ListFilter }, - [ClientToolCallState.error]: { text: 'Failed to search block choices', icon: XCircle }, - [ClientToolCallState.aborted]: { text: 'Aborted searching block choices', icon: XCircle }, - [ClientToolCallState.rejected]: { - text: 'Skipped searching block choices', - icon: MinusCircle, - }, - }, - getDynamicText: (params, state) => { - if (params?.blockIds && Array.isArray(params.blockIds) && params.blockIds.length > 0) { - const blockList = params.blockIds - .slice(0, 3) - .map((blockId) => blockId.replace(/_/g, ' ')) - .join(', ') - const more = params.blockIds.length > 3 ? '...' : '' - const blocks = `${blockList}${more}` - - switch (state) { - case ClientToolCallState.success: - return `Searched ${blocks}` - case ClientToolCallState.executing: - case ClientToolCallState.generating: - case ClientToolCallState.pending: - return `Searching ${blocks}` - case ClientToolCallState.error: - return `Failed to search ${blocks}` - case ClientToolCallState.aborted: - return `Aborted searching ${blocks}` - case ClientToolCallState.rejected: - return `Skipped searching ${blocks}` - } - } - return undefined - }, -} - const META_get_examples_rag: ToolMetadata = { displayNames: { [ClientToolCallState.generating]: { text: 'Fetching examples', icon: Loader2 }, @@ -843,19 +713,6 @@ const META_get_page_contents: ToolMetadata = { }, } -const META_get_trigger_blocks: ToolMetadata = { - displayNames: { - [ClientToolCallState.generating]: { text: 'Finding trigger blocks', icon: Loader2 }, - [ClientToolCallState.pending]: { text: 'Finding trigger blocks', icon: Loader2 }, - [ClientToolCallState.executing]: { text: 'Finding trigger blocks', icon: Loader2 }, - [ClientToolCallState.success]: { text: 'Found trigger blocks', icon: ListFilter }, - [ClientToolCallState.error]: { text: 'Failed to find trigger blocks', icon: XCircle }, - [ClientToolCallState.aborted]: { text: 'Aborted finding trigger blocks', icon: MinusCircle }, - [ClientToolCallState.rejected]: { text: 'Skipped finding trigger blocks', icon: MinusCircle }, - }, - interrupt: undefined, -} - const META_get_trigger_examples: ToolMetadata = { displayNames: { [ClientToolCallState.generating]: { text: 'Selecting a trigger', icon: Loader2 }, @@ -951,26 +808,6 @@ const META_get_workflow_data: ToolMetadata = { }, } -const META_info: ToolMetadata = { - displayNames: { - [ClientToolCallState.generating]: { text: 'Getting info', icon: Loader2 }, - [ClientToolCallState.pending]: { text: 'Getting info', icon: Loader2 }, - [ClientToolCallState.executing]: { text: 'Getting info', icon: Loader2 }, - [ClientToolCallState.success]: { text: 'Retrieved info', icon: Info }, - [ClientToolCallState.error]: { text: 'Failed to get info', icon: XCircle }, - [ClientToolCallState.rejected]: { text: 'Skipped info', icon: XCircle }, - [ClientToolCallState.aborted]: { text: 'Aborted info', icon: XCircle }, - }, - uiConfig: { - subagent: { - streamingLabel: 'Getting info', - completedLabel: 'Info retrieved', - shouldCollapse: true, - outputArtifacts: [], - }, - }, -} - const META_knowledge: ToolMetadata = { displayNames: { [ClientToolCallState.generating]: { text: 'Managing knowledge', icon: Loader2 }, @@ -1404,26 +1241,6 @@ const META_oauth_request_access: ToolMetadata = { }, } -const META_plan: ToolMetadata = { - displayNames: { - [ClientToolCallState.generating]: { text: 'Planning', icon: Loader2 }, - [ClientToolCallState.pending]: { text: 'Planning', icon: Loader2 }, - [ClientToolCallState.executing]: { text: 'Planning', icon: Loader2 }, - [ClientToolCallState.success]: { text: 'Planned', icon: ListTodo }, - [ClientToolCallState.error]: { text: 'Failed to plan', icon: XCircle }, - [ClientToolCallState.rejected]: { text: 'Skipped plan', icon: XCircle }, - [ClientToolCallState.aborted]: { text: 'Aborted plan', icon: XCircle }, - }, - uiConfig: { - subagent: { - streamingLabel: 'Planning', - completedLabel: 'Planned', - shouldCollapse: true, - outputArtifacts: ['plan'], - }, - }, -} - const META_redeploy: ToolMetadata = { displayNames: { [ClientToolCallState.generating]: { text: 'Redeploying workflow', icon: Loader2 }, @@ -2266,66 +2083,6 @@ const META_superagent: ToolMetadata = { }, } -const META_test: ToolMetadata = { - displayNames: { - [ClientToolCallState.generating]: { text: 'Testing', icon: Loader2 }, - [ClientToolCallState.pending]: { text: 'Testing', icon: Loader2 }, - [ClientToolCallState.executing]: { text: 'Testing', icon: Loader2 }, - [ClientToolCallState.success]: { text: 'Tested', icon: FlaskConical }, - [ClientToolCallState.error]: { text: 'Failed to test', icon: XCircle }, - [ClientToolCallState.rejected]: { text: 'Skipped test', icon: XCircle }, - [ClientToolCallState.aborted]: { text: 'Aborted test', icon: XCircle }, - }, - uiConfig: { - subagent: { - streamingLabel: 'Testing', - completedLabel: 'Tested', - shouldCollapse: true, - outputArtifacts: [], - }, - }, -} - -const META_tour: ToolMetadata = { - displayNames: { - [ClientToolCallState.generating]: { text: 'Touring', icon: Loader2 }, - [ClientToolCallState.pending]: { text: 'Touring', icon: Loader2 }, - [ClientToolCallState.executing]: { text: 'Touring', icon: Loader2 }, - [ClientToolCallState.success]: { text: 'Completed tour', icon: Compass }, - [ClientToolCallState.error]: { text: 'Failed tour', icon: XCircle }, - [ClientToolCallState.rejected]: { text: 'Skipped tour', icon: XCircle }, - [ClientToolCallState.aborted]: { text: 'Aborted tour', icon: XCircle }, - }, - uiConfig: { - subagent: { - streamingLabel: 'Touring', - completedLabel: 'Tour complete', - shouldCollapse: true, - outputArtifacts: [], - }, - }, -} - -const META_workflow: ToolMetadata = { - displayNames: { - [ClientToolCallState.generating]: { text: 'Managing workflow', icon: Loader2 }, - [ClientToolCallState.pending]: { text: 'Managing workflow', icon: Loader2 }, - [ClientToolCallState.executing]: { text: 'Managing workflow', icon: Loader2 }, - [ClientToolCallState.success]: { text: 'Managed workflow', icon: GitBranch }, - [ClientToolCallState.error]: { text: 'Failed to manage workflow', icon: XCircle }, - [ClientToolCallState.rejected]: { text: 'Skipped workflow', icon: XCircle }, - [ClientToolCallState.aborted]: { text: 'Aborted workflow', icon: XCircle }, - }, - uiConfig: { - subagent: { - streamingLabel: 'Managing workflow', - completedLabel: 'Workflow managed', - shouldCollapse: true, - outputArtifacts: [], - }, - }, -} - const TOOL_METADATA_BY_ID: Record = { auth: META_auth, check_deployment_status: META_check_deployment_status, @@ -2334,28 +2091,21 @@ const TOOL_METADATA_BY_ID: Record = { create_workspace_mcp_server: META_create_workspace_mcp_server, build: META_build, custom_tool: META_custom_tool, - debug: META_debug, deploy: META_deploy, - discovery: META_discovery, deploy_api: META_deploy_api, deploy_chat: META_deploy_chat, deploy_mcp: META_deploy_mcp, - edit: META_edit, edit_workflow: META_edit_workflow, - evaluate: META_evaluate, get_block_outputs: META_get_block_outputs, get_block_upstream_references: META_get_block_upstream_references, - get_blocks_metadata: META_get_blocks_metadata, generate_api_key: META_generate_api_key, get_examples_rag: META_get_examples_rag, get_operations_examples: META_get_operations_examples, get_page_contents: META_get_page_contents, get_platform_actions: META_get_platform_actions, - get_trigger_blocks: META_get_trigger_blocks, get_trigger_examples: META_get_trigger_examples, get_workflow_console: META_get_workflow_console, get_workflow_data: META_get_workflow_data, - info: META_info, knowledge: META_knowledge, knowledge_base: META_knowledge_base, list_workspace_mcp_servers: META_list_workspace_mcp_servers, @@ -2365,7 +2115,6 @@ const TOOL_METADATA_BY_ID: Record = { mark_todo_in_progress: META_mark_todo_in_progress, navigate_ui: META_navigate_ui, oauth_request_access: META_oauth_request_access, - plan: META_plan, redeploy: META_redeploy, remember_debug: META_remember_debug, research: META_research, @@ -2384,9 +2133,6 @@ const TOOL_METADATA_BY_ID: Record = { sleep: META_sleep, summarize_conversation: META_summarize_conversation, superagent: META_superagent, - test: META_test, - tour: META_tour, - workflow: META_workflow, } export const TOOL_DISPLAY_REGISTRY: Record = Object.fromEntries( diff --git a/apps/sim/stores/panel/copilot/store.ts b/apps/sim/stores/panel/copilot/store.ts index bd4dd76e2..509ed4373 100644 --- a/apps/sim/stores/panel/copilot/store.ts +++ b/apps/sim/stores/panel/copilot/store.ts @@ -1650,7 +1650,7 @@ export const useCopilotStore = create()( map[id] = { ...current, state: norm, - display: resolveToolDisplay(current.name, norm, id, current.params), + display: resolveToolDisplay(current.name, norm, id, current.params, current.serverUI), } set({ toolCallsById: map }) } catch (error) { @@ -1671,7 +1671,7 @@ export const useCopilotStore = create()( map[toolCallId] = { ...current, params: updatedParams, - display: resolveToolDisplay(current.name, current.state, toolCallId, updatedParams), + display: resolveToolDisplay(current.name, current.state, toolCallId, updatedParams, current.serverUI), } set({ toolCallsById: map }) } catch (error) { @@ -1728,7 +1728,7 @@ export const useCopilotStore = create()( // Update store map const updatedMap = { ...toolCallsById } - const updatedDisplay = resolveToolDisplay(current.name, targetState, id, current.params) + const updatedDisplay = resolveToolDisplay(current.name, targetState, id, current.params, current.serverUI) updatedMap[id] = { ...current, state: targetState, diff --git a/apps/sim/stores/panel/copilot/types.ts b/apps/sim/stores/panel/copilot/types.ts index 883e4a9b5..c8916b67a 100644 --- a/apps/sim/stores/panel/copilot/types.ts +++ b/apps/sim/stores/panel/copilot/types.ts @@ -4,6 +4,7 @@ import type { AvailableModel } from '@/lib/copilot/types' export type { CopilotMode, CopilotModelId } from '@/lib/copilot/models' import type { ClientContentBlock } from '@/lib/copilot/client-sse/types' +import type { ServerToolUI } from '@/lib/copilot/store-utils' import type { ClientToolCallState, ClientToolDisplay } from '@/lib/copilot/tools/client/base-tool' import type { WorkflowState } from '@/stores/workflows/workflow/types' @@ -26,6 +27,8 @@ export interface CopilotToolCall { params?: Record input?: Record display?: ClientToolDisplay + /** UI metadata from the copilot SSE event (used as fallback for unregistered tools) */ + serverUI?: ServerToolUI /** Content streamed from a subagent (e.g., debug agent) */ subAgentContent?: string /** Tool calls made by the subagent */