Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1425,10 +1425,7 @@ function RunSkipButtons({
setIsProcessing(true)
setButtonsHidden(true)
try {
// Add to auto-allowed list - this also executes all pending integration tools of this type
await addAutoAllowedTool(toolCall.name)
// For client tools with interrupts (not integration tools), we still need to call handleRun
// since executeIntegrationTool only works for server-side tools
if (!isIntegrationTool(toolCall.name)) {
await handleRun(toolCall, setToolCallState, onStateChange, editedParams)
}
Expand Down Expand Up @@ -1526,7 +1523,11 @@ export function ToolCall({
toolCall.name === 'user_memory' ||
toolCall.name === 'edit_respond' ||
toolCall.name === 'debug_respond' ||
toolCall.name === 'plan_respond'
toolCall.name === 'plan_respond' ||
toolCall.name === 'research_respond' ||
toolCall.name === 'info_respond' ||
toolCall.name === 'deploy_respond' ||
toolCall.name === 'superagent_respond'
)
return null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,20 @@ export interface SlashCommand {
export const TOP_LEVEL_COMMANDS: readonly SlashCommand[] = [
{ id: 'fast', label: 'Fast' },
{ id: 'research', label: 'Research' },
{ id: 'superagent', label: 'Actions' },
{ id: 'actions', label: 'Actions' },
] as const

/**
* Maps UI command IDs to API command IDs.
* Some commands have different IDs for display vs API (e.g., "actions" -> "superagent")
*/
export function getApiCommandId(uiCommandId: string): string {
const commandMapping: Record<string, string> = {
actions: 'superagent',
}
return commandMapping[uiCommandId] || uiCommandId
}

export const WEB_COMMANDS: readonly SlashCommand[] = [
{ id: 'search', label: 'Search' },
{ id: 'read', label: 'Read' },
Expand Down
39 changes: 35 additions & 4 deletions apps/sim/stores/panel/copilot/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2116,6 +2116,24 @@ const subAgentSSEHandlers: Record<string, SSEHandler> = {
})
})
}
} else {
// Check if this is an integration tool (server-side) that should be auto-executed
const isIntegrationTool = !CLASS_TOOL_METADATA[name]
if (isIntegrationTool && isSubAgentAutoAllowed) {
logger.info('[SubAgent] Auto-executing integration tool (auto-allowed)', {
id,
name,
})
// Execute integration tool via the store method
const { executeIntegrationTool } = get()
executeIntegrationTool(id).catch((err) => {
logger.error('[SubAgent] Integration tool auto-execution failed', {
id,
name,
error: err?.message || err,
})
})
}
}
}
} catch (e: any) {
Expand Down Expand Up @@ -2797,9 +2815,14 @@ export const useCopilotStore = create<CopilotStore>()(
mode === 'ask' ? 'ask' : mode === 'plan' ? 'plan' : 'agent'

// Extract slash commands from contexts (lowercase) and filter them out from contexts
// Map UI command IDs to API command IDs (e.g., "actions" -> "superagent")
const uiToApiCommandMap: Record<string, string> = { actions: 'superagent' }
const commands = contexts
?.filter((c) => c.kind === 'slash_command' && 'command' in c)
.map((c) => (c as any).command.toLowerCase()) as string[] | undefined
.map((c) => {
const uiCommand = (c as any).command.toLowerCase()
return uiToApiCommandMap[uiCommand] || uiCommand
}) as string[] | undefined
const filteredContexts = contexts?.filter((c) => c.kind !== 'slash_command')

const result = await sendStreamingMessage({
Expand Down Expand Up @@ -3923,11 +3946,16 @@ export const useCopilotStore = create<CopilotStore>()(

loadAutoAllowedTools: async () => {
try {
logger.info('[AutoAllowedTools] Loading from API...')
const res = await fetch('/api/copilot/auto-allowed-tools')
logger.info('[AutoAllowedTools] Load response', { status: res.status, ok: res.ok })
if (res.ok) {
const data = await res.json()
set({ autoAllowedTools: data.autoAllowedTools || [] })
logger.info('[AutoAllowedTools] Loaded', { tools: data.autoAllowedTools })
const tools = data.autoAllowedTools || []
set({ autoAllowedTools: tools })
logger.info('[AutoAllowedTools] Loaded successfully', { count: tools.length, tools })
} else {
logger.warn('[AutoAllowedTools] Load failed with status', { status: res.status })
}
} catch (err) {
logger.error('[AutoAllowedTools] Failed to load', { error: err })
Expand All @@ -3936,15 +3964,18 @@ export const useCopilotStore = create<CopilotStore>()(

addAutoAllowedTool: async (toolId: string) => {
try {
logger.info('[AutoAllowedTools] Adding tool...', { toolId })
const res = await fetch('/api/copilot/auto-allowed-tools', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ toolId }),
})
logger.info('[AutoAllowedTools] API response', { toolId, status: res.status, ok: res.ok })
if (res.ok) {
const data = await res.json()
logger.info('[AutoAllowedTools] API returned', { toolId, tools: data.autoAllowedTools })
set({ autoAllowedTools: data.autoAllowedTools || [] })
logger.info('[AutoAllowedTools] Added tool', { toolId })
logger.info('[AutoAllowedTools] Added tool to store', { toolId })

// Auto-execute all pending tools of the same type
const { toolCallsById, executeIntegrationTool } = get()
Expand Down